mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-04 13:08:33 +00:00
New upstream version 1.59.0+dfsg1
This commit is contained in:
parent
3c0e092ef8
commit
a2a8927aec
302
Cargo.lock
generated
302
Cargo.lock
generated
@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli",
|
||||
"gimli 0.25.0",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
@ -87,9 +87,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.34"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
|
||||
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||
|
||||
[[package]]
|
||||
name = "array_tool"
|
||||
@ -175,9 +175,7 @@ dependencies = [
|
||||
"filetime",
|
||||
"getopts",
|
||||
"ignore",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"merge",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"opener",
|
||||
@ -276,7 +274,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo"
|
||||
version = "0.59.0"
|
||||
version = "0.60.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"atty",
|
||||
@ -370,7 +368,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"directories",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version 0.3.3",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"vergen",
|
||||
@ -419,7 +417,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-util"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"core-foundation",
|
||||
@ -492,9 +490,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chalk-derive"
|
||||
version = "0.55.0"
|
||||
version = "0.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3983193cacd81f0f924acb666b7fe5e1a0d81db9f113fa69203eda7ea8ce8b6c"
|
||||
checksum = "d54e3b5f9e3425e6b119ff07568d8d006bfa5a8d6f78a9cbc3530b1e962e316c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -504,9 +502,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-engine"
|
||||
version = "0.55.0"
|
||||
version = "0.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05a171ce5abbf0fbd06f221ab80ab182c7ef78603d23b858bc44e7ce8a86a396"
|
||||
checksum = "bdc891073396b167163db77123b0a3c00088edc00466cecc5531f33e3e989523"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"chalk-ir",
|
||||
@ -517,9 +515,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-ir"
|
||||
version = "0.55.0"
|
||||
version = "0.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a522f53af971e7678f472d687e053120157b3ae26e2ebd5ecbc0f5ab124f2cb6"
|
||||
checksum = "2b79e5a1d04b79311e90c69356a2c62027853906a7e33b3e070b93c055fc3e8a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"chalk-derive",
|
||||
@ -528,14 +526,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-solve"
|
||||
version = "0.55.0"
|
||||
version = "0.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdf79fb77a567e456a170f7ec84ea6584163d4ba3f13660cd182013d34ca667c"
|
||||
checksum = "a5d2a1db6605aba70a58820bd80ac422b218913a510f1a40beef9efc5371ea1d"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"chalk-ir",
|
||||
"ena",
|
||||
"itertools 0.9.0",
|
||||
"itertools 0.10.1",
|
||||
"petgraph",
|
||||
"rustc-hash",
|
||||
"tracing",
|
||||
@ -558,11 +556,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0",
|
||||
"ansi_term 0.12.1",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
@ -574,7 +572,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.14.0",
|
||||
"clippy_lints",
|
||||
@ -584,6 +582,7 @@ dependencies = [
|
||||
"filetime",
|
||||
"if_chain",
|
||||
"itertools 0.10.1",
|
||||
"parking_lot",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-workspace-hack",
|
||||
@ -600,6 +599,7 @@ name = "clippy_dev"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"cargo_metadata 0.14.0",
|
||||
"clap",
|
||||
"indoc",
|
||||
"itertools 0.10.1",
|
||||
@ -611,13 +611,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.14.0",
|
||||
"clippy_utils",
|
||||
"if_chain",
|
||||
"itertools 0.10.1",
|
||||
"pulldown-cmark 0.8.0",
|
||||
"pulldown-cmark",
|
||||
"quine-mc_cluskey",
|
||||
"regex-syntax",
|
||||
"rustc-semver",
|
||||
@ -632,7 +632,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"if_chain",
|
||||
"rustc-semver",
|
||||
@ -678,9 +678,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.53"
|
||||
version = "0.1.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2467ff455350a4df7d02f1ed1449d0279605a763de5d586dcf6aa7d732508bcb"
|
||||
checksum = "a68c69e9451f1df4b215c9588c621670c12286b53e60fb5ec4b59aaa1138d18e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc-std-workspace-core",
|
||||
@ -766,7 +766,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||
|
||||
[[package]]
|
||||
name = "crates-io"
|
||||
version = "0.33.0"
|
||||
version = "0.33.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"curl",
|
||||
@ -1158,6 +1158,12 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.14"
|
||||
@ -1446,6 +1452,17 @@ dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
|
||||
dependencies = [
|
||||
"fallible-iterator",
|
||||
"indexmap",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.23"
|
||||
@ -1713,9 +1730,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.6"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
@ -1900,9 +1920,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.106"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
|
||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
@ -1921,6 +1941,16 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.1.4"
|
||||
@ -1939,9 +1969,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.19"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca46220853ba1c512fc82826d0834d87b06bcd3c2a42241b7de72f3d2fe17056"
|
||||
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -1992,9 +2022,9 @@ version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.1"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
@ -2092,9 +2122,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.0.1"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
@ -2124,9 +2154,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mdbook"
|
||||
version = "0.4.12"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0651782b4cc514c3f98c0acf9b5af1101a735bbe1ac6852bb1a90cb91bdf0ed4"
|
||||
checksum = "241f10687eb3b4e0634b3b4e423f97c5f1efbd69dc9522e24a8b94583eeec3c6"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
@ -2138,8 +2168,8 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memchr",
|
||||
"open",
|
||||
"pulldown-cmark 0.7.2",
|
||||
"opener",
|
||||
"pulldown-cmark",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@ -2147,6 +2177,7 @@ dependencies = [
|
||||
"shlex",
|
||||
"tempfile",
|
||||
"toml",
|
||||
"topological-sort",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2205,28 +2236,6 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "merge"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
|
||||
dependencies = [
|
||||
"merge_derive",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "merge_derive"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minifier"
|
||||
version = "0.0.41"
|
||||
@ -2284,7 +2293,7 @@ dependencies = [
|
||||
"measureme 9.1.2",
|
||||
"rand 0.8.4",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version 0.4.0",
|
||||
"rustc_version",
|
||||
"shell-escape",
|
||||
"smallvec",
|
||||
]
|
||||
@ -2347,6 +2356,18 @@ dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "odht"
|
||||
version = "0.3.1"
|
||||
@ -2374,15 +2395,6 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "open"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c283bf0114efea9e42f1a60edea9859e8c47528eae09d01df4b29c1e489cc48"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opener"
|
||||
version = "0.5.0"
|
||||
@ -2511,9 +2523,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
@ -2522,9 +2534,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.3"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
@ -2796,9 +2808,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.7.2"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca36dea94d187597e104a5c8e4b07576a8a45aa5db48a65e12940d3eb7461f55"
|
||||
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"getopts",
|
||||
@ -2806,17 +2818,6 @@ dependencies = [
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "punycode"
|
||||
version = "0.4.1"
|
||||
@ -3085,15 +3086,15 @@ dependencies = [
|
||||
"anyhow",
|
||||
"cargo",
|
||||
"cargo-util",
|
||||
"cargo_metadata 0.12.0",
|
||||
"cargo_metadata 0.14.0",
|
||||
"clippy_lints",
|
||||
"crossbeam-channel",
|
||||
"difference",
|
||||
"env_logger 0.7.1",
|
||||
"env_logger 0.9.0",
|
||||
"futures 0.3.12",
|
||||
"heck",
|
||||
"home",
|
||||
"itertools 0.9.0",
|
||||
"itertools 0.10.1",
|
||||
"jsonrpc-core",
|
||||
"lazy_static",
|
||||
"log",
|
||||
@ -3102,7 +3103,7 @@ dependencies = [
|
||||
"num_cpus",
|
||||
"ordslice",
|
||||
"racer",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.4",
|
||||
"rayon",
|
||||
"regex",
|
||||
"rls-analysis",
|
||||
@ -3692,6 +3693,7 @@ dependencies = [
|
||||
"rustc_expand",
|
||||
"rustc_feature",
|
||||
"rustc_lexer",
|
||||
"rustc_lint_defs",
|
||||
"rustc_parse",
|
||||
"rustc_parse_format",
|
||||
"rustc_session",
|
||||
@ -3708,6 +3710,7 @@ dependencies = [
|
||||
"bitflags",
|
||||
"cstr",
|
||||
"libc",
|
||||
"libloading",
|
||||
"measureme 10.0.0",
|
||||
"rustc-demangle",
|
||||
"rustc_arena",
|
||||
@ -3728,7 +3731,6 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec",
|
||||
"snap",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@ -3741,10 +3743,11 @@ dependencies = [
|
||||
"itertools 0.9.0",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"object",
|
||||
"object 0.26.2",
|
||||
"pathdiff",
|
||||
"regex",
|
||||
"rustc_apfloat",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_attr",
|
||||
"rustc_data_structures",
|
||||
@ -3763,7 +3766,9 @@ dependencies = [
|
||||
"rustc_symbol_mangling",
|
||||
"rustc_target",
|
||||
"smallvec",
|
||||
"snap",
|
||||
"tempfile",
|
||||
"thorin-dwp",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@ -3823,7 +3828,6 @@ dependencies = [
|
||||
name = "rustc_driver"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"libc",
|
||||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
@ -3837,6 +3841,7 @@ dependencies = [
|
||||
"rustc_hir_pretty",
|
||||
"rustc_interface",
|
||||
"rustc_lint",
|
||||
"rustc_log",
|
||||
"rustc_metadata",
|
||||
"rustc_middle",
|
||||
"rustc_parse",
|
||||
@ -3848,8 +3853,6 @@ dependencies = [
|
||||
"rustc_target",
|
||||
"rustc_typeck",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-tree",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@ -3967,6 +3970,7 @@ dependencies = [
|
||||
"arrayvec",
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3992,6 +3996,7 @@ name = "rustc_interface"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libloading",
|
||||
"rustc-rayon",
|
||||
"rustc-rayon-core",
|
||||
"rustc_ast",
|
||||
@ -4090,6 +4095,17 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_log"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"rustc_span",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_macros"
|
||||
version = "0.1.0"
|
||||
@ -4104,7 +4120,7 @@ dependencies = [
|
||||
name = "rustc_metadata"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libloading",
|
||||
"odht",
|
||||
"rustc_ast",
|
||||
"rustc_attr",
|
||||
@ -4124,7 +4140,6 @@ dependencies = [
|
||||
"smallvec",
|
||||
"snap",
|
||||
"tracing",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4297,6 +4312,7 @@ dependencies = [
|
||||
name = "rustc_plugin_impl"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
"rustc_ast",
|
||||
"rustc_errors",
|
||||
"rustc_hir",
|
||||
@ -4590,15 +4606,6 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
||||
dependencies = [
|
||||
"semver 0.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
@ -4616,7 +4623,7 @@ dependencies = [
|
||||
"expect-test",
|
||||
"itertools 0.9.0",
|
||||
"minifier",
|
||||
"pulldown-cmark 0.8.0",
|
||||
"pulldown-cmark",
|
||||
"rayon",
|
||||
"regex",
|
||||
"rustdoc-json-types",
|
||||
@ -5006,7 +5013,7 @@ dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"object 0.26.2",
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
@ -5070,9 +5077,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.16"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
|
||||
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
@ -5081,9 +5088,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.9"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
@ -5123,9 +5130,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.4"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5262,24 +5269,36 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.20"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.20"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thorin-dwp"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "039d1fc0bfdb73910c2702893515580e38c192f47a987bc98ddd38a36f2d953a"
|
||||
dependencies = [
|
||||
"gimli 0.26.1",
|
||||
"indexmap",
|
||||
"object 0.27.1",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
@ -5393,6 +5412,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "topological-sort"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa7c7f42dea4b1b99439786f5633aeb9c14c1b53f75e282803c2ec2ad545873c"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
@ -5401,9 +5426,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.28"
|
||||
version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8"
|
||||
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
@ -5413,9 +5438,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4f915eb6abf914599c200260efced9203504c4c37380af10cdf3b7d36970650"
|
||||
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5442,49 +5467,34 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-serde"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.16"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96"
|
||||
checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
"matchers",
|
||||
"parking_lot",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-tree"
|
||||
version = "0.1.9"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1712b40907f8d9bc2bc66763ab61dec914b7123d7149e59feb0d4e2a95fc4967"
|
||||
checksum = "3ce989c9962c7f61fe084dd4a230eec784649dfc2392467c790007c3a6e134e7"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"atty",
|
||||
"termcolor",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
346
RELEASES.md
346
RELEASES.md
@ -1,3 +1,184 @@
|
||||
Version 1.59.0 (2022-02-24)
|
||||
==========================
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
- [Stabilize default arguments for const generics][90207]
|
||||
- [Stabilize destructuring assignment][90521]
|
||||
- [Relax private in public lint on generic bounds and where clauses of trait impls][90586]
|
||||
- [Stabilize asm! and global_asm! for x86, x86_64, ARM, Aarch64, and RISC-V][91728]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
- [Stabilize new symbol mangling format, leaving it opt-in (-Csymbol-mangling-version=v0)][90128]
|
||||
- [Emit LLVM optimization remarks when enabled with `-Cremark`][90833]
|
||||
- [Fix sparc64 ABI for aggregates with floating point members][91003]
|
||||
- [Warn when a `#[test]`-like built-in attribute macro is present multiple times.][91172]
|
||||
- [Add support for riscv64gc-unknown-freebsd][91284]
|
||||
- [Stabilize `-Z emit-future-incompat` as `--json future-incompat`][91535]
|
||||
- [Soft disable incremental compilation][94124]
|
||||
|
||||
This release disables incremental compilation, unless the user has explicitly
|
||||
opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable.
|
||||
This is due to a known and relatively frequently occurring bug in incremental
|
||||
compilation, which causes builds to issue internal compiler errors. This
|
||||
particular bug is already fixed on nightly, but that fix has not yet rolled out
|
||||
to stable and is deemed too risky for a direct stable backport.
|
||||
|
||||
As always, we encourage users to test with nightly and report bugs so that we
|
||||
can track failures and fix issues earlier.
|
||||
|
||||
See [94124] for more details.
|
||||
|
||||
[94124]: https://github.com/rust-lang/rust/issues/94124
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
- [Remove unnecessary bounds for some Hash{Map,Set} methods][91593]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`std::thread::available_parallelism`][available_parallelism]
|
||||
- [`Result::copied`][result-copied]
|
||||
- [`Result::cloned`][result-cloned]
|
||||
- [`arch::asm!`][asm]
|
||||
- [`arch::global_asm!`][global_asm]
|
||||
- [`ops::ControlFlow::is_break`][is_break]
|
||||
- [`ops::ControlFlow::is_continue`][is_continue]
|
||||
- [`TryFrom<char> for u8`][try_from_char_u8]
|
||||
- [`char::TryFromCharError`][try_from_char_err]
|
||||
implementing `Clone`, `Debug`, `Display`, `PartialEq`, `Copy`, `Eq`, `Error`
|
||||
- [`iter::zip`][zip]
|
||||
- [`NonZeroU8::is_power_of_two`][is_power_of_two8]
|
||||
- [`NonZeroU16::is_power_of_two`][is_power_of_two16]
|
||||
- [`NonZeroU32::is_power_of_two`][is_power_of_two32]
|
||||
- [`NonZeroU64::is_power_of_two`][is_power_of_two64]
|
||||
- [`NonZeroU128::is_power_of_two`][is_power_of_two128]
|
||||
- [`DoubleEndedIterator for ToLowercase`][lowercase]
|
||||
- [`DoubleEndedIterator for ToUppercase`][uppercase]
|
||||
- [`TryFrom<&mut [T]> for [T; N]`][tryfrom_ref_arr]
|
||||
- [`UnwindSafe for Once`][unwindsafe_once]
|
||||
- [`RefUnwindSafe for Once`][refunwindsafe_once]
|
||||
- [armv8 neon intrinsics for aarch64][stdarch/1266]
|
||||
|
||||
Const-stable:
|
||||
|
||||
- [`mem::MaybeUninit::as_ptr`][muninit_ptr]
|
||||
- [`mem::MaybeUninit::assume_init`][muninit_init]
|
||||
- [`mem::MaybeUninit::assume_init_ref`][muninit_init_ref]
|
||||
- [`ffi::CStr::from_bytes_with_nul_unchecked`][cstr_from_bytes]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
- [Stabilize the `strip` profile option][cargo/10088]
|
||||
- [Stabilize future-incompat-report][cargo/10165]
|
||||
- [Support abbreviating `--release` as `-r`][cargo/10133]
|
||||
- [Support `term.quiet` configuration][cargo/10152]
|
||||
- [Remove `--host` from cargo {publish,search,login}][cargo/10145]
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [Refactor weak symbols in std::sys::unix][90846]
|
||||
This may add new, versioned, symbols when building with a newer glibc, as the
|
||||
standard library uses weak linkage rather than dynamically attempting to load
|
||||
certain symbols at runtime.
|
||||
- [Deprecate crate_type and crate_name nested inside `#![cfg_attr]`][83744]
|
||||
This adds a future compatibility lint to supporting the use of cfg_attr
|
||||
wrapping either crate_type or crate_name specification within Rust files;
|
||||
it is recommended that users migrate to setting the equivalent command line
|
||||
flags.
|
||||
- [Remove effect of `#[no_link]` attribute on name resolution][92034]
|
||||
This may expose new names, leading to conflicts with preexisting names in a
|
||||
given namespace and a compilation failure.
|
||||
- [Cargo will document libraries before binaries.][cargo/10172]
|
||||
- [Respect doc=false in dependencies, not just the root crate][cargo/10201]
|
||||
- [Weaken guarantee around advancing underlying iterators in zip][83791]
|
||||
- [Make split_inclusive() on an empty slice yield an empty output][89825]
|
||||
- [Update std::env::temp_dir to use GetTempPath2 on Windows when available.][89999]
|
||||
- [unreachable! was updated to match other formatting macro behavior on Rust 2021][92137]
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
These changes provide no direct user facing benefits, but represent significant
|
||||
improvements to the internals and overall performance of rustc
|
||||
and related tools.
|
||||
|
||||
- [Fix many cases of normalization-related ICEs][91255]
|
||||
- [Replace dominators algorithm with simple Lengauer-Tarjan][85013]
|
||||
- [Store liveness in interval sets for region inference][90637]
|
||||
|
||||
- [Remove `in_band_lifetimes` from the compiler and standard library, in preparation for removing this
|
||||
unstable feature.][91867]
|
||||
|
||||
[91867]: https://github.com/rust-lang/rust/issues/91867
|
||||
[83744]: https://github.com/rust-lang/rust/pull/83744/
|
||||
[83791]: https://github.com/rust-lang/rust/pull/83791/
|
||||
[85013]: https://github.com/rust-lang/rust/pull/85013/
|
||||
[89825]: https://github.com/rust-lang/rust/pull/89825/
|
||||
[89999]: https://github.com/rust-lang/rust/pull/89999/
|
||||
[90128]: https://github.com/rust-lang/rust/pull/90128/
|
||||
[90207]: https://github.com/rust-lang/rust/pull/90207/
|
||||
[90521]: https://github.com/rust-lang/rust/pull/90521/
|
||||
[90586]: https://github.com/rust-lang/rust/pull/90586/
|
||||
[90637]: https://github.com/rust-lang/rust/pull/90637/
|
||||
[90833]: https://github.com/rust-lang/rust/pull/90833/
|
||||
[90846]: https://github.com/rust-lang/rust/pull/90846/
|
||||
[91003]: https://github.com/rust-lang/rust/pull/91003/
|
||||
[91172]: https://github.com/rust-lang/rust/pull/91172/
|
||||
[91255]: https://github.com/rust-lang/rust/pull/91255/
|
||||
[91284]: https://github.com/rust-lang/rust/pull/91284/
|
||||
[91535]: https://github.com/rust-lang/rust/pull/91535/
|
||||
[91593]: https://github.com/rust-lang/rust/pull/91593/
|
||||
[91728]: https://github.com/rust-lang/rust/pull/91728/
|
||||
[91878]: https://github.com/rust-lang/rust/pull/91878/
|
||||
[91896]: https://github.com/rust-lang/rust/pull/91896/
|
||||
[91926]: https://github.com/rust-lang/rust/pull/91926/
|
||||
[91984]: https://github.com/rust-lang/rust/pull/91984/
|
||||
[92020]: https://github.com/rust-lang/rust/pull/92020/
|
||||
[92034]: https://github.com/rust-lang/rust/pull/92034/
|
||||
[92483]: https://github.com/rust-lang/rust/pull/92483/
|
||||
[cargo/10088]: https://github.com/rust-lang/cargo/pull/10088/
|
||||
[cargo/10133]: https://github.com/rust-lang/cargo/pull/10133/
|
||||
[cargo/10145]: https://github.com/rust-lang/cargo/pull/10145/
|
||||
[cargo/10152]: https://github.com/rust-lang/cargo/pull/10152/
|
||||
[cargo/10165]: https://github.com/rust-lang/cargo/pull/10165/
|
||||
[cargo/10172]: https://github.com/rust-lang/cargo/pull/10172/
|
||||
[cargo/10201]: https://github.com/rust-lang/cargo/pull/10201/
|
||||
[cargo/10269]: https://github.com/rust-lang/cargo/pull/10269/
|
||||
|
||||
[cstr_from_bytes]: https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_bytes_with_nul_unchecked
|
||||
[muninit_ptr]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr
|
||||
[muninit_init]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init
|
||||
[muninit_init_ref]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
|
||||
[unwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-UnwindSafe
|
||||
[refunwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-RefUnwindSafe
|
||||
[tryfrom_ref_arr]: https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html#impl-TryFrom%3C%26%27_%20mut%20%5BT%5D%3E
|
||||
[lowercase]: https://doc.rust-lang.org/stable/std/char/struct.ToLowercase.html#impl-DoubleEndedIterator
|
||||
[uppercase]: https://doc.rust-lang.org/stable/std/char/struct.ToUppercase.html#impl-DoubleEndedIterator
|
||||
[try_from_char_err]: https://doc.rust-lang.org/stable/std/char/struct.TryFromCharError.html
|
||||
[available_parallelism]: https://doc.rust-lang.org/stable/std/thread/fn.available_parallelism.html
|
||||
[result-copied]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.copied
|
||||
[result-cloned]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.cloned
|
||||
[asm]: https://doc.rust-lang.org/stable/core/arch/macro.asm.html
|
||||
[global_asm]: https://doc.rust-lang.org/stable/core/arch/macro.global_asm.html
|
||||
[is_break]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_break
|
||||
[is_continue]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_continue
|
||||
[try_from_char_u8]: https://doc.rust-lang.org/stable/std/primitive.char.html#impl-TryFrom%3Cchar%3E
|
||||
[zip]: https://doc.rust-lang.org/stable/std/iter/fn.zip.html
|
||||
[is_power_of_two8]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU8.html#method.is_power_of_two
|
||||
[is_power_of_two16]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU16.html#method.is_power_of_two
|
||||
[is_power_of_two32]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU32.html#method.is_power_of_two
|
||||
[is_power_of_two64]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU64.html#method.is_power_of_two
|
||||
[is_power_of_two128]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU128.html#method.is_power_of_two
|
||||
[stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266
|
||||
|
||||
Version 1.58.1 (2022-01-19)
|
||||
===========================
|
||||
|
||||
@ -7,7 +188,7 @@ Version 1.58.1 (2022-01-19)
|
||||
* [Fix wrong error message displayed when some imports are missing][91254]
|
||||
* [Fix rustfmt not formatting generated files from stdin][92912]
|
||||
|
||||
[CVE-2022-21658]: https://www.cve.org/CVERecord?id=CVE-2022-21658]
|
||||
[CVE-2022-21658]: https://www.cve.org/CVERecord?id=CVE-2022-21658
|
||||
[91254]: https://github.com/rust-lang/rust/pull/91254
|
||||
[92912]: https://github.com/rust-lang/rust/pull/92912
|
||||
[clippy/8075]: https://github.com/rust-lang/rust-clippy/pull/8075
|
||||
@ -58,7 +239,6 @@ Stabilized APIs
|
||||
- [`Option::unwrap_unchecked`]
|
||||
- [`Result::unwrap_unchecked`]
|
||||
- [`Result::unwrap_err_unchecked`]
|
||||
- [`NonZero{unsigned}::is_power_of_two`]
|
||||
- [`File::options`]
|
||||
|
||||
These APIs are now usable in const contexts:
|
||||
@ -71,10 +251,6 @@ These APIs are now usable in const contexts:
|
||||
- [`Duration::checked_mul`]
|
||||
- [`Duration::saturating_mul`]
|
||||
- [`Duration::checked_div`]
|
||||
- [`MaybeUninit::as_ptr`]
|
||||
- [`MaybeUninit::as_mut_ptr`]
|
||||
- [`MaybeUninit::assume_init`]
|
||||
- [`MaybeUninit::assume_init_ref`]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
@ -115,19 +291,14 @@ and related tools.
|
||||
[87467]: https://github.com/rust-lang/rust/pull/87467/
|
||||
[87704]: https://github.com/rust-lang/rust/pull/87704/
|
||||
[88041]: https://github.com/rust-lang/rust/pull/88041/
|
||||
[88300]: https://github.com/rust-lang/rust/pull/88300/
|
||||
[88447]: https://github.com/rust-lang/rust/pull/88447/
|
||||
[88601]: https://github.com/rust-lang/rust/pull/88601/
|
||||
[88624]: https://github.com/rust-lang/rust/pull/88624/
|
||||
[89062]: https://github.com/rust-lang/rust/pull/89062/
|
||||
[89174]: https://github.com/rust-lang/rust/pull/89174/
|
||||
[89542]: https://github.com/rust-lang/rust/pull/89542/
|
||||
[89551]: https://github.com/rust-lang/rust/pull/89551/
|
||||
[89558]: https://github.com/rust-lang/rust/pull/89558/
|
||||
[89580]: https://github.com/rust-lang/rust/pull/89580/
|
||||
[89652]: https://github.com/rust-lang/rust/pull/89652/
|
||||
[89677]: https://github.com/rust-lang/rust/pull/89677/
|
||||
[89951]: https://github.com/rust-lang/rust/pull/89951/
|
||||
[90041]: https://github.com/rust-lang/rust/pull/90041/
|
||||
[90058]: https://github.com/rust-lang/rust/pull/90058/
|
||||
[90104]: https://github.com/rust-lang/rust/pull/90104/
|
||||
@ -143,11 +314,9 @@ and related tools.
|
||||
[90733]: https://github.com/rust-lang/rust/pull/90733/
|
||||
[90833]: https://github.com/rust-lang/rust/pull/90833/
|
||||
[90846]: https://github.com/rust-lang/rust/pull/90846/
|
||||
[90896]: https://github.com/rust-lang/rust/pull/90896/
|
||||
[91026]: https://github.com/rust-lang/rust/pull/91026/
|
||||
[91207]: https://github.com/rust-lang/rust/pull/91207/
|
||||
[91255]: https://github.com/rust-lang/rust/pull/91255/
|
||||
[91301]: https://github.com/rust-lang/rust/pull/91301/
|
||||
[cargo/10082]: https://github.com/rust-lang/cargo/pull/10082/
|
||||
[cargo/10107]: https://github.com/rust-lang/cargo/pull/10107/
|
||||
[`Metadata::is_symlink`]: https://doc.rust-lang.org/stable/std/fs/struct.Metadata.html#method.is_symlink
|
||||
@ -156,34 +325,8 @@ and related tools.
|
||||
[`Option::unwrap_unchecked`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.unwrap_unchecked
|
||||
[`Result::unwrap_unchecked`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.unwrap_unchecked
|
||||
[`Result::unwrap_err_unchecked`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.unwrap_err_unchecked
|
||||
[`NonZero{unsigned}::is_power_of_two`]: https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html#method.is_power_of_two
|
||||
[`File::options`]: https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.options
|
||||
[`unix::process::ExitStatusExt::core_dumped`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.core_dumped
|
||||
[`unix::process::ExitStatusExt::stopped_signal`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.stopped_signal
|
||||
[`unix::process::ExitStatusExt::continued`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.continued
|
||||
[`unix::process::ExitStatusExt::into_raw`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.into_raw
|
||||
[`Duration::new`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.new
|
||||
[`Duration::checked_add`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_add
|
||||
[`Duration::saturating_add`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_add
|
||||
[`Duration::checked_sub`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_sub
|
||||
[`Duration::saturating_sub`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_sub
|
||||
[`Duration::checked_mul`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_mul
|
||||
[`Duration::saturating_mul`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_mul
|
||||
[`Duration::checked_div`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_div
|
||||
[`Duration::as_secs_f64`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.as_secs_f64
|
||||
[`Duration::as_secs_f32`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.as_secs_f32
|
||||
[`Duration::from_secs_f64`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_secs_f64
|
||||
[`Duration::from_secs_f32`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_secs_f32
|
||||
[`Duration::mul_f64`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.mul_f64
|
||||
[`Duration::mul_f32`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.mul_f32
|
||||
[`Duration::div_f64`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.div_f64
|
||||
[`Duration::div_f32`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.div_f32
|
||||
[`Duration::div_duration_f64`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.div_duration_f64
|
||||
[`Duration::div_duration_f32`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.div_duration_f32
|
||||
[`MaybeUninit::as_ptr`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr
|
||||
[`MaybeUninit::as_mut_ptr`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_mut_ptr
|
||||
[`MaybeUninit::assume_init`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init
|
||||
[`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
|
||||
|
||||
Version 1.57.0 (2021-12-02)
|
||||
==========================
|
||||
@ -194,6 +337,7 @@ Language
|
||||
- [Macro attributes may follow `#[derive]` and will see the original (pre-`cfg`) input.][87220]
|
||||
- [Accept curly-brace macros in expressions, like `m!{ .. }.method()` and `m!{ .. }?`.][88690]
|
||||
- [Allow panicking in constant evaluation.][89508]
|
||||
- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
@ -254,6 +398,9 @@ Cargo
|
||||
Compatibility notes
|
||||
-------------------
|
||||
|
||||
- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200]
|
||||
This will break some builds that set `#![deny(dead_code)]`.
|
||||
|
||||
Internal changes
|
||||
----------------
|
||||
These changes provide no direct user facing benefits, but represent significant
|
||||
@ -262,10 +409,10 @@ and related tools.
|
||||
|
||||
- [Added an experimental backend for codegen with `libgccjit`.][87260]
|
||||
|
||||
[85200]: https://github.com/rust-lang/rust/pull/85200/
|
||||
[86191]: https://github.com/rust-lang/rust/pull/86191/
|
||||
[87220]: https://github.com/rust-lang/rust/pull/87220/
|
||||
[87260]: https://github.com/rust-lang/rust/pull/87260/
|
||||
[88243]: https://github.com/rust-lang/rust/pull/88243/
|
||||
[88321]: https://github.com/rust-lang/rust/pull/88321/
|
||||
[88529]: https://github.com/rust-lang/rust/pull/88529/
|
||||
[88690]: https://github.com/rust-lang/rust/pull/88690/
|
||||
@ -421,8 +568,6 @@ and related tools.
|
||||
as well as rustdoc.
|
||||
|
||||
[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
|
||||
[`Iterator::intersperse`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
|
||||
[`Iterator::intersperse_with`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
|
||||
[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get
|
||||
[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
|
||||
[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662
|
||||
@ -444,12 +589,7 @@ and related tools.
|
||||
[rust#86183]: https://github.com/rust-lang/rust/pull/86183
|
||||
[rust#87385]: https://github.com/rust-lang/rust/pull/87385
|
||||
[rust#88100]: https://github.com/rust-lang/rust/pull/88100
|
||||
[rust#86860]: https://github.com/rust-lang/rust/pull/86860
|
||||
[rust#84039]: https://github.com/rust-lang/rust/pull/84039
|
||||
[rust#86492]: https://github.com/rust-lang/rust/pull/86492
|
||||
[rust#88363]: https://github.com/rust-lang/rust/pull/88363
|
||||
[rust#85305]: https://github.com/rust-lang/rust/pull/85305
|
||||
[rust#87832]: https://github.com/rust-lang/rust/pull/87832
|
||||
[rust#88069]: https://github.com/rust-lang/rust/pull/88069
|
||||
[rust#87472]: https://github.com/rust-lang/rust/pull/87472
|
||||
[rust#87699]: https://github.com/rust-lang/rust/pull/87699
|
||||
@ -460,31 +600,12 @@ and related tools.
|
||||
[rust#87580]: https://github.com/rust-lang/rust/pull/87580
|
||||
[rust#83342]: https://github.com/rust-lang/rust/pull/83342
|
||||
[rust#83093]: https://github.com/rust-lang/rust/pull/83093
|
||||
[rust#88177]: https://github.com/rust-lang/rust/pull/88177
|
||||
[rust#88548]: https://github.com/rust-lang/rust/pull/88548
|
||||
[rust#88551]: https://github.com/rust-lang/rust/pull/88551
|
||||
[rust#88299]: https://github.com/rust-lang/rust/pull/88299
|
||||
[rust#88220]: https://github.com/rust-lang/rust/pull/88220
|
||||
[rust#85835]: https://github.com/rust-lang/rust/pull/85835
|
||||
[rust#86879]: https://github.com/rust-lang/rust/pull/86879
|
||||
[rust#86744]: https://github.com/rust-lang/rust/pull/86744
|
||||
[rust#84662]: https://github.com/rust-lang/rust/pull/84662
|
||||
[rust#86593]: https://github.com/rust-lang/rust/pull/86593
|
||||
[rust#81050]: https://github.com/rust-lang/rust/pull/81050
|
||||
[rust#81363]: https://github.com/rust-lang/rust/pull/81363
|
||||
[rust#84111]: https://github.com/rust-lang/rust/pull/84111
|
||||
[rust#85769]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720
|
||||
[rust#88490]: https://github.com/rust-lang/rust/pull/88490
|
||||
[rust#88269]: https://github.com/rust-lang/rust/pull/88269
|
||||
[rust#84176]: https://github.com/rust-lang/rust/pull/84176
|
||||
[rust#88399]: https://github.com/rust-lang/rust/pull/88399
|
||||
[rust#88227]: https://github.com/rust-lang/rust/pull/88227
|
||||
[rust#88200]: https://github.com/rust-lang/rust/pull/88200
|
||||
[rust#82776]: https://github.com/rust-lang/rust/pull/82776
|
||||
[rust#88077]: https://github.com/rust-lang/rust/pull/88077
|
||||
[rust#87728]: https://github.com/rust-lang/rust/pull/87728
|
||||
[rust#87050]: https://github.com/rust-lang/rust/pull/87050
|
||||
[rust#87619]: https://github.com/rust-lang/rust/pull/87619
|
||||
[rust#81825]: https://github.com/rust-lang/rust/pull/81825#issuecomment-808406918
|
||||
[rust#88019]: https://github.com/rust-lang/rust/pull/88019
|
||||
[rust#87666]: https://github.com/rust-lang/rust/pull/87666
|
||||
@ -590,20 +711,14 @@ Compatibility Notes
|
||||
[86294]: https://github.com/rust-lang/rust/pull/86294
|
||||
[86858]: https://github.com/rust-lang/rust/pull/86858
|
||||
[86761]: https://github.com/rust-lang/rust/pull/86761
|
||||
[85769]: https://github.com/rust-lang/rust/pull/85769
|
||||
[85746]: https://github.com/rust-lang/rust/pull/85746
|
||||
[85305]: https://github.com/rust-lang/rust/pull/85305
|
||||
[85270]: https://github.com/rust-lang/rust/pull/85270
|
||||
[84111]: https://github.com/rust-lang/rust/pull/84111
|
||||
[83918]: https://github.com/rust-lang/rust/pull/83918
|
||||
[79965]: https://github.com/rust-lang/rust/pull/79965
|
||||
[87370]: https://github.com/rust-lang/rust/pull/87370
|
||||
[87298]: https://github.com/rust-lang/rust/pull/87298
|
||||
[cargo/9663]: https://github.com/rust-lang/cargo/pull/9663
|
||||
[cargo/9675]: https://github.com/rust-lang/cargo/pull/9675
|
||||
[cargo/9550]: https://github.com/rust-lang/cargo/pull/9550
|
||||
[cargo/9680]: https://github.com/rust-lang/cargo/pull/9680
|
||||
[cargo/9663]: https://github.com/rust-lang/cargo/pull/9663
|
||||
[`array::map`]: https://doc.rust-lang.org/stable/std/primitive.array.html#method.map
|
||||
[`Bound::cloned`]: https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.cloned
|
||||
[`Drain::as_str`]: https://doc.rust-lang.org/stable/std/string/struct.Drain.html#method.as_str
|
||||
@ -612,7 +727,6 @@ Compatibility Notes
|
||||
[`MaybeUninit::assume_init_mut`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_mut
|
||||
[`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
|
||||
[`MaybeUninit::write`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write
|
||||
[`Seek::rewind`]: https://doc.rust-lang.org/stable/std/io/trait.Seek.html#method.rewind
|
||||
[`ops::ControlFlow`]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html
|
||||
[`str::from_utf8_unchecked`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8_unchecked.html
|
||||
[`x86::_bittest`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittest.html
|
||||
@ -716,7 +830,6 @@ Compatibility Notes
|
||||
[85574]: https://github.com/rust-lang/rust/issues/85574
|
||||
[86831]: https://github.com/rust-lang/rust/issues/86831
|
||||
[86063]: https://github.com/rust-lang/rust/issues/86063
|
||||
[86831]: https://github.com/rust-lang/rust/issues/86831
|
||||
[79608]: https://github.com/rust-lang/rust/pull/79608
|
||||
[84988]: https://github.com/rust-lang/rust/pull/84988
|
||||
[84701]: https://github.com/rust-lang/rust/pull/84701
|
||||
@ -918,7 +1031,6 @@ related tools.
|
||||
[`Ordering::is_le`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.is_le
|
||||
[`Ordering::is_lt`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.is_lt
|
||||
[`Ordering::is_ne`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.is_ne
|
||||
[`OsStr::eq_ignore_ascii_case`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.eq_ignore_ascii_case
|
||||
[`OsStr::is_ascii`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.is_ascii
|
||||
[`OsStr::make_ascii_lowercase`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.make_ascii_lowercase
|
||||
[`OsStr::make_ascii_uppercase`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.make_ascii_uppercase
|
||||
@ -1249,7 +1361,6 @@ Internal Only
|
||||
[80053]: https://github.com/rust-lang/rust/pull/80053
|
||||
[79502]: https://github.com/rust-lang/rust/pull/79502
|
||||
[75180]: https://github.com/rust-lang/rust/pull/75180
|
||||
[79135]: https://github.com/rust-lang/rust/pull/79135
|
||||
[81521]: https://github.com/rust-lang/rust/pull/81521
|
||||
[80968]: https://github.com/rust-lang/rust/pull/80968
|
||||
[80959]: https://github.com/rust-lang/rust/pull/80959
|
||||
@ -1563,7 +1674,6 @@ related tools.
|
||||
[`slice::select_nth_unstable`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable
|
||||
[`slice::select_nth_unstable_by`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by
|
||||
[`slice::select_nth_unstable_by_key`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by_key
|
||||
[`hint::spin_loop`]: https://doc.rust-lang.org/stable/std/hint/fn.spin_loop.html
|
||||
[`Poll::is_ready`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_ready
|
||||
[`Poll::is_pending`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_pending
|
||||
[rustdoc-ws-post]: https://blog.guillaume-gomez.fr/articles/2020-11-11+New+doc+comment+handling+in+rustdoc
|
||||
@ -1810,8 +1920,6 @@ Internal Only
|
||||
[74869]: https://github.com/rust-lang/rust/pull/74869/
|
||||
[73858]: https://github.com/rust-lang/rust/pull/73858/
|
||||
[75716]: https://github.com/rust-lang/rust/pull/75716/
|
||||
[75908]: https://github.com/rust-lang/rust/pull/75908/
|
||||
[75516]: https://github.com/rust-lang/rust/pull/75516/
|
||||
[75560]: https://github.com/rust-lang/rust/pull/75560/
|
||||
[75568]: https://github.com/rust-lang/rust/pull/75568/
|
||||
[75366]: https://github.com/rust-lang/rust/pull/75366/
|
||||
@ -1826,7 +1934,6 @@ Internal Only
|
||||
[73583]: https://github.com/rust-lang/rust/pull/73583/
|
||||
[73084]: https://github.com/rust-lang/rust/pull/73084/
|
||||
[73197]: https://github.com/rust-lang/rust/pull/73197/
|
||||
[72488]: https://github.com/rust-lang/rust/pull/72488/
|
||||
[cargo/8456]: https://github.com/rust-lang/cargo/pull/8456/
|
||||
[cargo/8478]: https://github.com/rust-lang/cargo/pull/8478/
|
||||
[cargo/8485]: https://github.com/rust-lang/cargo/pull/8485/
|
||||
@ -1837,7 +1944,6 @@ Internal Only
|
||||
[`RangeInclusive::is_empty`]: https://doc.rust-lang.org/nightly/std/ops/struct.RangeInclusive.html#method.is_empty
|
||||
[`Result::as_deref_mut`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#method.as_deref_mut
|
||||
[`Result::as_deref`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#method.as_deref
|
||||
[`TypeId::of`]: https://doc.rust-lang.org/nightly/std/any/struct.TypeId.html#method.of
|
||||
[`Vec::leak`]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.leak
|
||||
[`f32::TAU`]: https://doc.rust-lang.org/nightly/std/f32/consts/constant.TAU.html
|
||||
[`f64::TAU`]: https://doc.rust-lang.org/nightly/std/f64/consts/constant.TAU.html
|
||||
@ -2605,6 +2711,11 @@ Language
|
||||
- [Visibility modifiers (e.g. `pub`) are now syntactically allowed on trait items and
|
||||
enum variants.][66183] These are still rejected semantically, but
|
||||
can be seen and parsed by procedural macros and conditional compilation.
|
||||
- [You can now define a Rust `extern "C"` function with `Box<T>` and use `T*` as the corresponding
|
||||
type on the C side.][62514] Please see [the documentation][box-memory-layout] for more information,
|
||||
including the important caveat about preferring to avoid `Box<T>` in Rust signatures for functions defined in C.
|
||||
|
||||
[box-memory-layout]: https://doc.rust-lang.org/std/boxed/index.html#memory-layout
|
||||
|
||||
Compiler
|
||||
--------
|
||||
@ -2679,6 +2790,7 @@ Compatibility Notes
|
||||
|
||||
[54733]: https://github.com/rust-lang/rust/pull/54733/
|
||||
[61351]: https://github.com/rust-lang/rust/pull/61351/
|
||||
[62514]: https://github.com/rust-lang/rust/pull/62514/
|
||||
[67255]: https://github.com/rust-lang/rust/pull/67255/
|
||||
[66661]: https://github.com/rust-lang/rust/pull/66661/
|
||||
[66771]: https://github.com/rust-lang/rust/pull/66771/
|
||||
@ -2815,7 +2927,6 @@ Compatibility Notes
|
||||
[63803]: https://github.com/rust-lang/rust/pull/63803/
|
||||
[cargo/7450]: https://github.com/rust-lang/cargo/pull/7450/
|
||||
[cargo/7507]: https://github.com/rust-lang/cargo/pull/7507/
|
||||
[cargo/7525]: https://github.com/rust-lang/cargo/pull/7525/
|
||||
[cargo/7333]: https://github.com/rust-lang/cargo/pull/7333/
|
||||
[(rfc 2008)]: https://rust-lang.github.io/rfcs/2008-non-exhaustive.html
|
||||
[`f32::to_be_bytes`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_be_bytes
|
||||
@ -2948,13 +3059,6 @@ Compatibility Notes
|
||||
[63786]: https://github.com/rust-lang/rust/pull/63786/
|
||||
[63827]: https://github.com/rust-lang/rust/pull/63827/
|
||||
[63834]: https://github.com/rust-lang/rust/pull/63834/
|
||||
[63927]: https://github.com/rust-lang/rust/pull/63927/
|
||||
[63933]: https://github.com/rust-lang/rust/pull/63933/
|
||||
[63934]: https://github.com/rust-lang/rust/pull/63934/
|
||||
[63938]: https://github.com/rust-lang/rust/pull/63938/
|
||||
[63940]: https://github.com/rust-lang/rust/pull/63940/
|
||||
[63941]: https://github.com/rust-lang/rust/pull/63941/
|
||||
[63945]: https://github.com/rust-lang/rust/pull/63945/
|
||||
[64010]: https://github.com/rust-lang/rust/pull/64010/
|
||||
[64028]: https://github.com/rust-lang/rust/pull/64028/
|
||||
[64334]: https://github.com/rust-lang/rust/pull/64334/
|
||||
@ -3183,7 +3287,6 @@ Compatibility Notes
|
||||
[`Cell<slice>::as_slice_of_cells`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_slice_of_cells
|
||||
[`DoubleEndedIterator::nth_back`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back
|
||||
[`Option::xor`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.xor
|
||||
[`RefCell::try_borrow_unguarded`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.try_borrow_unguarded
|
||||
[`Wrapping::reverse_bits`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html#method.reverse_bits
|
||||
[`i128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i128.html#method.reverse_bits
|
||||
[`i16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i16.html#method.reverse_bits
|
||||
@ -3682,7 +3785,6 @@ Compatibility Notes
|
||||
- [Libtest no longer creates a new thread for each test when
|
||||
`--test-threads=1`. It also runs the tests in deterministic order][56243]
|
||||
|
||||
[55982]: https://github.com/rust-lang/rust/pull/55982/
|
||||
[56243]: https://github.com/rust-lang/rust/pull/56243
|
||||
[56303]: https://github.com/rust-lang/rust/pull/56303/
|
||||
[56351]: https://github.com/rust-lang/rust/pull/56351/
|
||||
@ -4082,7 +4184,6 @@ Cargo
|
||||
|
||||
[52813]: https://github.com/rust-lang/rust/pull/52813/
|
||||
[53218]: https://github.com/rust-lang/rust/pull/53218/
|
||||
[53555]: https://github.com/rust-lang/rust/issues/53555/
|
||||
[54057]: https://github.com/rust-lang/rust/pull/54057/
|
||||
[54240]: https://github.com/rust-lang/rust/pull/54240/
|
||||
[54430]: https://github.com/rust-lang/rust/pull/54430/
|
||||
@ -4204,7 +4305,6 @@ Misc
|
||||
[53044]: https://github.com/rust-lang/rust/pull/53044/
|
||||
[53165]: https://github.com/rust-lang/rust/pull/53165/
|
||||
[53611]: https://github.com/rust-lang/rust/pull/53611/
|
||||
[53213]: https://github.com/rust-lang/rust/pull/53213/
|
||||
[53236]: https://github.com/rust-lang/rust/pull/53236/
|
||||
[53272]: https://github.com/rust-lang/rust/pull/53272/
|
||||
[53370]: https://github.com/rust-lang/rust/pull/53370/
|
||||
@ -4212,7 +4312,6 @@ Misc
|
||||
[53774]: https://github.com/rust-lang/rust/pull/53774/
|
||||
[53822]: https://github.com/rust-lang/rust/pull/53822/
|
||||
[54057]: https://github.com/rust-lang/rust/pull/54057/
|
||||
[54146]: https://github.com/rust-lang/rust/pull/54146/
|
||||
[54404]: https://github.com/rust-lang/rust/pull/54404/
|
||||
[cargo/5877]: https://github.com/rust-lang/cargo/pull/5877/
|
||||
[cargo/5878]: https://github.com/rust-lang/cargo/pull/5878/
|
||||
@ -4320,12 +4419,10 @@ Compatibility Notes
|
||||
[52330]: https://github.com/rust-lang/rust/pull/52330/
|
||||
[52354]: https://github.com/rust-lang/rust/pull/52354/
|
||||
[52402]: https://github.com/rust-lang/rust/pull/52402/
|
||||
[52103]: https://github.com/rust-lang/rust/pull/52103/
|
||||
[52197]: https://github.com/rust-lang/rust/pull/52197/
|
||||
[51807]: https://github.com/rust-lang/rust/pull/51807/
|
||||
[51899]: https://github.com/rust-lang/rust/pull/51899/
|
||||
[51912]: https://github.com/rust-lang/rust/pull/51912/
|
||||
[51511]: https://github.com/rust-lang/rust/pull/51511/
|
||||
[51619]: https://github.com/rust-lang/rust/pull/51619/
|
||||
[51656]: https://github.com/rust-lang/rust/pull/51656/
|
||||
[51178]: https://github.com/rust-lang/rust/pull/51178/
|
||||
@ -4465,7 +4562,6 @@ Compatibility Notes
|
||||
[50855]: https://github.com/rust-lang/rust/pull/50855/
|
||||
[51050]: https://github.com/rust-lang/rust/pull/51050/
|
||||
[51196]: https://github.com/rust-lang/rust/pull/51196/
|
||||
[51200]: https://github.com/rust-lang/rust/pull/51200/
|
||||
[51241]: https://github.com/rust-lang/rust/pull/51241/
|
||||
[51276]: https://github.com/rust-lang/rust/pull/51276/
|
||||
[51298]: https://github.com/rust-lang/rust/pull/51298/
|
||||
@ -4646,15 +4742,12 @@ Compatibility Notes
|
||||
[49664]: https://github.com/rust-lang/rust/pull/49664/
|
||||
[49699]: https://github.com/rust-lang/rust/pull/49699/
|
||||
[49707]: https://github.com/rust-lang/rust/pull/49707/
|
||||
[49719]: https://github.com/rust-lang/rust/pull/49719/
|
||||
[49896]: https://github.com/rust-lang/rust/pull/49896/
|
||||
[49968]: https://github.com/rust-lang/rust/pull/49968/
|
||||
[50163]: https://github.com/rust-lang/rust/pull/50163
|
||||
[50177]: https://github.com/rust-lang/rust/pull/50177/
|
||||
[50378]: https://github.com/rust-lang/rust/pull/50378/
|
||||
[50398]: https://github.com/rust-lang/rust/pull/50398/
|
||||
[50423]: https://github.com/rust-lang/rust/pull/50423/
|
||||
[cargo/5203]: https://github.com/rust-lang/cargo/pull/5203/
|
||||
[cargo/5335]: https://github.com/rust-lang/cargo/pull/5335/
|
||||
[cargo/5359]: https://github.com/rust-lang/cargo/pull/5359/
|
||||
[cargo/5360]: https://github.com/rust-lang/cargo/pull/5360/
|
||||
@ -4856,7 +4949,6 @@ Compatibility Notes
|
||||
[47813]: https://github.com/rust-lang/rust/pull/47813
|
||||
[48056]: https://github.com/rust-lang/rust/pull/48056
|
||||
[48125]: https://github.com/rust-lang/rust/pull/48125
|
||||
[48166]: https://github.com/rust-lang/rust/pull/48166
|
||||
[48235]: https://github.com/rust-lang/rust/pull/48235
|
||||
[48274]: https://github.com/rust-lang/rust/pull/48274
|
||||
[48281]: https://github.com/rust-lang/rust/pull/48281
|
||||
@ -4873,10 +4965,7 @@ Compatibility Notes
|
||||
[48978]: https://github.com/rust-lang/rust/pull/48978
|
||||
[49101]: https://github.com/rust-lang/rust/pull/49101
|
||||
[49109]: https://github.com/rust-lang/rust/pull/49109
|
||||
[49121]: https://github.com/rust-lang/rust/pull/49121
|
||||
[49162]: https://github.com/rust-lang/rust/pull/49162
|
||||
[49184]: https://github.com/rust-lang/rust/pull/49184
|
||||
[49234]: https://github.com/rust-lang/rust/pull/49234
|
||||
[49255]: https://github.com/rust-lang/rust/pull/49255
|
||||
[49299]: https://github.com/rust-lang/rust/pull/49299
|
||||
[49305]: https://github.com/rust-lang/rust/pull/49305
|
||||
@ -5123,7 +5212,6 @@ Compatibility Notes
|
||||
[44884]: https://github.com/rust-lang/rust/pull/44884
|
||||
[45198]: https://github.com/rust-lang/rust/pull/45198
|
||||
[45506]: https://github.com/rust-lang/rust/pull/45506
|
||||
[45904]: https://github.com/rust-lang/rust/pull/45904
|
||||
[45990]: https://github.com/rust-lang/rust/pull/45990
|
||||
[46012]: https://github.com/rust-lang/rust/pull/46012
|
||||
[46077]: https://github.com/rust-lang/rust/pull/46077
|
||||
@ -5135,7 +5223,6 @@ Compatibility Notes
|
||||
[46671]: https://github.com/rust-lang/rust/pull/46671
|
||||
[46713]: https://github.com/rust-lang/rust/pull/46713
|
||||
[46735]: https://github.com/rust-lang/rust/pull/46735
|
||||
[46749]: https://github.com/rust-lang/rust/pull/46749
|
||||
[46760]: https://github.com/rust-lang/rust/pull/46760
|
||||
[46798]: https://github.com/rust-lang/rust/pull/46798
|
||||
[46828]: https://github.com/rust-lang/rust/pull/46828
|
||||
@ -5306,7 +5393,6 @@ Compatibility Notes
|
||||
|
||||
|
||||
[42526]: https://github.com/rust-lang/rust/pull/42526
|
||||
[43017]: https://github.com/rust-lang/rust/pull/43017
|
||||
[43716]: https://github.com/rust-lang/rust/pull/43716
|
||||
[43949]: https://github.com/rust-lang/rust/pull/43949
|
||||
[44015]: https://github.com/rust-lang/rust/pull/44015
|
||||
@ -5536,8 +5622,6 @@ Cargo
|
||||
- [Added `--no-fail-fast` flag to cargo to run all benchmarks regardless of
|
||||
failure.][cargo/4248]
|
||||
- [Changed the convention around which file is the crate root.][cargo/4259]
|
||||
- [The `include`/`exclude` property in `Cargo.toml` now accepts gitignore paths
|
||||
instead of glob patterns][cargo/4270]. Glob patterns are now deprecated.
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
@ -5580,7 +5664,6 @@ Compatibility Notes
|
||||
[cargo/4229]: https://github.com/rust-lang/cargo/pull/4229
|
||||
[cargo/4248]: https://github.com/rust-lang/cargo/pull/4248
|
||||
[cargo/4259]: https://github.com/rust-lang/cargo/pull/4259
|
||||
[cargo/4270]: https://github.com/rust-lang/cargo/pull/4270
|
||||
[`CStr::into_c_string`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.into_c_string
|
||||
[`CString::as_c_str`]: https://doc.rust-lang.org/std/ffi/struct.CString.html#method.as_c_str
|
||||
[`CString::into_boxed_c_str`]: https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
|
||||
@ -5873,7 +5956,6 @@ Misc
|
||||
----
|
||||
|
||||
- [rustdoc can now use pulldown-cmark with the `--enable-commonmark` flag][40338]
|
||||
- [Added rust-windbg script for better debugging on Windows][39983]
|
||||
- [Rust now uses the official cross compiler for NetBSD][40612]
|
||||
- [rustdoc now accepts `#` at the start of files][40828]
|
||||
- [Fixed jemalloc support for musl][41168]
|
||||
@ -5908,7 +5990,6 @@ Compatibility Notes
|
||||
[38165]: https://github.com/rust-lang/rust/pull/38165
|
||||
[39799]: https://github.com/rust-lang/rust/pull/39799
|
||||
[39891]: https://github.com/rust-lang/rust/pull/39891
|
||||
[39983]: https://github.com/rust-lang/rust/pull/39983
|
||||
[40043]: https://github.com/rust-lang/rust/pull/40043
|
||||
[40241]: https://github.com/rust-lang/rust/pull/40241
|
||||
[40338]: https://github.com/rust-lang/rust/pull/40338
|
||||
@ -6204,7 +6285,6 @@ Compatibility Notes
|
||||
[cargo/3691]: https://github.com/rust-lang/cargo/pull/3691
|
||||
[cargo/3699]: https://github.com/rust-lang/cargo/pull/3699
|
||||
[cargo/3731]: https://github.com/rust-lang/cargo/pull/3731
|
||||
[mdbook]: https://crates.io/crates/mdbook
|
||||
[ubook]: https://doc.rust-lang.org/unstable-book/
|
||||
|
||||
|
||||
@ -6275,7 +6355,7 @@ Libraries
|
||||
* [Ctrl-Z returns from `Stdin.read()` when reading from the console on
|
||||
Windows][38274]
|
||||
* [std: Fix partial writes in `LineWriter`][38062]
|
||||
* [std: Clamp max read/write sizes on Unix][38062]
|
||||
* [std: Clamp max read/write sizes on Unix][38622]
|
||||
* [Use more specific panic message for `&str` slicing errors][38066]
|
||||
* [`TcpListener::set_only_v6` is deprecated][38304]. This
|
||||
functionality cannot be achieved in std currently.
|
||||
@ -6341,7 +6421,7 @@ Compatibility Notes
|
||||
[38006]: https://github.com/rust-lang/rust/pull/38006
|
||||
[38051]: https://github.com/rust-lang/rust/pull/38051
|
||||
[38062]: https://github.com/rust-lang/rust/pull/38062
|
||||
[38062]: https://github.com/rust-lang/rust/pull/38622
|
||||
[38622]: https://github.com/rust-lang/rust/pull/38622
|
||||
[38066]: https://github.com/rust-lang/rust/pull/38066
|
||||
[38069]: https://github.com/rust-lang/rust/pull/38069
|
||||
[38131]: https://github.com/rust-lang/rust/pull/38131
|
||||
@ -6349,7 +6429,6 @@ Compatibility Notes
|
||||
[38274]: https://github.com/rust-lang/rust/pull/38274
|
||||
[38304]: https://github.com/rust-lang/rust/pull/38304
|
||||
[38313]: https://github.com/rust-lang/rust/pull/38313
|
||||
[38314]: https://github.com/rust-lang/rust/pull/38314
|
||||
[38327]: https://github.com/rust-lang/rust/pull/38327
|
||||
[38401]: https://github.com/rust-lang/rust/pull/38401
|
||||
[38413]: https://github.com/rust-lang/rust/pull/38413
|
||||
@ -6399,7 +6478,6 @@ Compatibility Notes
|
||||
[cargo/3546]: https://github.com/rust-lang/cargo/pull/3546
|
||||
[cargo/3557]: https://github.com/rust-lang/cargo/pull/3557
|
||||
[cargo/3604]: https://github.com/rust-lang/cargo/pull/3604
|
||||
[RFC 1623]: https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md
|
||||
|
||||
|
||||
Version 1.15.1 (2017-02-09)
|
||||
@ -6614,7 +6692,6 @@ Compatibility Notes
|
||||
[38192]: https://github.com/rust-lang/rust/pull/38192
|
||||
[38279]: https://github.com/rust-lang/rust/pull/38279
|
||||
[38835]: https://github.com/rust-lang/rust/pull/38835
|
||||
[RFC 1492]: https://github.com/rust-lang/rfcs/blob/master/text/1492-dotdot-in-patterns.md
|
||||
[RFC 1506]: https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md
|
||||
[RFC 1560]: https://github.com/rust-lang/rfcs/blob/master/text/1560-name-resolution.md
|
||||
[RFC 1681]: https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md
|
||||
@ -6803,7 +6880,6 @@ Compatibility Notes
|
||||
[1.14wasm]: https://users.rust-lang.org/t/compiling-to-the-web-with-rust-and-emscripten/7627
|
||||
[36430]: https://github.com/rust-lang/rust/pull/36430
|
||||
[36595]: https://github.com/rust-lang/rust/pull/36595
|
||||
[36595]: https://github.com/rust-lang/rust/pull/36595
|
||||
[36692]: https://github.com/rust-lang/rust/pull/36692
|
||||
[36767]: https://github.com/rust-lang/rust/pull/36767
|
||||
[36794]: https://github.com/rust-lang/rust/pull/36794
|
||||
@ -7031,7 +7107,6 @@ Compatibility Notes
|
||||
[34623]: https://github.com/rust-lang/rust/pull/34623
|
||||
[34923]: https://github.com/rust-lang/rust/pull/34923
|
||||
[34942]: https://github.com/rust-lang/rust/pull/34942
|
||||
[34982]: https://github.com/rust-lang/rust/pull/34982
|
||||
[35021]: https://github.com/rust-lang/rust/pull/35021
|
||||
[35048]: https://github.com/rust-lang/rust/pull/35048
|
||||
[35074]: https://github.com/rust-lang/rust/pull/35074
|
||||
@ -7088,7 +7163,6 @@ Compatibility Notes
|
||||
[36586]: https://github.com/rust-lang/rust/pull/36586
|
||||
[36592]: https://github.com/rust-lang/rust/pull/36592
|
||||
[36631]: https://github.com/rust-lang/rust/pull/36631
|
||||
[36639]: https://github.com/rust-lang/rust/pull/36639
|
||||
[36721]: https://github.com/rust-lang/rust/pull/36721
|
||||
[36727]: https://github.com/rust-lang/rust/pull/36727
|
||||
[36730]: https://github.com/rust-lang/rust/pull/36730
|
||||
@ -7120,7 +7194,6 @@ Compatibility Notes
|
||||
[cargo/3205]: https://github.com/rust-lang/cargo/pull/3205
|
||||
[cargo/3241]: https://github.com/rust-lang/cargo/pull/3241
|
||||
[cargo/3242]: https://github.com/rust-lang/cargo/pull/3242
|
||||
[rustup]: https://www.rustup.rs
|
||||
[`checked_abs`]: https://doc.rust-lang.org/std/primitive.i32.html#method.checked_abs
|
||||
[`wrapping_abs`]: https://doc.rust-lang.org/std/primitive.i32.html#method.wrapping_abs
|
||||
[`overflowing_abs`]: https://doc.rust-lang.org/std/primitive.i32.html#method.overflowing_abs
|
||||
@ -8038,7 +8111,7 @@ Cargo
|
||||
targets can be specified together. [RFC 1361].
|
||||
* [The environment variables `CARGO_TARGET_ROOT`, `RUSTC`, and
|
||||
`RUSTDOC` take precedence over the `build.target-dir`,
|
||||
`build.rustc`, and `build.rustdoc` configuration values][1.8cv].
|
||||
`build.rustc`, and `build.rustdoc` configuration values][1.8cfv].
|
||||
* [The child process tree is killed on Windows when Cargo is
|
||||
killed][1.8ck].
|
||||
* [The `build.target` configuration value sets the target platform,
|
||||
@ -8088,7 +8161,7 @@ Compatibility Notes
|
||||
[1.8ck]: https://github.com/rust-lang/cargo/pull/2370
|
||||
[1.8ct]: https://github.com/rust-lang/cargo/pull/2335
|
||||
[1.8cu]: https://github.com/rust-lang/rust/pull/31390
|
||||
[1.8cv]: https://github.com/rust-lang/cargo/issues/2365
|
||||
[1.8cfv]: https://github.com/rust-lang/cargo/issues/2365
|
||||
[1.8cv]: https://github.com/rust-lang/rust/pull/30998
|
||||
[1.8h]: https://github.com/rust-lang/rust/pull/31460
|
||||
[1.8l]: https://github.com/rust-lang/rust/pull/31668
|
||||
@ -9011,13 +9084,13 @@ Misc
|
||||
* The compiler gained many new extended error descriptions, which can
|
||||
be accessed with the `--explain` flag.
|
||||
* The `dropck` pass, which checks that destructors can't access
|
||||
destroyed values, [has been rewritten][dropck]. This fixes some
|
||||
destroyed values, [has been rewritten][27261]. This fixes some
|
||||
soundness holes, and as such will cause some previously-compiling
|
||||
code to no longer build.
|
||||
* `rustc` now uses [LLVM to write archive files where possible][ar].
|
||||
Eventually this will eliminate the compiler's dependency on the ar
|
||||
utility.
|
||||
* Rust has [preliminary support for i686 FreeBSD][fb] (it has long
|
||||
* Rust has [preliminary support for i686 FreeBSD][26959] (it has long
|
||||
supported FreeBSD on x86_64).
|
||||
* The [`unused_mut`][lum], [`unconditional_recursion`][lur],
|
||||
[`improper_ctypes`][lic], and [`negate_unsigned`][lnu] lints are
|
||||
@ -9056,7 +9129,7 @@ Misc
|
||||
[ar]: https://github.com/rust-lang/rust/pull/26926
|
||||
[b14]: https://static.rust-lang.org/dist/rust-beta-x86_64-pc-windows-msvc.msi
|
||||
[dms]: https://github.com/rust-lang/rust/pull/26241
|
||||
[dropck]: https://github.com/rust-lang/rust/pull/27261
|
||||
[27261]: https://github.com/rust-lang/rust/pull/27261
|
||||
[dropckrfc]: https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md
|
||||
[ds]: https://github.com/rust-lang/rust/pull/26818
|
||||
[dst1]: http://doc.rust-lang.org/nightly/std/mem/fn.size_of_val.html
|
||||
@ -9064,9 +9137,8 @@ Misc
|
||||
[dst3]: https://github.com/rust-lang/rust/pull/27351
|
||||
[e]: https://github.com/rust-lang/rust/pull/24793
|
||||
[f]: https://github.com/rust-lang/rust/pull/26588
|
||||
[fb]: https://github.com/rust-lang/rust/pull/26959
|
||||
[26959]: https://github.com/rust-lang/rust/pull/26959
|
||||
[fl]: https://github.com/rust-lang/rust-installer/pull/41
|
||||
[hs]: http://doc.rust-lang.org/nightly/std/hash/trait.Hash.html#method.hash_slice
|
||||
[ie]: http://doc.rust-lang.org/nightly/std/io/struct.Error.html
|
||||
[iec]: http://doc.rust-lang.org/nightly/std/io/struct.Error.html#method.cause
|
||||
[iegm]: http://doc.rust-lang.org/nightly/std/io/struct.Error.html#method.get_mut
|
||||
@ -9337,7 +9409,7 @@ Misc
|
||||
to rustc.
|
||||
* [Android executables are always position independent][pie].
|
||||
* [The `drop_with_repr_extern` lint warns about mixing `repr(C)`
|
||||
with `Drop`][drop].
|
||||
with `Drop`][24935].
|
||||
|
||||
[`str::split_whitespace`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_whitespace
|
||||
[`FromRawFd`]: https://doc.rust-lang.org/nightly/std/os/unix/io/trait.FromRawFd.html
|
||||
@ -9367,7 +9439,7 @@ Misc
|
||||
[`BinaryHeap`]: https://doc.rust-lang.org/nightly/std/collections/struct.BinaryHeap.html
|
||||
[ll]: https://github.com/rust-lang/rust/pull/26022
|
||||
[`split_off`]: https://doc.rust-lang.org/nightly/collections/linked_list/struct.LinkedList.html#method.split_off
|
||||
[drop]: https://github.com/rust-lang/rust/pull/24935
|
||||
[24935]: https://github.com/rust-lang/rust/pull/24935
|
||||
|
||||
Version 1.0.0 (2015-05-15)
|
||||
========================
|
||||
@ -9420,7 +9492,7 @@ Language
|
||||
property: generic code cannot behave differently for different type
|
||||
arguments except in minor ways.
|
||||
* The `unsafe_destructor` feature is now deprecated in favor of the
|
||||
[new `dropck`][dropck]. This change is a major reduction in unsafe
|
||||
[new `dropck`][rfc769]. This change is a major reduction in unsafe
|
||||
code.
|
||||
|
||||
Libraries
|
||||
@ -9428,7 +9500,7 @@ Libraries
|
||||
|
||||
* The `thread_local` module [has been renamed to `std::thread`][th].
|
||||
* The methods of `IteratorExt` [have been moved to the `Iterator`
|
||||
trait itself][ie].
|
||||
trait itself][23300].
|
||||
* Several traits that implement Rust's conventions for type
|
||||
conversions, `AsMut`, `AsRef`, `From`, and `Into` have been
|
||||
[centralized in the `std::convert` module][con].
|
||||
@ -9447,7 +9519,7 @@ Libraries
|
||||
* [In method resolution, object methods are resolved before inherent
|
||||
methods][meth].
|
||||
* [`String::from_str` has been deprecated in favor of the `From` impl,
|
||||
`String::from`][sf].
|
||||
`String::from`][24517].
|
||||
* [`io::Error` implements `Sync`][ios].
|
||||
* [The `words` method on `&str` has been replaced with
|
||||
`split_whitespace`][sw], to avoid answering the tricky question, 'what is
|
||||
@ -9495,7 +9567,7 @@ Misc
|
||||
[con]: https://github.com/rust-lang/rust/pull/23875
|
||||
[cr]: https://github.com/rust-lang/rust/pull/23419
|
||||
[fe]: https://github.com/rust-lang/rust/pull/23879
|
||||
[ie]: https://github.com/rust-lang/rust/pull/23300
|
||||
[23300]: https://github.com/rust-lang/rust/pull/23300
|
||||
[inv]: https://github.com/rust-lang/rust/pull/23938
|
||||
[ios]: https://github.com/rust-lang/rust/pull/24133
|
||||
[lex]: https://github.com/rust-lang/rfcs/blob/master/text/0879-small-base-lexing.md
|
||||
@ -9503,7 +9575,7 @@ Misc
|
||||
[meth]: https://github.com/rust-lang/rust/pull/24056
|
||||
[pat]: https://github.com/rust-lang/rfcs/blob/master/text/0528-string-patterns.md
|
||||
[po]: https://github.com/rust-lang/rust/pull/24270
|
||||
[sf]: https://github.com/rust-lang/rust/pull/24517
|
||||
[24517]: https://github.com/rust-lang/rust/pull/24517
|
||||
[slp]: https://github.com/rust-lang/rust/pull/23949
|
||||
[spl]: https://github.com/rust-lang/rfcs/blob/master/text/0979-align-splitn-with-other-languages.md
|
||||
[sw]: https://github.com/rust-lang/rfcs/blob/master/text/1054-str-words.md
|
||||
@ -9521,7 +9593,7 @@ Misc
|
||||
[conversion]: https://github.com/rust-lang/rfcs/pull/529
|
||||
[num-traits]: https://github.com/rust-lang/rust/pull/23549
|
||||
[index-value]: https://github.com/rust-lang/rust/pull/23601
|
||||
[dropck]: https://github.com/rust-lang/rfcs/pull/769
|
||||
[rfc769]: https://github.com/rust-lang/rfcs/pull/769
|
||||
[ci-compare]: https://gist.github.com/brson/a30a77836fbec057cbee
|
||||
[fn-inherit]: https://github.com/rust-lang/rust/pull/23282
|
||||
[fn-blanket]: https://github.com/rust-lang/rust/pull/23895
|
||||
|
@ -1,25 +1,32 @@
|
||||
// Configure jemalloc as the `global_allocator` when configured. This is
|
||||
// so that we use the sized deallocation apis jemalloc provides
|
||||
// (namely `sdallocx`).
|
||||
// A note about jemalloc: rustc uses jemalloc when built for CI and
|
||||
// distribution. The obvious way to do this is with the `#[global_allocator]`
|
||||
// mechanism. However, for complicated reasons (see
|
||||
// https://github.com/rust-lang/rust/pull/81782#issuecomment-784438001 for some
|
||||
// details) that mechanism doesn't work here. Also, we must use a consistent
|
||||
// allocator across the rustc <-> llvm boundary, and `#[global_allocator]`
|
||||
// wouldn't provide that.
|
||||
//
|
||||
// The symbol overrides documented below are also performed so that we can
|
||||
// ensure that we use a consistent allocator across the rustc <-> llvm boundary
|
||||
#[cfg(feature = "jemalloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
||||
|
||||
// Instead, we use a lower-level mechanism. rustc is linked with jemalloc in a
|
||||
// way such that jemalloc's implementation of `malloc`, `free`, etc., override
|
||||
// the libc allocator's implementation. This means that Rust's `System`
|
||||
// allocator, which calls `libc::malloc()` et al., is actually calling into
|
||||
// jemalloc.
|
||||
//
|
||||
// A consequence of not using `GlobalAlloc` (and the `tikv-jemallocator` crate
|
||||
// provides an impl of that trait, which is called `Jemalloc`) is that we
|
||||
// cannot use the sized deallocation APIs (`sdallocx`) that jemalloc provides.
|
||||
// It's unclear how much performance is lost because of this.
|
||||
//
|
||||
// As for the symbol overrides in `main` below: we're pulling in a static copy
|
||||
// of jemalloc. We need to actually reference its symbols for it to get linked.
|
||||
// The two crates we link to here, `std` and `rustc_driver`, are both dynamic
|
||||
// libraries. So we must reference jemalloc symbols one way or another, because
|
||||
// this file is the only object code in the rustc executable.
|
||||
#[cfg(feature = "tikv-jemalloc-sys")]
|
||||
use tikv_jemalloc_sys as jemalloc_sys;
|
||||
|
||||
fn main() {
|
||||
// Pull in jemalloc when enabled.
|
||||
//
|
||||
// Note that we're pulling in a static copy of jemalloc which means that to
|
||||
// pull it in we need to actually reference its symbols for it to get
|
||||
// linked. The two crates we link to here, std and rustc_driver, are both
|
||||
// dynamic libraries. That means to pull in jemalloc we actually need to
|
||||
// reference allocation symbols one way or another (as this file is the only
|
||||
// object code in the rustc executable).
|
||||
// See the comment at the top of this file for an explanation of this.
|
||||
#[cfg(feature = "tikv-jemalloc-sys")]
|
||||
{
|
||||
use std::os::raw::{c_int, c_void};
|
||||
|
@ -33,7 +33,6 @@
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(nll)]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -332,10 +332,7 @@ pub type GenericBounds = Vec<GenericBound>;
|
||||
pub enum ParamKindOrd {
|
||||
Lifetime,
|
||||
Type,
|
||||
// `unordered` is only `true` if `sess.unordered_const_ty_params()`
|
||||
// returns true. Specifically, if it's only `min_const_generics`, it will still require
|
||||
// ordering consts after types.
|
||||
Const { unordered: bool },
|
||||
Const,
|
||||
// `Infer` is not actually constructed directly from the AST, but is implicitly constructed
|
||||
// during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
|
||||
Infer,
|
||||
@ -346,11 +343,7 @@ impl Ord for ParamKindOrd {
|
||||
use ParamKindOrd::*;
|
||||
let to_int = |v| match v {
|
||||
Lifetime => 0,
|
||||
Infer | Type | Const { unordered: true } => 1,
|
||||
// technically both consts should be ordered equally,
|
||||
// but only one is ever encountered at a time, so this is
|
||||
// fine.
|
||||
Const { unordered: false } => 2,
|
||||
Infer | Type | Const => 1,
|
||||
};
|
||||
|
||||
to_int(*self).cmp(&to_int(*other))
|
||||
@ -517,6 +510,10 @@ pub struct Crate {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub items: Vec<P<Item>>,
|
||||
pub span: Span,
|
||||
/// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
|
||||
/// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
|
||||
pub id: NodeId,
|
||||
pub is_placeholder: bool,
|
||||
}
|
||||
|
||||
/// Possible values inside of compile-time attribute lists.
|
||||
@ -1979,7 +1976,7 @@ pub enum InlineAsmRegOrRegClass {
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||
pub struct InlineAsmOptions: u8 {
|
||||
pub struct InlineAsmOptions: u16 {
|
||||
const PURE = 1 << 0;
|
||||
const NOMEM = 1 << 1;
|
||||
const READONLY = 1 << 2;
|
||||
@ -1988,6 +1985,7 @@ bitflags::bitflags! {
|
||||
const NOSTACK = 1 << 5;
|
||||
const ATT_SYNTAX = 1 << 6;
|
||||
const RAW = 1 << 7;
|
||||
const MAY_UNWIND = 1 << 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::ptr::P;
|
||||
use super::token::Nonterminal;
|
||||
use super::tokenstream::LazyTokenStream;
|
||||
use super::{Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant};
|
||||
use super::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant};
|
||||
use super::{AssocItem, Expr, ForeignItem, Item, Local, MacCallStmt};
|
||||
use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
|
||||
use super::{AttrVec, Attribute, Stmt, StmtKind};
|
||||
@ -276,7 +276,7 @@ derive_has_tokens_and_attrs! {
|
||||
// These ast nodes only support inert attributes, so they don't
|
||||
// store tokens (since nothing can observe them)
|
||||
derive_has_attrs_no_tokens! {
|
||||
FieldDef, Arm, ExprField, PatField, Variant, Param, GenericParam
|
||||
FieldDef, Arm, ExprField, PatField, Variant, Param, GenericParam, Crate
|
||||
}
|
||||
|
||||
// These AST nodes don't support attributes, but can
|
||||
|
@ -136,15 +136,15 @@ impl Attribute {
|
||||
|
||||
pub fn value_str(&self) -> Option<Symbol> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item, _) => item.meta(self.span).and_then(|meta| meta.value_str()),
|
||||
AttrKind::Normal(ref item, _) => item.meta_kind().and_then(|kind| kind.value_str()),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item, _) => match item.meta(self.span) {
|
||||
Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
|
||||
AttrKind::Normal(ref item, _) => match item.meta_kind() {
|
||||
Some(MetaItemKind::List(list)) => Some(list),
|
||||
_ => None,
|
||||
},
|
||||
AttrKind::DocComment(..) => None,
|
||||
@ -228,6 +228,10 @@ impl AttrItem {
|
||||
span,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||
Some(MetaItemKind::from_mac_args(&self.args)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Attribute {
|
||||
@ -242,7 +246,7 @@ impl Attribute {
|
||||
match self.kind {
|
||||
AttrKind::DocComment(.., data) => Some(data),
|
||||
AttrKind::Normal(ref item, _) if item.path == sym::doc => {
|
||||
item.meta(self.span).and_then(|meta| meta.value_str())
|
||||
item.meta_kind().and_then(|kind| kind.value_str())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@ -270,6 +274,13 @@ impl Attribute {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref item, _) => item.meta_kind(),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tokens(&self) -> AttrAnnotatedTokenStream {
|
||||
match self.kind {
|
||||
AttrKind::Normal(_, ref tokens) => tokens
|
||||
@ -436,6 +447,16 @@ impl MetaItem {
|
||||
}
|
||||
|
||||
impl MetaItemKind {
|
||||
pub fn value_str(&self) -> Option<Symbol> {
|
||||
match self {
|
||||
MetaItemKind::NameValue(ref v) => match v.kind {
|
||||
LitKind::Str(ref s, _) => Some(*s),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mac_args(&self, span: Span) -> MacArgs {
|
||||
match self {
|
||||
MetaItemKind::Word => MacArgs::Empty,
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![feature(box_patterns)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(label_break_value)]
|
||||
#![feature(nll)]
|
||||
#![feature(min_specialization)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! A `MutVisitor` represents an AST modification; it accepts an AST piece and
|
||||
//! and mutates it in place. So, for instance, macro expansion is a `MutVisitor`
|
||||
//! mutates it in place. So, for instance, macro expansion is a `MutVisitor`
|
||||
//! that walks over an AST and modifies it.
|
||||
//!
|
||||
//! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on
|
||||
@ -14,13 +14,14 @@ use crate::tokenstream::*;
|
||||
|
||||
use rustc_data_structures::map_in_place::MapInPlace;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
|
||||
use smallvec::{smallvec, Array, SmallVec};
|
||||
use std::ops::DerefMut;
|
||||
use std::{panic, process, ptr};
|
||||
use std::{panic, ptr};
|
||||
|
||||
pub trait ExpectOne<A: Array> {
|
||||
fn expect_one(self, err: &'static str) -> A::Item;
|
||||
@ -283,19 +284,21 @@ pub trait MutVisitor: Sized {
|
||||
|
||||
/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
|
||||
/// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
|
||||
/// method. Abort the program if the closure panics.
|
||||
/// method.
|
||||
//
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
pub fn visit_clobber<T, F>(t: &mut T, f: F)
|
||||
where
|
||||
F: FnOnce(T) -> T,
|
||||
{
|
||||
pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) {
|
||||
unsafe {
|
||||
// Safe because `t` is used in a read-only fashion by `read()` before
|
||||
// being overwritten by `write()`.
|
||||
let old_t = ptr::read(t);
|
||||
let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t)))
|
||||
.unwrap_or_else(|_| process::abort());
|
||||
let new_t =
|
||||
panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))).unwrap_or_else(|err| {
|
||||
// Set `t` to some valid but possible meaningless value,
|
||||
// and pass the fatal error further.
|
||||
ptr::write(t, T::dummy());
|
||||
panic::resume_unwind(err);
|
||||
});
|
||||
ptr::write(t, new_t);
|
||||
}
|
||||
}
|
||||
@ -1105,36 +1108,12 @@ pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
|
||||
visit_unsafety(unsafety, vis);
|
||||
}
|
||||
|
||||
// FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible,
|
||||
// or make crate visiting first class if necessary.
|
||||
pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
|
||||
visit_clobber(krate, |Crate { attrs, items, span }| {
|
||||
let item_vis =
|
||||
Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None };
|
||||
let item = P(Item {
|
||||
ident: Ident::empty(),
|
||||
attrs,
|
||||
id: DUMMY_NODE_ID,
|
||||
vis: item_vis,
|
||||
span,
|
||||
kind: ItemKind::Mod(Unsafe::No, ModKind::Loaded(items, Inline::Yes, span)),
|
||||
tokens: None,
|
||||
});
|
||||
let items = vis.flat_map_item(item);
|
||||
|
||||
let len = items.len();
|
||||
if len == 0 {
|
||||
Crate { attrs: vec![], items: vec![], span }
|
||||
} else if len == 1 {
|
||||
let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner();
|
||||
match kind {
|
||||
ItemKind::Mod(_, ModKind::Loaded(items, ..)) => Crate { attrs, items, span },
|
||||
_ => panic!("visitor converted a module to not a module"),
|
||||
}
|
||||
} else {
|
||||
panic!("a crate cannot expand to more than one item");
|
||||
}
|
||||
});
|
||||
let Crate { attrs, items, span, id, is_placeholder: _ } = krate;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(attrs, vis);
|
||||
items.flat_map_in_place(|item| vis.flat_map_item(item));
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
// Mutates one item into possibly many items.
|
||||
@ -1475,3 +1454,109 @@ pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
|
||||
}
|
||||
vis.visit_span(&mut visibility.span);
|
||||
}
|
||||
|
||||
/// Some value for the AST node that is valid but possibly meaningless.
|
||||
pub trait DummyAstNode {
|
||||
fn dummy() -> Self;
|
||||
}
|
||||
|
||||
impl<T> DummyAstNode for Option<T> {
|
||||
fn dummy() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
|
||||
fn dummy() -> Self {
|
||||
P(DummyAstNode::dummy())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DummyAstNode for ThinVec<T> {
|
||||
fn dummy() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Item {
|
||||
fn dummy() -> Self {
|
||||
Item {
|
||||
attrs: Default::default(),
|
||||
id: DUMMY_NODE_ID,
|
||||
span: Default::default(),
|
||||
vis: Visibility {
|
||||
kind: VisibilityKind::Public,
|
||||
span: Default::default(),
|
||||
tokens: Default::default(),
|
||||
},
|
||||
ident: Ident::empty(),
|
||||
kind: ItemKind::ExternCrate(None),
|
||||
tokens: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Expr {
|
||||
fn dummy() -> Self {
|
||||
Expr {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: ExprKind::Err,
|
||||
span: Default::default(),
|
||||
attrs: Default::default(),
|
||||
tokens: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Ty {
|
||||
fn dummy() -> Self {
|
||||
Ty {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: TyKind::Err,
|
||||
span: Default::default(),
|
||||
tokens: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Pat {
|
||||
fn dummy() -> Self {
|
||||
Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: PatKind::Wild,
|
||||
span: Default::default(),
|
||||
tokens: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Stmt {
|
||||
fn dummy() -> Self {
|
||||
Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Block {
|
||||
fn dummy() -> Self {
|
||||
Block {
|
||||
stmts: Default::default(),
|
||||
id: DUMMY_NODE_ID,
|
||||
rules: BlockCheckMode::Default,
|
||||
span: Default::default(),
|
||||
tokens: Default::default(),
|
||||
could_be_bare_literal: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Crate {
|
||||
fn dummy() -> Self {
|
||||
Crate {
|
||||
attrs: Default::default(),
|
||||
items: Default::default(),
|
||||
span: Default::default(),
|
||||
id: DUMMY_NODE_ID,
|
||||
is_placeholder: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,12 +35,12 @@ impl LitKind {
|
||||
LitKind::Bool(symbol == kw::True)
|
||||
}
|
||||
token::Byte => {
|
||||
return unescape_byte(&symbol.as_str())
|
||||
return unescape_byte(symbol.as_str())
|
||||
.map(LitKind::Byte)
|
||||
.map_err(|_| LitError::LexerError);
|
||||
}
|
||||
token::Char => {
|
||||
return unescape_char(&symbol.as_str())
|
||||
return unescape_char(symbol.as_str())
|
||||
.map(LitKind::Char)
|
||||
.map_err(|_| LitError::LexerError);
|
||||
}
|
||||
@ -57,7 +57,7 @@ impl LitKind {
|
||||
// string in the token.
|
||||
let s = symbol.as_str();
|
||||
let symbol =
|
||||
if s.contains(&['\\', '\r'][..]) {
|
||||
if s.contains(&['\\', '\r']) {
|
||||
let mut buf = String::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| {
|
||||
|
@ -211,6 +211,9 @@ pub trait Visitor<'ast>: Sized {
|
||||
fn visit_pat_field(&mut self, fp: &'ast PatField) {
|
||||
walk_pat_field(self, fp)
|
||||
}
|
||||
fn visit_crate(&mut self, krate: &'ast Crate) {
|
||||
walk_crate(self, krate)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
@ -49,11 +49,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
|
||||
.emit();
|
||||
}
|
||||
if asm.options.contains(InlineAsmOptions::MAY_UNWIND)
|
||||
&& !self.sess.features_untracked().asm_unwind
|
||||
{
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::asm_unwind,
|
||||
sp,
|
||||
"the `may_unwind` option is unstable",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
let mut clobber_abis = FxHashMap::default();
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
for (abi_name, abi_span) in &asm.clobber_abis {
|
||||
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) {
|
||||
match asm::InlineAsmClobberAbi::parse(
|
||||
asm_arch,
|
||||
|feature| self.sess.target_features.contains(&Symbol::intern(feature)),
|
||||
&self.sess.target,
|
||||
*abi_name,
|
||||
) {
|
||||
Ok(abi) => {
|
||||
// If the abi was already in the list, emit an error
|
||||
match clobber_abis.get(&abi) {
|
||||
|
@ -2,7 +2,6 @@ use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
|
||||
use rustc_ast::{AttrVec, Block, BlockCheckMode, Expr, Local, LocalKind, Stmt, StmtKind};
|
||||
use rustc_hir as hir;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, DesugaringKind};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
@ -39,8 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
match &local.kind {
|
||||
LocalKind::InitElse(init, els) => {
|
||||
let (s, e) = self.lower_let_else(hir_id, local, init, els, tail);
|
||||
stmts.push(s);
|
||||
let e = self.lower_let_else(hir_id, local, init, els, tail);
|
||||
expr = Some(e);
|
||||
// remaining statements are in let-else expression
|
||||
break;
|
||||
@ -125,36 +123,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
init: &Expr,
|
||||
els: &Block,
|
||||
tail: &[Stmt],
|
||||
) -> (hir::Stmt<'hir>, &'hir hir::Expr<'hir>) {
|
||||
) -> &'hir hir::Expr<'hir> {
|
||||
let ty = local
|
||||
.ty
|
||||
.as_ref()
|
||||
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
|
||||
let span = self.lower_span(local.span);
|
||||
let span = self.mark_span_with_reason(DesugaringKind::LetElse, span, None);
|
||||
let init = Some(self.lower_expr(init));
|
||||
let val = Ident::with_dummy_span(sym::val);
|
||||
let (pat, val_id) =
|
||||
self.pat_ident_binding_mode(span, val, hir::BindingAnnotation::Unannotated);
|
||||
let init = self.lower_expr(init);
|
||||
let local_hir_id = self.lower_node_id(local.id);
|
||||
self.lower_attrs(local_hir_id, &local.attrs);
|
||||
// first statement which basically exists for the type annotation
|
||||
let stmt = {
|
||||
let local = self.arena.alloc(hir::Local {
|
||||
let let_expr = {
|
||||
let lex = self.arena.alloc(hir::Let {
|
||||
hir_id: local_hir_id,
|
||||
pat: self.lower_pat(&local.pat),
|
||||
ty,
|
||||
pat,
|
||||
init,
|
||||
span,
|
||||
source: hir::LocalSource::Normal,
|
||||
});
|
||||
let kind = hir::StmtKind::Local(local);
|
||||
hir::Stmt { hir_id: stmt_hir_id, kind, span }
|
||||
};
|
||||
let let_expr = {
|
||||
let scrutinee = self.expr_ident(span, val, val_id);
|
||||
let let_kind = hir::ExprKind::Let(self.lower_pat(&local.pat), scrutinee, span);
|
||||
self.arena.alloc(self.expr(span, let_kind, AttrVec::new()))
|
||||
self.arena.alloc(self.expr(span, hir::ExprKind::Let(lex), AttrVec::new()))
|
||||
};
|
||||
let then_expr = {
|
||||
let (stmts, expr) = self.lower_stmts(tail);
|
||||
@ -165,9 +152,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let block = self.lower_block(els, false);
|
||||
self.arena.alloc(self.expr_block(block, AttrVec::new()))
|
||||
};
|
||||
self.alias_attrs(let_expr.hir_id, local_hir_id);
|
||||
self.alias_attrs(else_expr.hir_id, local_hir_id);
|
||||
let if_expr = self.arena.alloc(hir::Expr {
|
||||
hir_id: self.next_id(),
|
||||
hir_id: stmt_hir_id,
|
||||
span,
|
||||
kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)),
|
||||
});
|
||||
@ -180,6 +168,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
(stmt, if_expr)
|
||||
if_expr
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
@ -35,7 +34,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
ExprKind::Repeat(ref expr, ref count) => {
|
||||
let expr = self.lower_expr(expr);
|
||||
let count = self.lower_anon_const(count);
|
||||
let count = self.lower_array_length(count);
|
||||
hir::ExprKind::Repeat(expr, count)
|
||||
}
|
||||
ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
|
||||
@ -92,11 +91,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let ohs = self.lower_expr(ohs);
|
||||
hir::ExprKind::AddrOf(k, m, ohs)
|
||||
}
|
||||
ExprKind::Let(ref pat, ref scrutinee, span) => hir::ExprKind::Let(
|
||||
self.lower_pat(pat),
|
||||
self.lower_expr(scrutinee),
|
||||
self.lower_span(span),
|
||||
),
|
||||
ExprKind::Let(ref pat, ref scrutinee, span) => {
|
||||
hir::ExprKind::Let(self.arena.alloc(hir::Let {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
pat: self.lower_pat(pat),
|
||||
ty: None,
|
||||
init: self.lower_expr(scrutinee),
|
||||
}))
|
||||
}
|
||||
ExprKind::If(ref cond, ref then, ref else_opt) => {
|
||||
self.lower_expr_if(cond, then, else_opt.as_deref())
|
||||
}
|
||||
@ -130,7 +133,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::AsyncGeneratorKind::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
),
|
||||
ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
|
||||
ExprKind::Await(ref expr) => {
|
||||
let span = if expr.span.hi() < e.span.hi() {
|
||||
expr.span.shrink_to_hi().with_hi(e.span.hi())
|
||||
} else {
|
||||
// this is a recovered `await expr`
|
||||
e.span
|
||||
};
|
||||
self.lower_expr_await(span, expr)
|
||||
}
|
||||
ExprKind::Closure(
|
||||
capture_clause,
|
||||
asyncness,
|
||||
@ -479,8 +490,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
expr: &'hir hir::Expr<'hir>,
|
||||
overall_span: Span,
|
||||
) -> &'hir hir::Expr<'hir> {
|
||||
let constructor =
|
||||
self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new()));
|
||||
let constructor = self.arena.alloc(self.expr_lang_item_path(
|
||||
method_span,
|
||||
lang_item,
|
||||
ThinVec::new(),
|
||||
None,
|
||||
));
|
||||
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
||||
}
|
||||
|
||||
@ -584,8 +599,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// `future::from_generator`:
|
||||
let unstable_span =
|
||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||
let gen_future =
|
||||
self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new());
|
||||
let gen_future = self.expr_lang_item_path(
|
||||
unstable_span,
|
||||
hir::LangItem::FromGenerator,
|
||||
ThinVec::new(),
|
||||
None,
|
||||
);
|
||||
|
||||
// `future::from_generator(generator)`:
|
||||
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
|
||||
@ -593,7 +612,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
/// Desugar `<expr>.await` into:
|
||||
/// ```rust
|
||||
/// match <expr> {
|
||||
/// match ::std::future::IntoFuture::into_future(<expr>) {
|
||||
/// mut pinned => loop {
|
||||
/// match unsafe { ::std::future::Future::poll(
|
||||
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
|
||||
@ -607,6 +626,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
/// }
|
||||
/// ```
|
||||
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
|
||||
let dot_await_span = expr.span.shrink_to_hi().to(await_span);
|
||||
match self.generator_kind {
|
||||
Some(hir::GeneratorKind::Async(_)) => {}
|
||||
Some(hir::GeneratorKind::Gen) | None => {
|
||||
@ -623,13 +643,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
let span = self.mark_span_with_reason(DesugaringKind::Await, await_span, None);
|
||||
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
|
||||
let gen_future_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Await,
|
||||
await_span,
|
||||
self.allow_gen_future.clone(),
|
||||
);
|
||||
let expr = self.lower_expr(expr);
|
||||
let expr = self.lower_expr_mut(expr);
|
||||
let expr_hir_id = expr.hir_id;
|
||||
|
||||
let pinned_ident = Ident::with_dummy_span(sym::pinned);
|
||||
let (pinned_pat, pinned_pat_hid) =
|
||||
@ -656,16 +677,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
span,
|
||||
hir::LangItem::PinNewUnchecked,
|
||||
arena_vec![self; ref_mut_pinned],
|
||||
Some(expr_hir_id),
|
||||
);
|
||||
let get_context = self.expr_call_lang_item_fn_mut(
|
||||
gen_future_span,
|
||||
hir::LangItem::GetContext,
|
||||
arena_vec![self; task_context],
|
||||
Some(expr_hir_id),
|
||||
);
|
||||
let call = self.expr_call_lang_item_fn(
|
||||
span,
|
||||
hir::LangItem::FuturePoll,
|
||||
arena_vec![self; new_unchecked, get_context],
|
||||
Some(expr_hir_id),
|
||||
);
|
||||
self.arena.alloc(self.expr_unsafe(call))
|
||||
};
|
||||
@ -678,18 +702,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
|
||||
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
|
||||
let ready_field = self.single_pat_field(span, x_pat);
|
||||
let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
|
||||
let ready_pat = self.pat_lang_item_variant(
|
||||
span,
|
||||
hir::LangItem::PollReady,
|
||||
ready_field,
|
||||
Some(expr_hir_id),
|
||||
);
|
||||
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||
let expr_break =
|
||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
||||
this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new()))
|
||||
this.arena.alloc(this.expr(span, expr_break, ThinVec::new()))
|
||||
});
|
||||
self.arm(ready_pat, break_x)
|
||||
};
|
||||
|
||||
// `::std::task::Poll::Pending => {}`
|
||||
let pending_arm = {
|
||||
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
|
||||
let pending_pat = self.pat_lang_item_variant(
|
||||
span,
|
||||
hir::LangItem::PollPending,
|
||||
&[],
|
||||
Some(expr_hir_id),
|
||||
);
|
||||
let empty_block = self.expr_block_empty(span);
|
||||
self.arm(pending_pat, empty_block)
|
||||
};
|
||||
@ -709,7 +743,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let unit = self.expr_unit(span);
|
||||
let yield_expr = self.expr(
|
||||
span,
|
||||
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr.hir_id) }),
|
||||
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
|
||||
ThinVec::new(),
|
||||
);
|
||||
let yield_expr = self.arena.alloc(yield_expr);
|
||||
@ -746,10 +780,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// mut pinned => loop { ... }
|
||||
let pinned_arm = self.arm(pinned_pat, loop_expr);
|
||||
|
||||
// match <expr> {
|
||||
// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
|
||||
let into_future_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Await,
|
||||
await_span,
|
||||
self.allow_into_future.clone(),
|
||||
);
|
||||
let into_future_expr = self.expr_call_lang_item_fn(
|
||||
into_future_span,
|
||||
hir::LangItem::IntoFutureIntoFuture,
|
||||
arena_vec![self; expr],
|
||||
Some(expr_hir_id),
|
||||
);
|
||||
|
||||
// match <into_future_expr> {
|
||||
// mut pinned => loop { .. }
|
||||
// }
|
||||
hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar)
|
||||
hir::ExprKind::Match(
|
||||
into_future_expr,
|
||||
arena_vec![self; pinned_arm],
|
||||
hir::MatchSource::AwaitDesugar,
|
||||
)
|
||||
}
|
||||
|
||||
fn lower_expr_closure(
|
||||
@ -914,24 +965,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
self.lower_span(eq_sign_span),
|
||||
);
|
||||
}
|
||||
if !self.sess.features_untracked().destructuring_assignment {
|
||||
let mut err = feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::destructuring_assignment,
|
||||
eq_sign_span,
|
||||
"destructuring assignments are unstable",
|
||||
);
|
||||
err.span_label(lhs.span, "cannot assign to this expression");
|
||||
if self.is_in_loop_condition {
|
||||
err.span_suggestion_verbose(
|
||||
lhs.span.shrink_to_lo(),
|
||||
"you might have meant to use pattern destructuring",
|
||||
"let ".to_string(),
|
||||
rustc_errors::Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
let mut assignments = vec![];
|
||||
|
||||
@ -1144,7 +1177,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
|
||||
let e1 = self.lower_expr_mut(e1);
|
||||
let e2 = self.lower_expr_mut(e2);
|
||||
let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span));
|
||||
let fn_path =
|
||||
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
|
||||
let fn_expr =
|
||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
|
||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||
@ -1178,7 +1212,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
|
||||
hir::ExprKind::Struct(
|
||||
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span))),
|
||||
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span), None)),
|
||||
fields,
|
||||
None,
|
||||
)
|
||||
@ -1373,6 +1407,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
head_span,
|
||||
hir::LangItem::IteratorNext,
|
||||
arena_vec![self; ref_mut_iter],
|
||||
None,
|
||||
);
|
||||
let arms = arena_vec![self; none_arm, some_arm];
|
||||
|
||||
@ -1401,6 +1436,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
head_span,
|
||||
hir::LangItem::IntoIterIntoIter,
|
||||
arena_vec![self; head],
|
||||
None,
|
||||
)
|
||||
};
|
||||
|
||||
@ -1456,6 +1492,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
unstable_span,
|
||||
hir::LangItem::TryTraitBranch,
|
||||
arena_vec![self; sub_expr],
|
||||
None,
|
||||
)
|
||||
};
|
||||
|
||||
@ -1612,8 +1649,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
args: &'hir [hir::Expr<'hir>],
|
||||
hir_id: Option<hir::HirId>,
|
||||
) -> hir::Expr<'hir> {
|
||||
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new()));
|
||||
let path =
|
||||
self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id));
|
||||
self.expr_call_mut(span, path, args)
|
||||
}
|
||||
|
||||
@ -1622,8 +1661,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
args: &'hir [hir::Expr<'hir>],
|
||||
hir_id: Option<hir::HirId>,
|
||||
) -> &'hir hir::Expr<'hir> {
|
||||
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args))
|
||||
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args, hir_id))
|
||||
}
|
||||
|
||||
fn expr_lang_item_path(
|
||||
@ -1631,10 +1671,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
attrs: AttrVec,
|
||||
hir_id: Option<hir::HirId>,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(
|
||||
span,
|
||||
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span))),
|
||||
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
|
||||
attrs,
|
||||
)
|
||||
}
|
||||
|
@ -247,12 +247,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this, idty| {
|
||||
let ret_id = asyncness.opt_return_id();
|
||||
this.lower_fn_decl(
|
||||
&decl,
|
||||
Some((fn_def_id.to_def_id(), idty)),
|
||||
true,
|
||||
ret_id,
|
||||
)
|
||||
this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
|
||||
},
|
||||
);
|
||||
let sig = hir::FnSig {
|
||||
@ -1264,7 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|this, idty| {
|
||||
this.lower_fn_decl(
|
||||
&sig.decl,
|
||||
Some((fn_def_id.to_def_id(), idty)),
|
||||
Some((fn_def_id, idty)),
|
||||
impl_trait_return_allow,
|
||||
is_async,
|
||||
)
|
||||
@ -1283,7 +1278,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
|
||||
abi::lookup(&abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
|
||||
abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
|
||||
self.error_on_invalid_abi(abi);
|
||||
abi::Abi::Rust
|
||||
})
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
@ -47,20 +46,19 @@ use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
|
||||
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
|
||||
use rustc_hir::{ConstArg, GenericArg, ParamName};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::lint::LintBuffer;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
use rustc_span::source_map::{respan, DesugaringKind};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
@ -70,10 +68,9 @@ use smallvec::SmallVec;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
macro_rules! arena_vec {
|
||||
($this:expr; $($x:expr),*) => ({
|
||||
let a = [$($x),*];
|
||||
$this.arena.alloc_from_iter(std::array::IntoIter::new(a))
|
||||
});
|
||||
($this:expr; $($x:expr),*) => (
|
||||
$this.arena.alloc_from_iter([$($x),*])
|
||||
);
|
||||
}
|
||||
|
||||
mod asm;
|
||||
@ -162,6 +159,7 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||
|
||||
allow_try_trait: Option<Lrc<[Symbol]>>,
|
||||
allow_gen_future: Option<Lrc<[Symbol]>>,
|
||||
allow_into_future: Option<Lrc<[Symbol]>>,
|
||||
}
|
||||
|
||||
pub trait ResolverAstLowering {
|
||||
@ -228,7 +226,7 @@ enum ImplTraitContext<'b, 'a> {
|
||||
ReturnPositionOpaqueTy {
|
||||
/// `DefId` for the parent function, used to look up necessary
|
||||
/// information later.
|
||||
fn_def_id: DefId,
|
||||
fn_def_id: LocalDefId,
|
||||
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
||||
origin: hir::OpaqueTyOrigin,
|
||||
},
|
||||
@ -320,6 +318,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||
in_scope_lifetimes: Vec::new(),
|
||||
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||
allow_into_future: Some([sym::into_future][..].into()),
|
||||
}
|
||||
.lower_crate(krate)
|
||||
}
|
||||
@ -645,31 +644,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
/// parameter while `f` is running (and restored afterwards).
|
||||
fn collect_in_band_defs<T>(
|
||||
&mut self,
|
||||
parent_def_id: LocalDefId,
|
||||
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
||||
f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
|
||||
) -> (Vec<hir::GenericParam<'hir>>, T) {
|
||||
assert!(!self.is_collecting_in_band_lifetimes);
|
||||
assert!(self.lifetimes_to_define.is_empty());
|
||||
let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
|
||||
f: impl FnOnce(&mut Self) -> T,
|
||||
) -> (Vec<(Span, ParamName)>, T) {
|
||||
let was_collecting = std::mem::replace(&mut self.is_collecting_in_band_lifetimes, true);
|
||||
let len = self.lifetimes_to_define.len();
|
||||
|
||||
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
|
||||
self.is_collecting_in_band_lifetimes = true;
|
||||
let res = f(self);
|
||||
|
||||
let (in_band_ty_params, res) = f(self);
|
||||
|
||||
self.is_collecting_in_band_lifetimes = false;
|
||||
self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
|
||||
|
||||
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
|
||||
|
||||
let params = lifetimes_to_define
|
||||
.into_iter()
|
||||
.map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id))
|
||||
.chain(in_band_ty_params.into_iter())
|
||||
.collect();
|
||||
|
||||
(params, res)
|
||||
let lifetimes_to_define = self.lifetimes_to_define.split_off(len);
|
||||
self.is_collecting_in_band_lifetimes = was_collecting;
|
||||
(lifetimes_to_define, res)
|
||||
}
|
||||
|
||||
/// Converts a lifetime into a new generic parameter.
|
||||
@ -784,27 +768,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
||||
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
|
||||
) -> (hir::Generics<'hir>, T) {
|
||||
let (in_band_defs, (mut lowered_generics, res)) =
|
||||
self.with_in_scope_lifetime_defs(&generics.params, |this| {
|
||||
this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
|
||||
let mut params = Vec::new();
|
||||
// Note: it is necessary to lower generics *before* calling `f`.
|
||||
// When lowering `async fn`, there's a final step when lowering
|
||||
// the return type that assumes that all in-scope lifetimes have
|
||||
// already been added to either `in_scope_lifetimes` or
|
||||
// `lifetimes_to_define`. If we swapped the order of these two,
|
||||
// in-band-lifetimes introduced by generics or where-clauses
|
||||
// wouldn't have been added yet.
|
||||
let generics = this.lower_generics_mut(
|
||||
generics,
|
||||
ImplTraitContext::Universal(&mut params, this.current_hir_id_owner),
|
||||
);
|
||||
let res = f(this, &mut params);
|
||||
(params, (generics, res))
|
||||
let (lifetimes_to_define, (mut lowered_generics, impl_trait_defs, res)) = self
|
||||
.collect_in_band_defs(|this| {
|
||||
this.with_anonymous_lifetime_mode(anonymous_lifetime_mode, |this| {
|
||||
this.with_in_scope_lifetime_defs(&generics.params, |this| {
|
||||
let mut impl_trait_defs = Vec::new();
|
||||
// Note: it is necessary to lower generics *before* calling `f`.
|
||||
// When lowering `async fn`, there's a final step when lowering
|
||||
// the return type that assumes that all in-scope lifetimes have
|
||||
// already been added to either `in_scope_lifetimes` or
|
||||
// `lifetimes_to_define`. If we swapped the order of these two,
|
||||
// in-band-lifetimes introduced by generics or where-clauses
|
||||
// wouldn't have been added yet.
|
||||
let generics = this.lower_generics_mut(
|
||||
generics,
|
||||
ImplTraitContext::Universal(
|
||||
&mut impl_trait_defs,
|
||||
this.current_hir_id_owner,
|
||||
),
|
||||
);
|
||||
let res = f(this, &mut impl_trait_defs);
|
||||
(generics, impl_trait_defs, res)
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
lowered_generics.params.extend(in_band_defs);
|
||||
lowered_generics.params.extend(
|
||||
lifetimes_to_define
|
||||
.into_iter()
|
||||
.map(|(span, hir_name)| {
|
||||
self.lifetime_to_generic_param(span, hir_name, parent_def_id)
|
||||
})
|
||||
.chain(impl_trait_defs),
|
||||
);
|
||||
|
||||
let lowered_generics = lowered_generics.into_generics(self.arena);
|
||||
(lowered_generics, res)
|
||||
@ -1116,7 +1112,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
return GenericArg::Infer(hir::InferArg {
|
||||
hir_id: self.lower_node_id(ty.id),
|
||||
span: self.lower_span(ty.span),
|
||||
kind: InferKind::Type,
|
||||
});
|
||||
}
|
||||
// We parse const arguments as path types as we cannot distinguish them during
|
||||
@ -1188,11 +1183,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
) -> hir::Ty<'hir> {
|
||||
let id = self.lower_node_id(t.id);
|
||||
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
|
||||
let ty = self.ty_path(id, t.span, qpath);
|
||||
if let hir::TyKind::TraitObject(..) = ty.kind {
|
||||
self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
|
||||
}
|
||||
ty
|
||||
self.ty_path(id, t.span, qpath)
|
||||
}
|
||||
|
||||
fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
|
||||
@ -1258,7 +1249,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
))
|
||||
}
|
||||
TyKind::Array(ref ty, ref length) => {
|
||||
hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length))
|
||||
hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
|
||||
}
|
||||
TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
|
||||
TyKind::TraitObject(ref bounds, kind) => {
|
||||
@ -1289,9 +1280,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
|
||||
(bounds, lifetime_bound)
|
||||
});
|
||||
if kind != TraitObjectSyntax::Dyn {
|
||||
self.maybe_lint_bare_trait(t.span, t.id, false);
|
||||
}
|
||||
hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
|
||||
}
|
||||
TyKind::ImplTrait(def_node_id, ref bounds) => {
|
||||
@ -1379,7 +1367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_opaque_impl_trait(
|
||||
&mut self,
|
||||
span: Span,
|
||||
fn_def_id: Option<DefId>,
|
||||
fn_def_id: Option<LocalDefId>,
|
||||
origin: hir::OpaqueTyOrigin,
|
||||
opaque_ty_node_id: NodeId,
|
||||
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
||||
@ -1451,7 +1439,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
span: lctx.lower_span(span),
|
||||
},
|
||||
bounds: hir_bounds,
|
||||
impl_trait_fn: fn_def_id,
|
||||
origin,
|
||||
};
|
||||
|
||||
@ -1521,7 +1508,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_fn_decl(
|
||||
&mut self,
|
||||
decl: &FnDecl,
|
||||
mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
|
||||
mut in_band_ty_params: Option<(LocalDefId, &mut Vec<hir::GenericParam<'hir>>)>,
|
||||
impl_trait_return_allow: bool,
|
||||
make_ret_async: Option<NodeId>,
|
||||
) -> &'hir hir::FnDecl<'hir> {
|
||||
@ -1579,7 +1566,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
Some((def_id, _)) if impl_trait_return_allow => {
|
||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
fn_def_id: def_id,
|
||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(def_id),
|
||||
}
|
||||
}
|
||||
_ => ImplTraitContext::disallowed(),
|
||||
@ -1634,7 +1621,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_async_fn_ret_ty(
|
||||
&mut self,
|
||||
output: &FnRetTy,
|
||||
fn_def_id: DefId,
|
||||
fn_def_id: LocalDefId,
|
||||
opaque_ty_node_id: NodeId,
|
||||
) -> hir::FnRetTy<'hir> {
|
||||
debug!(
|
||||
@ -1688,18 +1675,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// this is because the elided lifetimes from the return type
|
||||
// should be figured out using the ordinary elision rules, and
|
||||
// this desugaring achieves that.
|
||||
//
|
||||
// The variable `input_lifetimes_count` tracks the number of
|
||||
// lifetime parameters to the opaque type *not counting* those
|
||||
// lifetimes elided in the return type. This includes those
|
||||
// that are explicitly declared (`in_scope_lifetimes`) and
|
||||
// those elided lifetimes we found in the arguments (current
|
||||
// content of `lifetimes_to_define`). Next, we will process
|
||||
// the return type, which will cause `lifetimes_to_define` to
|
||||
// grow.
|
||||
let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
|
||||
|
||||
let mut lifetime_params = Vec::new();
|
||||
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", self.in_scope_lifetimes);
|
||||
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", self.lifetimes_to_define);
|
||||
|
||||
// Calculate all the lifetimes that should be captured
|
||||
// by the opaque type. This should include all in-scope
|
||||
// lifetime parameters, including those defined in-band.
|
||||
//
|
||||
// `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
|
||||
|
||||
// Input lifetime like `'a` or `'1`:
|
||||
let mut lifetime_params: Vec<_> = self
|
||||
.in_scope_lifetimes
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|name| (name.ident().span, name, hir::LifetimeName::Param(name)))
|
||||
.chain(
|
||||
self.lifetimes_to_define
|
||||
.iter()
|
||||
.map(|&(span, name)| (span, name, hir::LifetimeName::Param(name))),
|
||||
)
|
||||
.collect();
|
||||
|
||||
self.with_hir_id_owner(opaque_ty_node_id, |this| {
|
||||
// We have to be careful to get elision right here. The
|
||||
// idea is that we create a lifetime parameter for each
|
||||
@ -1709,34 +1707,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
//
|
||||
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
|
||||
// hence the elision takes place at the fn site.
|
||||
let future_bound = this
|
||||
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
|
||||
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
|
||||
let (lifetimes_to_define, future_bound) =
|
||||
this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
|
||||
this.collect_in_band_defs(|this| {
|
||||
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
|
||||
})
|
||||
});
|
||||
|
||||
debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
|
||||
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define);
|
||||
|
||||
// Calculate all the lifetimes that should be captured
|
||||
// by the opaque type. This should include all in-scope
|
||||
// lifetime parameters, including those defined in-band.
|
||||
//
|
||||
// Note: this must be done after lowering the output type,
|
||||
// as the output type may introduce new in-band lifetimes.
|
||||
lifetime_params = this
|
||||
.in_scope_lifetimes
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|name| (name.ident().span, name))
|
||||
.chain(this.lifetimes_to_define.iter().cloned())
|
||||
.collect();
|
||||
|
||||
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
|
||||
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
|
||||
lifetime_params.extend(
|
||||
// Output lifetime like `'_`:
|
||||
lifetimes_to_define
|
||||
.into_iter()
|
||||
.map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))),
|
||||
);
|
||||
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
|
||||
|
||||
let generic_params =
|
||||
this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
|
||||
this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id)
|
||||
this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name, _)| {
|
||||
this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id)
|
||||
}));
|
||||
|
||||
let opaque_ty_item = hir::OpaqueTy {
|
||||
@ -1746,8 +1736,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
span: this.lower_span(span),
|
||||
},
|
||||
bounds: arena_vec![this; future_bound],
|
||||
impl_trait_fn: Some(fn_def_id),
|
||||
origin: hir::OpaqueTyOrigin::AsyncFn,
|
||||
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||
};
|
||||
|
||||
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
||||
@ -1770,25 +1759,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
//
|
||||
// For the "output" lifetime parameters, we just want to
|
||||
// generate `'_`.
|
||||
let mut generic_args = Vec::with_capacity(lifetime_params.len());
|
||||
generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
|
||||
|&(span, hir_name)| {
|
||||
// Input lifetime like `'a` or `'1`:
|
||||
let generic_args =
|
||||
self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| {
|
||||
GenericArg::Lifetime(hir::Lifetime {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
name: hir::LifetimeName::Param(hir_name),
|
||||
name,
|
||||
})
|
||||
},
|
||||
));
|
||||
generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
|
||||
// Output lifetime like `'_`.
|
||||
GenericArg::Lifetime(hir::Lifetime {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
name: hir::LifetimeName::Implicit,
|
||||
})));
|
||||
let generic_args = self.arena.alloc_from_iter(generic_args);
|
||||
}));
|
||||
|
||||
// Create the `Foo<...>` reference itself. Note that the `type
|
||||
// Foo = impl Trait` is, internally, created as a child of the
|
||||
@ -1804,7 +1782,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_async_fn_output_type_to_future_bound(
|
||||
&mut self,
|
||||
output: &FnRetTy,
|
||||
fn_def_id: DefId,
|
||||
fn_def_id: LocalDefId,
|
||||
span: Span,
|
||||
) -> hir::GenericBound<'hir> {
|
||||
// Compute the `T` in `Future<Output = T>` from the return type.
|
||||
@ -1815,7 +1793,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// generates.
|
||||
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
fn_def_id,
|
||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||
};
|
||||
self.lower_ty(ty, context)
|
||||
}
|
||||
@ -1927,7 +1905,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
});
|
||||
let param_name = match lt.name {
|
||||
hir::LifetimeName::Param(param_name) => param_name,
|
||||
hir::LifetimeName::Implicit
|
||||
hir::LifetimeName::Implicit(_)
|
||||
| hir::LifetimeName::Underscore
|
||||
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
@ -2062,6 +2040,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.expr_block(block, AttrVec::new())
|
||||
}
|
||||
|
||||
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
||||
match c.value.kind {
|
||||
ExprKind::Underscore => {
|
||||
if self.sess.features_untracked().generic_arg_infer {
|
||||
hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
|
||||
} else {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::generic_arg_infer,
|
||||
c.value.span,
|
||||
"using `_` for array lengths is unstable",
|
||||
)
|
||||
.emit();
|
||||
hir::ArrayLen::Body(self.lower_anon_const(c))
|
||||
}
|
||||
}
|
||||
_ => hir::ArrayLen::Body(self.lower_anon_const(c)),
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
|
||||
self.with_new_scopes(|this| hir::AnonConst {
|
||||
hir_id: this.lower_node_id(c.id),
|
||||
@ -2139,21 +2137,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||
let field = self.single_pat_field(span, pat);
|
||||
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
|
||||
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
|
||||
}
|
||||
|
||||
fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||
let field = self.single_pat_field(span, pat);
|
||||
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
|
||||
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
|
||||
}
|
||||
|
||||
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||
let field = self.single_pat_field(span, pat);
|
||||
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
|
||||
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
|
||||
}
|
||||
|
||||
fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
|
||||
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
|
||||
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
|
||||
}
|
||||
|
||||
fn single_pat_field(
|
||||
@ -2176,8 +2174,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
fields: &'hir [hir::PatField<'hir>],
|
||||
hir_id: Option<hir::HirId>,
|
||||
) -> &'hir hir::Pat<'hir> {
|
||||
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
|
||||
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
|
||||
self.pat(span, hir::PatKind::Struct(qpath, fields, false))
|
||||
}
|
||||
|
||||
@ -2290,7 +2289,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
|
||||
|
||||
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
|
||||
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span, false),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2322,11 +2321,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&'s mut self,
|
||||
span: Span,
|
||||
count: usize,
|
||||
param_mode: ParamMode,
|
||||
) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
|
||||
(0..count).map(move |_| self.elided_path_lifetime(span))
|
||||
(0..count).map(move |_| self.elided_path_lifetime(span, param_mode))
|
||||
}
|
||||
|
||||
fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
|
||||
fn elided_path_lifetime(&mut self, span: Span, param_mode: ParamMode) -> hir::Lifetime {
|
||||
match self.anonymous_lifetime_mode {
|
||||
AnonymousLifetimeMode::CreateParameter => {
|
||||
// We should have emitted E0726 when processing this path above
|
||||
@ -2342,7 +2342,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
|
||||
// later, at which point a suitable error will be emitted.
|
||||
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
|
||||
self.new_implicit_lifetime(span)
|
||||
self.new_implicit_lifetime(span, param_mode == ParamMode::Explicit)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2385,44 +2385,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
r
|
||||
}
|
||||
|
||||
fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
|
||||
fn new_implicit_lifetime(&mut self, span: Span, missing: bool) -> hir::Lifetime {
|
||||
hir::Lifetime {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
name: hir::LifetimeName::Implicit,
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) {
|
||||
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
|
||||
// call site which do not have a macro backtrace. See #61963.
|
||||
let is_macro_callsite = self
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_snippet(span)
|
||||
.map(|snippet| snippet.starts_with("#["))
|
||||
.unwrap_or(true);
|
||||
if !is_macro_callsite {
|
||||
if span.edition() < Edition::Edition2021 {
|
||||
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
|
||||
BARE_TRAIT_OBJECTS,
|
||||
id,
|
||||
span,
|
||||
"trait objects without an explicit `dyn` are deprecated",
|
||||
BuiltinLintDiagnostics::BareTraitObject(span, is_global),
|
||||
)
|
||||
} else {
|
||||
let msg = "trait objects must include the `dyn` keyword";
|
||||
let label = "add `dyn` keyword before this trait";
|
||||
let mut err = struct_span_err!(self.sess, span, E0782, "{}", msg,);
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
label,
|
||||
String::from("dyn "),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
name: hir::LifetimeName::Implicit(missing),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2451,17 +2418,12 @@ impl<'hir> GenericArgsCtor<'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug")]
|
||||
fn lifetimes_from_impl_trait_bounds(
|
||||
opaque_ty_id: NodeId,
|
||||
bounds: hir::GenericBounds<'_>,
|
||||
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
||||
) -> Vec<(hir::LifetimeName, Span)> {
|
||||
debug!(
|
||||
"lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
|
||||
bounds={:#?})",
|
||||
opaque_ty_id, bounds,
|
||||
);
|
||||
|
||||
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
|
||||
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
||||
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
|
||||
@ -2536,7 +2498,7 @@ fn lifetimes_from_impl_trait_bounds(
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
|
||||
let name = match lifetime.name {
|
||||
hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
|
||||
hir::LifetimeName::Implicit(_) | hir::LifetimeName::Underscore => {
|
||||
if self.collect_elided_lifetimes {
|
||||
// Use `'_` for both implicit and underscore lifetimes in
|
||||
// `type Foo<'_> = impl SomeTrait<'_>;`.
|
||||
|
@ -24,7 +24,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
|
||||
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
|
||||
}
|
||||
PatKind::Lit(ref e) => break hir::PatKind::Lit(self.lower_expr(e)),
|
||||
PatKind::Lit(ref e) => {
|
||||
break hir::PatKind::Lit(self.lower_expr_within_pat(e, false));
|
||||
}
|
||||
PatKind::TupleStruct(ref qself, ref path, ref pats) => {
|
||||
let qpath = self.lower_qpath(
|
||||
pattern.id,
|
||||
@ -81,8 +83,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
|
||||
break hir::PatKind::Range(
|
||||
e1.as_deref().map(|e| self.lower_expr(e)),
|
||||
e2.as_deref().map(|e| self.lower_expr(e)),
|
||||
e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
|
||||
e2.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
|
||||
self.lower_range_end(end, e2.is_some()),
|
||||
);
|
||||
}
|
||||
@ -314,4 +316,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
RangeEnd::Excluded | RangeEnd::Included(_) => hir::RangeEnd::Included,
|
||||
}
|
||||
}
|
||||
|
||||
/// Matches `'-' lit | lit (cf. parser::Parser::parse_literal_maybe_minus)`,
|
||||
/// or paths for ranges.
|
||||
//
|
||||
// FIXME: do we want to allow `expr -> pattern` conversion to create path expressions?
|
||||
// That means making this work:
|
||||
//
|
||||
// ```rust,ignore (FIXME)
|
||||
// struct S;
|
||||
// macro_rules! m {
|
||||
// ($a:expr) => {
|
||||
// let $a = S;
|
||||
// }
|
||||
// }
|
||||
// m!(S);
|
||||
// ```
|
||||
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> {
|
||||
match expr.kind {
|
||||
ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {}
|
||||
ExprKind::Path(..) if allow_paths => {}
|
||||
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||
_ => {
|
||||
self.diagnostic()
|
||||
.span_err(expr.span, "arbitrary expressions aren't allowed in patterns");
|
||||
return self.arena.alloc(self.expr_err(expr.span));
|
||||
}
|
||||
}
|
||||
self.lower_expr(expr)
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_session::lint::builtin::ELIDED_LIFETIMES_IN_PATHS;
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
@ -231,15 +229,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
|
||||
// Do not suggest going from `Trait()` to `Trait<>`
|
||||
if !data.inputs.is_empty() {
|
||||
if let Some(split) = snippet.find('(') {
|
||||
let trait_name = &snippet[0..split];
|
||||
let args = &snippet[split + 1..snippet.len() - 1];
|
||||
err.span_suggestion(
|
||||
data.span,
|
||||
"use angle brackets instead",
|
||||
format!("{}<{}>", trait_name, args),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
// Suggest replacing `(` and `)` with `<` and `>`
|
||||
// The snippet may be missing the closing `)`, skip that case
|
||||
if snippet.ends_with(')') {
|
||||
if let Some(split) = snippet.find('(') {
|
||||
let trait_name = &snippet[0..split];
|
||||
let args = &snippet[split + 1..snippet.len() - 1];
|
||||
err.span_suggestion(
|
||||
data.span,
|
||||
"use angle brackets instead",
|
||||
format!("{}<{}>", trait_name, args),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -270,12 +272,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
let has_lifetimes =
|
||||
generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
|
||||
if !generic_args.parenthesized && !has_lifetimes {
|
||||
if !generic_args.parenthesized && !has_lifetimes && expected_lifetimes > 0 {
|
||||
// Note: these spans are used for diagnostics when they can't be inferred.
|
||||
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
|
||||
let elided_lifetime_span = if generic_args.span.is_empty() {
|
||||
// If there are no brackets, use the identifier span.
|
||||
segment.ident.span
|
||||
// HACK: we use find_ancestor_inside to properly suggest elided spans in paths
|
||||
// originating from macros, since the segment's span might be from a macro arg.
|
||||
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
|
||||
} else if generic_args.is_empty() {
|
||||
// If there are brackets, but not generic arguments, then use the opening bracket
|
||||
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
|
||||
@ -284,67 +288,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
|
||||
};
|
||||
generic_args.args = self
|
||||
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes)
|
||||
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes, param_mode)
|
||||
.map(GenericArg::Lifetime)
|
||||
.chain(generic_args.args.into_iter())
|
||||
.collect();
|
||||
if expected_lifetimes > 0 && param_mode == ParamMode::Explicit {
|
||||
// In create-parameter mode we error here because we don't want to support
|
||||
// deprecated impl elision in new features like impl elision and `async fn`,
|
||||
// both of which work using the `CreateParameter` mode:
|
||||
//
|
||||
// impl Foo for std::cell::Ref<u32> // note lack of '_
|
||||
// async fn foo(_: std::cell::Ref<u32>) { ... }
|
||||
if let (ParamMode::Explicit, AnonymousLifetimeMode::CreateParameter) =
|
||||
(param_mode, self.anonymous_lifetime_mode)
|
||||
{
|
||||
let anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", ");
|
||||
let no_non_lt_args = generic_args.args.len() == expected_lifetimes;
|
||||
let no_bindings = generic_args.bindings.is_empty();
|
||||
let (incl_angl_brckt, insertion_sp, suggestion) = if no_non_lt_args && no_bindings {
|
||||
let (incl_angl_brckt, suggestion) = if no_non_lt_args && no_bindings {
|
||||
// If there are no generic args, our suggestion can include the angle brackets.
|
||||
(true, path_span.shrink_to_hi(), format!("<{}>", anon_lt_suggestion))
|
||||
(true, format!("<{}>", anon_lt_suggestion))
|
||||
} else {
|
||||
// Otherwise we'll insert a `'_, ` right after the opening bracket.
|
||||
let span = generic_args
|
||||
.span
|
||||
.with_lo(generic_args.span.lo() + BytePos(1))
|
||||
.shrink_to_lo();
|
||||
(false, span, format!("{}, ", anon_lt_suggestion))
|
||||
(false, format!("{}, ", anon_lt_suggestion))
|
||||
};
|
||||
match self.anonymous_lifetime_mode {
|
||||
// In create-parameter mode we error here because we don't want to support
|
||||
// deprecated impl elision in new features like impl elision and `async fn`,
|
||||
// both of which work using the `CreateParameter` mode:
|
||||
//
|
||||
// impl Foo for std::cell::Ref<u32> // note lack of '_
|
||||
// async fn foo(_: std::cell::Ref<u32>) { ... }
|
||||
AnonymousLifetimeMode::CreateParameter => {
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
path_span,
|
||||
E0726,
|
||||
"implicit elided lifetime not allowed here"
|
||||
);
|
||||
rustc_errors::add_elided_lifetime_in_path_suggestion(
|
||||
&self.sess.source_map(),
|
||||
&mut err,
|
||||
expected_lifetimes,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_sp,
|
||||
suggestion,
|
||||
);
|
||||
err.note("assuming a `'static` lifetime...");
|
||||
err.emit();
|
||||
}
|
||||
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
|
||||
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
|
||||
ELIDED_LIFETIMES_IN_PATHS,
|
||||
CRATE_NODE_ID,
|
||||
path_span,
|
||||
"hidden lifetime parameters in types are deprecated",
|
||||
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
|
||||
expected_lifetimes,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_sp,
|
||||
suggestion,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
let insertion_sp = elided_lifetime_span.shrink_to_hi();
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
path_span,
|
||||
E0726,
|
||||
"implicit elided lifetime not allowed here"
|
||||
);
|
||||
rustc_errors::add_elided_lifetime_in_path_suggestion(
|
||||
&self.sess.source_map(),
|
||||
&mut err,
|
||||
expected_lifetimes,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_sp,
|
||||
suggestion,
|
||||
);
|
||||
err.note("assuming a `'static` lifetime...");
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
use std::mem;
|
||||
use std::ops::DerefMut;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
const MORE_EXTERN: &str =
|
||||
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
|
||||
@ -302,34 +302,6 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Matches `'-' lit | lit (cf. parser::Parser::parse_literal_maybe_minus)`,
|
||||
/// or paths for ranges.
|
||||
//
|
||||
// FIXME: do we want to allow `expr -> pattern` conversion to create path expressions?
|
||||
// That means making this work:
|
||||
//
|
||||
// ```rust,ignore (FIXME)
|
||||
// struct S;
|
||||
// macro_rules! m {
|
||||
// ($a:expr) => {
|
||||
// let $a = S;
|
||||
// }
|
||||
// }
|
||||
// m!(S);
|
||||
// ```
|
||||
fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) {
|
||||
match expr.kind {
|
||||
ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {}
|
||||
ExprKind::Path(..) if allow_paths => {}
|
||||
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||
_ => self.err_handler().span_err(
|
||||
expr.span,
|
||||
"arbitrary expressions aren't allowed \
|
||||
in patterns",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
|
||||
// Check only lifetime parameters are present and that the lifetime
|
||||
// parameters that are present have no bounds.
|
||||
@ -580,8 +552,7 @@ impl<'a> AstValidator<'a> {
|
||||
|
||||
/// An item in `extern { ... }` cannot use non-ascii identifier.
|
||||
fn check_foreign_item_ascii_only(&self, ident: Ident) {
|
||||
let symbol_str = ident.as_str();
|
||||
if !symbol_str.is_ascii() {
|
||||
if !ident.as_str().is_ascii() {
|
||||
let n = 83942;
|
||||
self.err_handler()
|
||||
.struct_span_err(
|
||||
@ -894,7 +865,6 @@ impl<'a> AstValidator<'a> {
|
||||
/// Checks that generic parameters are in the correct order,
|
||||
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
|
||||
fn validate_generic_param_order(
|
||||
sess: &Session,
|
||||
handler: &rustc_errors::Handler,
|
||||
generics: &[GenericParam],
|
||||
span: Span,
|
||||
@ -911,8 +881,7 @@ fn validate_generic_param_order(
|
||||
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
|
||||
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
let unordered = sess.features_untracked().unordered_const_ty_params();
|
||||
(ParamKindOrd::Const { unordered }, format!("const {}: {}", ident, ty))
|
||||
(ParamKindOrd::Const, format!("const {}: {}", ident, ty))
|
||||
}
|
||||
};
|
||||
param_idents.push((kind, ord_kind, bounds, idx, ident));
|
||||
@ -968,14 +937,7 @@ fn validate_generic_param_order(
|
||||
);
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"reorder the parameters: lifetimes, {}",
|
||||
if sess.features_untracked().unordered_const_ty_params() {
|
||||
"then consts and types"
|
||||
} else {
|
||||
"then types, then consts"
|
||||
}
|
||||
),
|
||||
"reorder the parameters: lifetimes, then consts and types",
|
||||
ordered_params.clone(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
@ -1342,8 +1304,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &'a Generics) {
|
||||
let cg_defaults = self.session.features_untracked().unordered_const_ty_params();
|
||||
|
||||
let mut prev_param_default = None;
|
||||
for param in &generics.params {
|
||||
match param.kind {
|
||||
@ -1358,12 +1318,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
span,
|
||||
"generic parameters with a default must be trailing",
|
||||
);
|
||||
if matches!(param.kind, GenericParamKind::Const { .. }) && !cg_defaults {
|
||||
err.note(
|
||||
"using type defaults and const parameters \
|
||||
in the same parameter list is currently not permitted",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
break;
|
||||
}
|
||||
@ -1371,12 +1325,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
validate_generic_param_order(
|
||||
self.session,
|
||||
self.err_handler(),
|
||||
&generics.params,
|
||||
generics.span,
|
||||
);
|
||||
validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
|
||||
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
||||
@ -1449,25 +1398,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
visit::walk_param_bound(self, bound)
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &'a Pat) {
|
||||
match &pat.kind {
|
||||
PatKind::Lit(expr) => {
|
||||
self.check_expr_within_pat(expr, false);
|
||||
}
|
||||
PatKind::Range(start, end, _) => {
|
||||
if let Some(expr) = start {
|
||||
self.check_expr_within_pat(expr, true);
|
||||
}
|
||||
if let Some(expr) = end {
|
||||
self.check_expr_within_pat(expr, true);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_pat(self, pat)
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifier) {
|
||||
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
|
||||
visit::walk_poly_trait_ref(self, t, m);
|
||||
@ -1714,6 +1644,53 @@ fn deny_equality_constraints(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
|
||||
if let [potential_param, potential_assoc] = &full_path.segments[..] {
|
||||
for param in &generics.params {
|
||||
if param.ident == potential_param.ident {
|
||||
for bound in ¶m.bounds {
|
||||
if let ast::GenericBound::Trait(trait_ref, TraitBoundModifier::None) = bound
|
||||
{
|
||||
if let [trait_segment] = &trait_ref.trait_ref.path.segments[..] {
|
||||
let assoc = pprust::path_to_string(&ast::Path::from_ident(
|
||||
potential_assoc.ident,
|
||||
));
|
||||
let ty = pprust::ty_to_string(&predicate.rhs_ty);
|
||||
let (args, span) = match &trait_segment.args {
|
||||
Some(args) => match args.deref() {
|
||||
ast::GenericArgs::AngleBracketed(args) => {
|
||||
let Some(arg) = args.args.last() else {
|
||||
continue;
|
||||
};
|
||||
(
|
||||
format!(", {} = {}", assoc, ty),
|
||||
arg.span().shrink_to_hi(),
|
||||
)
|
||||
}
|
||||
_ => continue,
|
||||
},
|
||||
None => (
|
||||
format!("<{} = {}>", assoc, ty),
|
||||
trait_segment.span().shrink_to_hi(),
|
||||
),
|
||||
};
|
||||
err.multipart_suggestion(
|
||||
&format!(
|
||||
"if `{}::{}` is an associated type you're trying to set, \
|
||||
use the associated type binding syntax",
|
||||
trait_segment.ident, potential_assoc.ident,
|
||||
),
|
||||
vec![(span, args), (predicate.span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err.note(
|
||||
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
|
||||
);
|
||||
|
@ -61,7 +61,7 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||
fn check_abi(&self, abi: ast::StrLit) {
|
||||
let ast::StrLit { symbol_unescaped, span, .. } = abi;
|
||||
|
||||
match &*symbol_unescaped.as_str() {
|
||||
match symbol_unescaped.as_str() {
|
||||
// Stable
|
||||
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
||||
| "system" => {}
|
||||
@ -347,7 +347,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
|
||||
if let Some(modifiers) = nested_meta.value_str() {
|
||||
for modifier in modifiers.as_str().split(',') {
|
||||
if let Some(modifier) = modifier.strip_prefix(&['+', '-'][..]) {
|
||||
if let Some(modifier) = modifier.strip_prefix(&['+', '-']) {
|
||||
macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => {
|
||||
$(if modifier == $name {
|
||||
let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable");
|
||||
@ -383,7 +383,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
ast::ItemKind::Fn(..) => {
|
||||
if self.sess.contains_name(&i.attrs[..], sym::start) {
|
||||
if self.sess.contains_name(&i.attrs, sym::start) {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
start,
|
||||
@ -396,7 +396,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
ast::ItemKind::Struct(..) => {
|
||||
for attr in self.sess.filter_by_name(&i.attrs[..], sym::repr) {
|
||||
for attr in self.sess.filter_by_name(&i.attrs, sym::repr) {
|
||||
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
|
||||
if item.has_name(sym::simd) {
|
||||
gate_feature_post!(
|
||||
@ -724,15 +724,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
||||
gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
|
||||
gate_all!(inline_const, "inline-const is experimental");
|
||||
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
|
||||
gate_all!(
|
||||
const_generics_defaults,
|
||||
"default values for const generic parameters are experimental"
|
||||
);
|
||||
if sess.parse_sess.span_diagnostic.err_count() == 0 {
|
||||
// Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
|
||||
// involved, so we only emit errors where there are no other parsing errors.
|
||||
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
|
||||
}
|
||||
|
||||
// All uses of `gate_all!` below this point were added in #65742,
|
||||
// and subsequently disabled (with the non-early gating readded).
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#![feature(iter_is_partitioned)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(let_else)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
pub mod ast_validation;
|
||||
|
@ -35,4 +35,14 @@ impl Printer {
|
||||
self.word(w);
|
||||
self.nbsp()
|
||||
}
|
||||
|
||||
// Synthesizes a comment that was not textually present in the original
|
||||
// source file.
|
||||
pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) {
|
||||
self.word("/*");
|
||||
self.space();
|
||||
self.word(text);
|
||||
self.space();
|
||||
self.word("*/")
|
||||
}
|
||||
}
|
||||
|
@ -73,5 +73,14 @@ pub fn attribute_to_string(attr: &ast::Attribute) -> String {
|
||||
}
|
||||
|
||||
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
|
||||
State::new().to_string(f)
|
||||
State::to_string(f)
|
||||
}
|
||||
|
||||
pub fn crate_to_string_for_macros(krate: &ast::Crate) -> String {
|
||||
State::to_string(|s| {
|
||||
s.print_inner_attributes(&krate.attrs);
|
||||
for item in &krate.items {
|
||||
s.print_item(item);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -236,7 +236,7 @@ where
|
||||
|
||||
// These unwraps are safe because `get` ensures the meta item
|
||||
// is a name/value pair string literal.
|
||||
issue_num = match &*issue.unwrap().as_str() {
|
||||
issue_num = match issue.unwrap().as_str() {
|
||||
"none" => None,
|
||||
issue => {
|
||||
let emit_diag = |msg: &str| {
|
||||
@ -301,7 +301,7 @@ where
|
||||
|
||||
match (feature, reason, issue) {
|
||||
(Some(feature), reason, Some(_)) => {
|
||||
if !rustc_lexer::is_ident(&feature.as_str()) {
|
||||
if !rustc_lexer::is_ident(feature.as_str()) {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
@ -519,8 +519,10 @@ pub fn eval_condition(
|
||||
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||
(sym, span)
|
||||
}
|
||||
[NestedMetaItem::Literal(Lit { span, .. })
|
||||
| NestedMetaItem::MetaItem(MetaItem { span, .. })] => {
|
||||
[
|
||||
NestedMetaItem::Literal(Lit { span, .. })
|
||||
| NestedMetaItem::MetaItem(MetaItem { span, .. }),
|
||||
] => {
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(*span, "expected a version literal")
|
||||
.emit();
|
||||
@ -533,7 +535,7 @@ pub fn eval_condition(
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let min_version = match parse_version(&min_version.as_str(), false) {
|
||||
let min_version = match parse_version(min_version.as_str(), false) {
|
||||
Some(ver) => ver,
|
||||
None => {
|
||||
sess.span_diagnostic
|
||||
|
@ -84,7 +84,7 @@ pub enum LocalsStateAtExit {
|
||||
}
|
||||
|
||||
impl LocalsStateAtExit {
|
||||
fn build(
|
||||
fn build<'tcx>(
|
||||
locals_are_invalidated_at_exit: bool,
|
||||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
|
@ -5,7 +5,7 @@ use rustc_middle::ty::RegionVid;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
|
||||
use rustc_mir_dataflow::ResultsVisitable;
|
||||
use rustc_mir_dataflow::{self, fmt::DebugWithContext, GenKill};
|
||||
use rustc_mir_dataflow::{self, fmt::DebugWithContext, CallReturnPlaces, GenKill};
|
||||
use rustc_mir_dataflow::{Analysis, Direction, Results};
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
@ -434,9 +434,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
||||
&self,
|
||||
_trans: &mut impl GenKill<Self::Idx>,
|
||||
_block: mir::BasicBlock,
|
||||
_func: &mir::Operand<'tcx>,
|
||||
_args: &[mir::Operand<'tcx>],
|
||||
_dest_place: mir::Place<'tcx>,
|
||||
_return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store) |
|
||||
|
||||
// This is potentially both a def and a use...
|
||||
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
|
||||
PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput) |
|
||||
|
||||
// We let Call define the result in both the success and
|
||||
// unwind cases. This is not really correct, however it
|
||||
@ -26,6 +26,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||
// the def in call only to the input from the success
|
||||
// path and not the unwind path. -nmatsakis
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Call) |
|
||||
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Yield) |
|
||||
|
||||
// Storage live and storage dead aren't proper defines, but we can ignore
|
||||
|
@ -31,7 +31,7 @@ enum UniverseInfoInner<'tcx> {
|
||||
Other,
|
||||
}
|
||||
|
||||
impl UniverseInfo<'tcx> {
|
||||
impl<'tcx> UniverseInfo<'tcx> {
|
||||
crate fn other() -> UniverseInfo<'tcx> {
|
||||
UniverseInfo(UniverseInfoInner::Other)
|
||||
}
|
||||
@ -191,7 +191,7 @@ struct PredicateQuery<'tcx> {
|
||||
base_universe: ty::UniverseIndex,
|
||||
}
|
||||
|
||||
impl TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||
impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||
fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error");
|
||||
err.note(&format!("could not prove {}", self.canonical_query.value.value.predicate));
|
||||
@ -231,7 +231,7 @@ struct NormalizeQuery<'tcx, T> {
|
||||
base_universe: ty::UniverseIndex,
|
||||
}
|
||||
|
||||
impl<T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
|
||||
impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
|
||||
where
|
||||
T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx,
|
||||
{
|
||||
@ -291,7 +291,7 @@ struct AscribeUserTypeQuery<'tcx> {
|
||||
base_universe: ty::UniverseIndex,
|
||||
}
|
||||
|
||||
impl TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||
impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||
fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
// FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
|
||||
// and is only the fallback when the nice error fails. Consider improving this some more.
|
||||
@ -368,6 +368,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||
error_region,
|
||||
cause.clone(),
|
||||
placeholder_region,
|
||||
vec![],
|
||||
),
|
||||
),
|
||||
(Some(error_region), _) => NiceRegionError::new(
|
||||
|
@ -15,16 +15,18 @@ use rustc_span::symbol::sym;
|
||||
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
|
||||
use crate::borrow_set::TwoPhaseActivation;
|
||||
use crate::borrowck_errors;
|
||||
|
||||
use crate::diagnostics::find_all_local_uses;
|
||||
use crate::{
|
||||
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
||||
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
|
||||
};
|
||||
|
||||
use super::{
|
||||
explain_borrow::BorrowExplanation, FnSelfUseKind, IncludingDowncast, RegionName,
|
||||
RegionNameSource, UseSpans,
|
||||
explain_borrow::{BorrowExplanation, LaterUseKind},
|
||||
FnSelfUseKind, IncludingDowncast, RegionName, RegionNameSource, UseSpans,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -414,7 +416,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
tcx,
|
||||
generics,
|
||||
&mut err,
|
||||
¶m.name.as_str(),
|
||||
param.name.as_str(),
|
||||
"Copy",
|
||||
None,
|
||||
);
|
||||
@ -768,9 +770,92 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
Some((issued_span, span)),
|
||||
);
|
||||
|
||||
self.suggest_using_local_if_applicable(
|
||||
&mut err,
|
||||
location,
|
||||
(place, span),
|
||||
gen_borrow_kind,
|
||||
issued_borrow,
|
||||
explanation,
|
||||
);
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, err))]
|
||||
fn suggest_using_local_if_applicable(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
location: Location,
|
||||
(place, span): (Place<'tcx>, Span),
|
||||
gen_borrow_kind: BorrowKind,
|
||||
issued_borrow: &BorrowData<'tcx>,
|
||||
explanation: BorrowExplanation,
|
||||
) {
|
||||
let used_in_call =
|
||||
matches!(explanation, BorrowExplanation::UsedLater(LaterUseKind::Call, _call_span, _));
|
||||
if !used_in_call {
|
||||
debug!("not later used in call");
|
||||
return;
|
||||
}
|
||||
|
||||
let outer_call_loc =
|
||||
if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
|
||||
loc
|
||||
} else {
|
||||
issued_borrow.reserve_location
|
||||
};
|
||||
let outer_call_stmt = self.body.stmt_at(outer_call_loc);
|
||||
|
||||
let inner_param_location = location;
|
||||
let Some(inner_param_stmt) = self.body.stmt_at(inner_param_location).left() else {
|
||||
debug!("`inner_param_location` {:?} is not for a statement", inner_param_location);
|
||||
return;
|
||||
};
|
||||
let Some(&inner_param) = inner_param_stmt.kind.as_assign().map(|(p, _)| p) else {
|
||||
debug!(
|
||||
"`inner_param_location` {:?} is not for an assignment: {:?}",
|
||||
inner_param_location, inner_param_stmt
|
||||
);
|
||||
return;
|
||||
};
|
||||
let inner_param_uses = find_all_local_uses::find(self.body, inner_param.local);
|
||||
let Some((inner_call_loc,inner_call_term)) = inner_param_uses.into_iter().find_map(|loc| {
|
||||
let Either::Right(term) = self.body.stmt_at(loc) else {
|
||||
debug!("{:?} is a statement, so it can't be a call", loc);
|
||||
return None;
|
||||
};
|
||||
let TerminatorKind::Call { args, .. } = &term.kind else {
|
||||
debug!("not a call: {:?}", term);
|
||||
return None;
|
||||
};
|
||||
debug!("checking call args for uses of inner_param: {:?}", args);
|
||||
if args.contains(&Operand::Move(inner_param)) {
|
||||
Some((loc,term))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) else {
|
||||
debug!("no uses of inner_param found as a by-move call arg");
|
||||
return;
|
||||
};
|
||||
debug!("===> outer_call_loc = {:?}, inner_call_loc = {:?}", outer_call_loc, inner_call_loc);
|
||||
|
||||
let inner_call_span = inner_call_term.source_info.span;
|
||||
let outer_call_span = outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span;
|
||||
if outer_call_span == inner_call_span || !outer_call_span.contains(inner_call_span) {
|
||||
// FIXME: This stops the suggestion in some cases where it should be emitted.
|
||||
// Fix the spans for those cases so it's emitted correctly.
|
||||
debug!(
|
||||
"outer span {:?} does not strictly contain inner span {:?}",
|
||||
outer_call_span, inner_call_span
|
||||
);
|
||||
return;
|
||||
}
|
||||
err.span_help(inner_call_span, "try adding a local storing this argument...");
|
||||
err.span_help(outer_call_span, "...and then using that local as the argument to this call");
|
||||
}
|
||||
|
||||
fn suggest_split_at_mut_if_applicable(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
@ -977,9 +1062,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
Some(ref name),
|
||||
BorrowExplanation::MustBeValidFor {
|
||||
category:
|
||||
category
|
||||
@
|
||||
(ConstraintCategory::Return(_)
|
||||
category @ (ConstraintCategory::Return(_)
|
||||
| ConstraintCategory::CallArgument
|
||||
| ConstraintCategory::OpaqueType),
|
||||
from_closure: false,
|
||||
@ -1515,8 +1598,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
location: Location,
|
||||
mpi: MovePathIndex,
|
||||
) -> (Vec<MoveSite>, Vec<Location>) {
|
||||
fn predecessor_locations(
|
||||
body: &'a mir::Body<'tcx>,
|
||||
fn predecessor_locations<'a>(
|
||||
body: &'a mir::Body<'_>,
|
||||
location: Location,
|
||||
) -> impl Iterator<Item = Location> + 'a {
|
||||
if location.statement_index == 0 {
|
||||
|
@ -0,0 +1,26 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{Body, Local, Location};
|
||||
|
||||
/// Find all uses of (including assignments to) a [`Local`].
|
||||
///
|
||||
/// Uses `BTreeSet` so output is deterministic.
|
||||
pub(super) fn find<'tcx>(body: &Body<'tcx>, local: Local) -> BTreeSet<Location> {
|
||||
let mut visitor = AllLocalUsesVisitor { for_local: local, uses: BTreeSet::default() };
|
||||
visitor.visit_body(body);
|
||||
visitor.uses
|
||||
}
|
||||
|
||||
struct AllLocalUsesVisitor {
|
||||
for_local: Local,
|
||||
uses: BTreeSet<Location>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for AllLocalUsesVisitor {
|
||||
fn visit_local(&mut self, local: &Local, _context: PlaceContext, location: Location) {
|
||||
if *local == self.for_local {
|
||||
self.uses.insert(location);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ use rustc_target::abi::VariantIdx;
|
||||
use super::borrow_set::BorrowData;
|
||||
use super::MirBorrowckCtxt;
|
||||
|
||||
mod find_all_local_uses;
|
||||
mod find_use;
|
||||
mod outlives_suggestion;
|
||||
mod region_name;
|
||||
@ -205,7 +206,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
{
|
||||
let local_info = &self.body.local_decls[local].local_info;
|
||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
|
||||
buf.push_str(&self.infcx.tcx.item_name(def_id).as_str());
|
||||
buf.push_str(self.infcx.tcx.item_name(def_id).as_str());
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
@ -317,7 +318,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let decl = &self.body.local_decls[local];
|
||||
match self.local_names[local] {
|
||||
Some(name) if !decl.from_compiler_desugaring() => {
|
||||
buf.push_str(&name.as_str());
|
||||
buf.push_str(name.as_str());
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(()),
|
||||
@ -408,7 +409,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
/// Add a note that a type does not implement `Copy`
|
||||
pub(super) fn note_type_does_not_implement_copy(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'a>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
place_desc: &str,
|
||||
ty: Ty<'tcx>,
|
||||
span: Option<Span>,
|
||||
@ -732,21 +733,19 @@ pub(super) enum BorrowedContentSource<'tcx> {
|
||||
OverloadedIndex(Ty<'tcx>),
|
||||
}
|
||||
|
||||
impl BorrowedContentSource<'tcx> {
|
||||
impl<'tcx> BorrowedContentSource<'tcx> {
|
||||
pub(super) fn describe_for_unnamed_place(&self, tcx: TyCtxt<'_>) -> String {
|
||||
match *self {
|
||||
BorrowedContentSource::DerefRawPointer => "a raw pointer".to_string(),
|
||||
BorrowedContentSource::DerefSharedRef => "a shared reference".to_string(),
|
||||
BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
|
||||
BorrowedContentSource::OverloadedDeref(ty) => match ty.kind() {
|
||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
|
||||
"an `Rc`".to_string()
|
||||
}
|
||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
|
||||
"an `Arc`".to_string()
|
||||
}
|
||||
_ => format!("dereference of `{}`", ty),
|
||||
},
|
||||
BorrowedContentSource::OverloadedDeref(ty) => ty
|
||||
.ty_adt_def()
|
||||
.and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
|
||||
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
|
||||
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
|
||||
}
|
||||
}
|
||||
@ -770,15 +769,13 @@ impl BorrowedContentSource<'tcx> {
|
||||
BorrowedContentSource::DerefMutableRef => {
|
||||
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
|
||||
}
|
||||
BorrowedContentSource::OverloadedDeref(ty) => match ty.kind() {
|
||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
|
||||
"an `Rc`".to_string()
|
||||
}
|
||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
|
||||
"an `Arc`".to_string()
|
||||
}
|
||||
_ => format!("a dereference of `{}`", ty),
|
||||
},
|
||||
BorrowedContentSource::OverloadedDeref(ty) => ty
|
||||
.ty_adt_def()
|
||||
.and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
|
||||
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
|
||||
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty),
|
||||
}
|
||||
}
|
||||
@ -960,8 +957,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
_ => None,
|
||||
});
|
||||
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
|
||||
tcx.is_diagnostic_item(sym::Option, def_id)
|
||||
|| tcx.is_diagnostic_item(sym::Result, def_id)
|
||||
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
|
||||
});
|
||||
FnSelfUseKind::Normal { self_arg, implicit_into_iter, is_option_or_result }
|
||||
});
|
||||
|
@ -165,10 +165,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
PlaceRef {
|
||||
local: _,
|
||||
projection:
|
||||
[.., ProjectionElem::Index(_)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..)],
|
||||
[
|
||||
..,
|
||||
ProjectionElem::Index(_)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..),
|
||||
],
|
||||
} => bug!("Unexpected immutable place."),
|
||||
}
|
||||
|
||||
@ -217,19 +220,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
PlaceRef {
|
||||
local,
|
||||
projection:
|
||||
[proj_base @ .., ProjectionElem::Deref, ProjectionElem::Field(field, _), ProjectionElem::Deref],
|
||||
[
|
||||
proj_base @ ..,
|
||||
ProjectionElem::Deref,
|
||||
ProjectionElem::Field(field, _),
|
||||
ProjectionElem::Deref,
|
||||
],
|
||||
} => {
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
|
||||
if let Some((span, message)) = annotate_struct_field(
|
||||
if let Some(span) = get_mut_span_in_struct_field(
|
||||
self.infcx.tcx,
|
||||
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
|
||||
field,
|
||||
) {
|
||||
err.span_suggestion(
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
"consider changing this to be mutable",
|
||||
message,
|
||||
" mut ".into(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
@ -739,7 +747,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
HirId, ImplItem, ImplItemKind, Item, ItemKind,
|
||||
};
|
||||
|
||||
fn maybe_body_id_of_fn(hir_map: &Map<'tcx>, id: HirId) -> Option<BodyId> {
|
||||
fn maybe_body_id_of_fn(hir_map: &Map<'_>, id: HirId) -> Option<BodyId> {
|
||||
match hir_map.find(id) {
|
||||
Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. }))
|
||||
| Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => {
|
||||
@ -763,11 +771,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
kind:
|
||||
Call(
|
||||
_,
|
||||
[Expr {
|
||||
kind: MethodCall(path_segment, ..),
|
||||
hir_id,
|
||||
..
|
||||
}, ..],
|
||||
[
|
||||
Expr {
|
||||
kind: MethodCall(path_segment, ..),
|
||||
hir_id,
|
||||
..
|
||||
},
|
||||
..,
|
||||
],
|
||||
),
|
||||
..
|
||||
},
|
||||
@ -1048,18 +1059,18 @@ fn is_closure_or_generator(ty: Ty<'_>) -> bool {
|
||||
ty.is_closure() || ty.is_generator()
|
||||
}
|
||||
|
||||
/// Adds a suggestion to a struct definition given a field access to a local.
|
||||
/// This function expects the local to be a reference to a struct in order to produce a suggestion.
|
||||
/// Given a field that needs to be mutable, returns a span where the " mut " could go.
|
||||
/// This function expects the local to be a reference to a struct in order to produce a span.
|
||||
///
|
||||
/// ```text
|
||||
/// LL | s: &'a String
|
||||
/// | ---------- use `&'a mut String` here to make mutable
|
||||
/// LL | s: &'a String
|
||||
/// | ^^^ returns a span taking up the space here
|
||||
/// ```
|
||||
fn annotate_struct_field(
|
||||
fn get_mut_span_in_struct_field<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
field: &mir::Field,
|
||||
) -> Option<(Span, String)> {
|
||||
) -> Option<Span> {
|
||||
// Expect our local to be a reference to a struct of some kind.
|
||||
if let ty::Ref(_, ty, _) = ty.kind() {
|
||||
if let ty::Adt(def, _) = ty.kind() {
|
||||
@ -1070,25 +1081,10 @@ fn annotate_struct_field(
|
||||
// Now we're dealing with the actual struct that we're going to suggest a change to,
|
||||
// we can expect a field that is an immutable reference to a type.
|
||||
if let hir::Node::Field(field) = node {
|
||||
if let hir::TyKind::Rptr(
|
||||
lifetime,
|
||||
hir::MutTy { mutbl: hir::Mutability::Not, ref ty },
|
||||
) = field.ty.kind
|
||||
if let hir::TyKind::Rptr(lifetime, hir::MutTy { mutbl: hir::Mutability::Not, ty }) =
|
||||
field.ty.kind
|
||||
{
|
||||
// Get the snippets in two parts - the named lifetime (if there is one) and
|
||||
// type being referenced, that way we can reconstruct the snippet without loss
|
||||
// of detail.
|
||||
let type_snippet = tcx.sess.source_map().span_to_snippet(ty.span).ok()?;
|
||||
let lifetime_snippet = if !lifetime.is_elided() {
|
||||
format!("{} ", tcx.sess.source_map().span_to_snippet(lifetime.span).ok()?)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
return Some((
|
||||
field.ty.span,
|
||||
format!("&{}mut {}", lifetime_snippet, &*type_snippet,),
|
||||
));
|
||||
return Some(lifetime.span.between(ty.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use rustc_infer::infer::{
|
||||
error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin,
|
||||
};
|
||||
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::{BytePos, Span};
|
||||
@ -334,13 +334,43 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
match variance_info {
|
||||
ty::VarianceDiagInfo::None => {}
|
||||
ty::VarianceDiagInfo::Mut { kind, ty } => {
|
||||
let kind_name = match kind {
|
||||
ty::VarianceDiagMutKind::Ref => "reference",
|
||||
ty::VarianceDiagMutKind::RawPtr => "pointer",
|
||||
ty::VarianceDiagInfo::Invariant { ty, param_index } => {
|
||||
let (desc, note) = match ty.kind() {
|
||||
ty::RawPtr(ty_mut) => {
|
||||
assert_eq!(ty_mut.mutbl, rustc_hir::Mutability::Mut);
|
||||
(
|
||||
format!("a mutable pointer to {}", ty_mut.ty),
|
||||
"mutable pointers are invariant over their type parameter".to_string(),
|
||||
)
|
||||
}
|
||||
ty::Ref(_, inner_ty, mutbl) => {
|
||||
assert_eq!(*mutbl, rustc_hir::Mutability::Mut);
|
||||
(
|
||||
format!("a mutable reference to {}", inner_ty),
|
||||
"mutable references are invariant over their type parameter"
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
ty::Adt(adt, substs) => {
|
||||
let generic_arg = substs[param_index as usize];
|
||||
let identity_substs =
|
||||
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did);
|
||||
let base_ty = self.infcx.tcx.mk_adt(adt, identity_substs);
|
||||
let base_generic_arg = identity_substs[param_index as usize];
|
||||
let adt_desc = adt.descr();
|
||||
|
||||
let desc = format!(
|
||||
"the type {ty}, which makes the generic argument {generic_arg} invariant"
|
||||
);
|
||||
let note = format!(
|
||||
"the {adt_desc} {base_ty} is invariant over the parameter {base_generic_arg}"
|
||||
);
|
||||
(desc, note)
|
||||
}
|
||||
_ => panic!("Unexpected type {:?}", ty),
|
||||
};
|
||||
diag.note(&format!("requirement occurs because of a mutable {kind_name} to {ty}",));
|
||||
diag.note(&format!("mutable {kind_name}s are invariant over their type parameter"));
|
||||
diag.note(&format!("requirement occurs because of {desc}",));
|
||||
diag.note(¬e);
|
||||
diag.help("see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance");
|
||||
}
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
|
||||
}
|
||||
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => {
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit(_) => {
|
||||
// In this case, the user left off the lifetime; so
|
||||
// they wrote something like:
|
||||
//
|
||||
@ -769,20 +769,24 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
let opaque_ty = hir.item(id);
|
||||
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
bounds:
|
||||
[hir::GenericBound::LangItemTrait(
|
||||
hir::LangItem::Future,
|
||||
_,
|
||||
_,
|
||||
hir::GenericArgs {
|
||||
bindings:
|
||||
[hir::TypeBinding {
|
||||
ident: Ident { name: sym::Output, .. },
|
||||
kind: hir::TypeBindingKind::Equality { ty },
|
||||
..
|
||||
}],
|
||||
..
|
||||
},
|
||||
)],
|
||||
[
|
||||
hir::GenericBound::LangItemTrait(
|
||||
hir::LangItem::Future,
|
||||
_,
|
||||
_,
|
||||
hir::GenericArgs {
|
||||
bindings:
|
||||
[
|
||||
hir::TypeBinding {
|
||||
ident: Ident { name: sym::Output, .. },
|
||||
kind: hir::TypeBindingKind::Equality { ty },
|
||||
..
|
||||
},
|
||||
],
|
||||
..
|
||||
},
|
||||
),
|
||||
],
|
||||
..
|
||||
}) = opaque_ty.kind
|
||||
{
|
||||
|
@ -199,6 +199,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
options: _,
|
||||
line_spans: _,
|
||||
destination: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
for op in operands {
|
||||
match *op {
|
||||
|
@ -3,9 +3,6 @@
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![cfg_attr(bootstrap, feature(format_args_capture))]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(let_else)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
@ -792,6 +789,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
options: _,
|
||||
line_spans: _,
|
||||
destination: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
for op in operands {
|
||||
match *op {
|
||||
@ -1396,10 +1394,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
|
||||
Rvalue::NullaryOp(_op, _ty) => {
|
||||
// nullary ops take no dynamic input; no borrowck effect.
|
||||
//
|
||||
// FIXME: is above actually true? Do we want to track
|
||||
// the fact that uninitialized data can be created via
|
||||
// `NullOp::Box`?
|
||||
}
|
||||
|
||||
Rvalue::Aggregate(ref aggregate_kind, ref operands) => {
|
||||
|
@ -53,7 +53,7 @@ rustc_index::newtype_index! {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MemberConstraintSet<'tcx, ty::RegionVid> {
|
||||
impl Default for MemberConstraintSet<'_, ty::RegionVid> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
first_constraints: Default::default(),
|
||||
@ -97,7 +97,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R1> MemberConstraintSet<'tcx, R1>
|
||||
impl<'tcx, R1> MemberConstraintSet<'tcx, R1>
|
||||
where
|
||||
R1: Copy + Hash + Eq,
|
||||
{
|
||||
@ -140,7 +140,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> MemberConstraintSet<'tcx, R>
|
||||
impl<R> MemberConstraintSet<'_, R>
|
||||
where
|
||||
R: Copy + Hash + Eq,
|
||||
{
|
||||
|
@ -141,7 +141,7 @@ pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool {
|
||||
/// then returns the index of the field being projected. Note that this closure will always
|
||||
/// be `self` in the current MIR, because that is the only time we directly access the fields
|
||||
/// of a closure type.
|
||||
pub(crate) fn is_upvar_field_projection(
|
||||
pub(crate) fn is_upvar_field_projection<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
upvars: &[Upvar<'tcx>],
|
||||
place_ref: PlaceRef<'tcx>,
|
||||
|
@ -173,7 +173,7 @@ fn check_opaque_type_parameter_valid(
|
||||
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
||||
//
|
||||
// which would error here on all of the `'static` args.
|
||||
OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true,
|
||||
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
|
||||
// Check these
|
||||
OpaqueTyOrigin::TyAlias => {}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix};
|
||||
use rustc_index::bit_set::SparseBitMatrix;
|
||||
use rustc_index::interval::IntervalSet;
|
||||
use rustc_index::interval::SparseIntervalMatrix;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::mir::{BasicBlock, Body, Location};
|
||||
@ -110,11 +112,11 @@ crate enum RegionElement {
|
||||
PlaceholderRegion(ty::PlaceholderRegion),
|
||||
}
|
||||
|
||||
/// When we initially compute liveness, we use a bit matrix storing
|
||||
/// points for each region-vid.
|
||||
/// When we initially compute liveness, we use an interval matrix storing
|
||||
/// liveness ranges for each region-vid.
|
||||
crate struct LivenessValues<N: Idx> {
|
||||
elements: Rc<RegionValueElements>,
|
||||
points: SparseBitMatrix<N, PointIndex>,
|
||||
points: SparseIntervalMatrix<N, PointIndex>,
|
||||
}
|
||||
|
||||
impl<N: Idx> LivenessValues<N> {
|
||||
@ -122,7 +124,7 @@ impl<N: Idx> LivenessValues<N> {
|
||||
/// Each of the regions in num_region_variables will be initialized with an
|
||||
/// empty set of points and no causal information.
|
||||
crate fn new(elements: Rc<RegionValueElements>) -> Self {
|
||||
Self { points: SparseBitMatrix::new(elements.num_points), elements }
|
||||
Self { points: SparseIntervalMatrix::new(elements.num_points), elements }
|
||||
}
|
||||
|
||||
/// Iterate through each region that has a value in this set.
|
||||
@ -140,7 +142,7 @@ impl<N: Idx> LivenessValues<N> {
|
||||
|
||||
/// Adds all the elements in the given bit array into the given
|
||||
/// region. Returns whether any of them are newly added.
|
||||
crate fn add_elements(&mut self, row: N, locations: &HybridBitSet<PointIndex>) -> bool {
|
||||
crate fn add_elements(&mut self, row: N, locations: &IntervalSet<PointIndex>) -> bool {
|
||||
debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations);
|
||||
self.points.union_row(row, locations)
|
||||
}
|
||||
@ -153,7 +155,7 @@ impl<N: Idx> LivenessValues<N> {
|
||||
/// Returns `true` if the region `r` contains the given element.
|
||||
crate fn contains(&self, row: N, location: Location) -> bool {
|
||||
let index = self.elements.point_from_location(location);
|
||||
self.points.contains(row, index)
|
||||
self.points.row(row).map_or(false, |r| r.contains(index))
|
||||
}
|
||||
|
||||
/// Returns an iterator of all the elements contained by the region `r`
|
||||
@ -221,7 +223,7 @@ impl PlaceholderIndices {
|
||||
crate struct RegionValues<N: Idx> {
|
||||
elements: Rc<RegionValueElements>,
|
||||
placeholder_indices: Rc<PlaceholderIndices>,
|
||||
points: SparseBitMatrix<N, PointIndex>,
|
||||
points: SparseIntervalMatrix<N, PointIndex>,
|
||||
free_regions: SparseBitMatrix<N, RegionVid>,
|
||||
|
||||
/// Placeholders represent bound regions -- so something like `'a`
|
||||
@ -241,7 +243,7 @@ impl<N: Idx> RegionValues<N> {
|
||||
let num_placeholders = placeholder_indices.len();
|
||||
Self {
|
||||
elements: elements.clone(),
|
||||
points: SparseBitMatrix::new(elements.num_points),
|
||||
points: SparseIntervalMatrix::new(elements.num_points),
|
||||
placeholder_indices: placeholder_indices.clone(),
|
||||
free_regions: SparseBitMatrix::new(num_universal_regions),
|
||||
placeholders: SparseBitMatrix::new(num_placeholders),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||
use rustc_middle::mir::{Body, Location, PlaceElem, Promoted};
|
||||
use rustc_middle::mir::{Body, Location, Promoted};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
|
||||
@ -62,22 +62,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
|
||||
debug!(?ty);
|
||||
}
|
||||
|
||||
fn process_projection_elem(
|
||||
&mut self,
|
||||
elem: PlaceElem<'tcx>,
|
||||
_: Location,
|
||||
) -> Option<PlaceElem<'tcx>> {
|
||||
if let PlaceElem::Field(field, ty) = elem {
|
||||
let new_ty = self.renumber_regions(ty);
|
||||
|
||||
if new_ty != ty {
|
||||
return Some(PlaceElem::Field(field, new_ty));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
||||
*substs = self.renumber_regions(*substs);
|
||||
|
@ -6,6 +6,7 @@ use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
@ -95,11 +96,23 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
self.add_outlives(r1_vid, r2_vid);
|
||||
}
|
||||
|
||||
GenericArgKind::Type(t1) => {
|
||||
GenericArgKind::Type(mut t1) => {
|
||||
// we don't actually use this for anything, but
|
||||
// the `TypeOutlives` code needs an origin.
|
||||
let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
|
||||
|
||||
// Placeholder regions need to be converted now because it may
|
||||
// create new region variables, which can't be done later when
|
||||
// verifying these bounds.
|
||||
if t1.has_placeholders() {
|
||||
t1 = tcx.fold_regions(&t1, &mut false, |r, _| match *r {
|
||||
ty::RegionKind::RePlaceholder(placeholder) => {
|
||||
self.constraints.placeholder_region(self.infcx, placeholder)
|
||||
}
|
||||
_ => r,
|
||||
});
|
||||
}
|
||||
|
||||
TypeOutlives::new(
|
||||
&mut *self,
|
||||
tcx,
|
||||
|
@ -58,7 +58,7 @@ crate struct CreateResult<'tcx> {
|
||||
crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
|
||||
}
|
||||
|
||||
crate fn create(
|
||||
crate fn create<'tcx>(
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||
@ -81,7 +81,7 @@ crate fn create(
|
||||
.create()
|
||||
}
|
||||
|
||||
impl UniversalRegionRelations<'tcx> {
|
||||
impl UniversalRegionRelations<'_> {
|
||||
/// Records in the `outlives_relation` (and
|
||||
/// `inverse_outlives_relation`) that `fr_a: fr_b`. Invoked by the
|
||||
/// builder below.
|
||||
@ -110,7 +110,7 @@ impl UniversalRegionRelations<'tcx> {
|
||||
/// outlives `fr` and (b) is not local.
|
||||
///
|
||||
/// (*) If there are multiple competing choices, we return all of them.
|
||||
crate fn non_local_upper_bounds(&'a self, fr: &'a RegionVid) -> Vec<&'a RegionVid> {
|
||||
crate fn non_local_upper_bounds<'a>(&'a self, fr: &'a RegionVid) -> Vec<&'a RegionVid> {
|
||||
debug!("non_local_upper_bound(fr={:?})", fr);
|
||||
let res = self.non_local_bounds(&self.inverse_outlives, fr);
|
||||
assert!(!res.is_empty(), "can't find an upper bound!?");
|
||||
@ -232,7 +232,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> {
|
||||
region_bound_pairs: RegionBoundPairs<'tcx>,
|
||||
}
|
||||
|
||||
impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
||||
impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
crate fn create(mut self) -> CreateResult<'tcx> {
|
||||
let unnormalized_input_output_tys = self
|
||||
.universal_regions
|
||||
|
@ -117,9 +117,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
assert!(body.yield_ty().is_some() == universal_regions.yield_ty.is_some());
|
||||
if let Some(mir_yield_ty) = body.yield_ty() {
|
||||
let ur_yield_ty = universal_regions.yield_ty.unwrap();
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}",
|
||||
body.yield_ty(),
|
||||
universal_regions.yield_ty
|
||||
);
|
||||
|
||||
// We will not have a universal_regions.yield_ty if we yield (by accident)
|
||||
// outside of a generator and return an `impl Trait`, so emit a delay_span_bug
|
||||
// because we don't want to panic in an assert here if we've already got errors.
|
||||
if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() {
|
||||
self.tcx().sess.delay_span_bug(
|
||||
body.span,
|
||||
&format!(
|
||||
"Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})",
|
||||
body.yield_ty(),
|
||||
universal_regions.yield_ty,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if let (Some(mir_yield_ty), Some(ur_yield_ty)) =
|
||||
(body.yield_ty(), universal_regions.yield_ty)
|
||||
{
|
||||
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ impl LocalUseMapBuild<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<'tcx> for LocalUseMapBuild<'_> {
|
||||
impl Visitor<'_> for LocalUseMapBuild<'_> {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
||||
if self.locals_with_use_data[local] {
|
||||
match def_use::categorize(context) {
|
||||
|
@ -74,7 +74,7 @@ pub(super) fn generate<'mir, 'tcx>(
|
||||
// to compute whether a variable `X` is live if that variable contains
|
||||
// some region `R` in its type where `R` is not known to outlive a free
|
||||
// region (i.e., where `R` may be valid for just a subset of the fn body).
|
||||
fn compute_live_locals(
|
||||
fn compute_live_locals<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
free_regions: &FxHashSet<RegionVid>,
|
||||
body: &Body<'tcx>,
|
||||
@ -104,7 +104,7 @@ fn compute_live_locals(
|
||||
/// regions. For these regions, we do not need to compute
|
||||
/// liveness, since the outlives constraints will ensure that they
|
||||
/// are live over the whole fn body anyhow.
|
||||
fn regions_that_outlive_free_regions(
|
||||
fn regions_that_outlive_free_regions<'tcx>(
|
||||
num_region_vars: usize,
|
||||
universal_regions: &UniversalRegions<'tcx>,
|
||||
constraint_set: &OutlivesConstraintSet<'tcx>,
|
||||
|
@ -53,7 +53,7 @@ impl UseFactsExtractor<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<'tcx> for UseFactsExtractor<'_> {
|
||||
impl Visitor<'_> for UseFactsExtractor<'_> {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
||||
match def_use::categorize(context) {
|
||||
Some(DefUse::Def) => self.insert_def(local, location),
|
||||
@ -63,7 +63,7 @@ impl Visitor<'tcx> for UseFactsExtractor<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
|
||||
fn visit_place(&mut self, place: &Place<'_>, context: PlaceContext, location: Location) {
|
||||
self.super_place(place, context, location);
|
||||
match context {
|
||||
PlaceContext::NonMutatingUse(_) => {
|
||||
@ -82,7 +82,7 @@ impl Visitor<'tcx> for UseFactsExtractor<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn populate_access_facts(
|
||||
pub(super) fn populate_access_facts<'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
location_table: &LocationTable,
|
||||
@ -123,7 +123,7 @@ pub(super) fn populate_access_facts(
|
||||
|
||||
// For every potentially drop()-touched region `region` in `local`'s type
|
||||
// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
|
||||
pub(super) fn add_drop_of_var_derefs_origin(
|
||||
pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
local: Local,
|
||||
kind: &GenericArg<'tcx>,
|
||||
|
@ -1,5 +1,6 @@
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_index::bit_set::HybridBitSet;
|
||||
use rustc_index::interval::IntervalSet;
|
||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
|
||||
use rustc_middle::ty::{Ty, TypeFoldable};
|
||||
@ -34,7 +35,7 @@ use crate::{
|
||||
/// DROP-LIVE set are to the liveness sets for regions found in the
|
||||
/// `dropck_outlives` result of the variable's type (in particular,
|
||||
/// this respects `#[may_dangle]` annotations).
|
||||
pub(super) fn trace(
|
||||
pub(super) fn trace<'mir, 'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
elements: &Rc<RegionValueElements>,
|
||||
@ -105,12 +106,12 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||
|
||||
/// Points where the current variable is "use live" -- meaning
|
||||
/// that there is a future "full use" that may use its value.
|
||||
use_live_at: HybridBitSet<PointIndex>,
|
||||
use_live_at: IntervalSet<PointIndex>,
|
||||
|
||||
/// Points where the current variable is "drop live" -- meaning
|
||||
/// that there is no future "full use" that may use its value, but
|
||||
/// there is a future drop.
|
||||
drop_live_at: HybridBitSet<PointIndex>,
|
||||
drop_live_at: IntervalSet<PointIndex>,
|
||||
|
||||
/// Locations where drops may occur.
|
||||
drop_locations: Vec<Location>,
|
||||
@ -119,14 +120,14 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||
stack: Vec<PointIndex>,
|
||||
}
|
||||
|
||||
impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||
impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self {
|
||||
let num_points = cx.elements.num_points();
|
||||
LivenessResults {
|
||||
cx,
|
||||
defs: HybridBitSet::new_empty(num_points),
|
||||
use_live_at: HybridBitSet::new_empty(num_points),
|
||||
drop_live_at: HybridBitSet::new_empty(num_points),
|
||||
use_live_at: IntervalSet::new(num_points),
|
||||
drop_live_at: IntervalSet::new(num_points),
|
||||
drop_locations: vec![],
|
||||
stack: vec![],
|
||||
}
|
||||
@ -165,7 +166,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||
drop_used: Vec<(Local, Location)>,
|
||||
live_locals: FxHashSet<Local>,
|
||||
) {
|
||||
let locations = HybridBitSet::new_empty(self.cx.elements.num_points());
|
||||
let locations = IntervalSet::new(self.cx.elements.num_points());
|
||||
|
||||
for (local, location) in drop_used {
|
||||
if !live_locals.contains(&local) {
|
||||
@ -418,7 +419,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl LivenessContext<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
|
||||
/// Returns `true` if the local variable (or some part of it) is initialized at the current
|
||||
/// cursor position. Callers should call one of the `seek` methods immediately before to point
|
||||
/// the cursor to the desired location.
|
||||
@ -456,7 +457,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
||||
fn add_use_live_facts_for(
|
||||
&mut self,
|
||||
value: impl TypeFoldable<'tcx>,
|
||||
live_at: &HybridBitSet<PointIndex>,
|
||||
live_at: &IntervalSet<PointIndex>,
|
||||
) {
|
||||
debug!("add_use_live_facts_for(value={:?})", value);
|
||||
|
||||
@ -473,7 +474,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
||||
dropped_local: Local,
|
||||
dropped_ty: Ty<'tcx>,
|
||||
drop_locations: &[Location],
|
||||
live_at: &HybridBitSet<PointIndex>,
|
||||
live_at: &IntervalSet<PointIndex>,
|
||||
) {
|
||||
debug!(
|
||||
"add_drop_live_constraint(\
|
||||
@ -521,7 +522,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
||||
elements: &RegionValueElements,
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
value: impl TypeFoldable<'tcx>,
|
||||
live_at: &HybridBitSet<PointIndex>,
|
||||
live_at: &IntervalSet<PointIndex>,
|
||||
) {
|
||||
debug!("make_all_regions_live(value={:?})", value);
|
||||
debug!(
|
||||
|
@ -31,7 +31,7 @@ use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::{
|
||||
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
|
||||
ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
|
||||
ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
||||
};
|
||||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -945,7 +945,7 @@ crate struct MirTypeckRegionConstraints<'tcx> {
|
||||
crate type_tests: Vec<TypeTest<'tcx>>,
|
||||
}
|
||||
|
||||
impl MirTypeckRegionConstraints<'tcx> {
|
||||
impl<'tcx> MirTypeckRegionConstraints<'tcx> {
|
||||
fn placeholder_region(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
@ -1828,10 +1828,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
self.assert_iscleanup(body, block_data, unwind, true);
|
||||
}
|
||||
}
|
||||
TerminatorKind::InlineAsm { destination, .. } => {
|
||||
TerminatorKind::InlineAsm { destination, cleanup, .. } => {
|
||||
if let Some(target) = destination {
|
||||
self.assert_iscleanup(body, block_data, target, is_cleanup);
|
||||
}
|
||||
if let Some(cleanup) = cleanup {
|
||||
if is_cleanup {
|
||||
span_mirbug!(self, block_data, "cleanup on cleanup block")
|
||||
}
|
||||
self.assert_iscleanup(body, block_data, cleanup, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1910,7 +1916,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
match *ak {
|
||||
AggregateKind::Adt(def, variant_index, substs, _, active_field_index) => {
|
||||
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
|
||||
let def = tcx.adt_def(adt_did);
|
||||
let variant = &def.variants[variant_index];
|
||||
let adj_field_index = active_field_index.unwrap_or(field_index);
|
||||
if let Some(field) = variant.fields.get(adj_field_index) {
|
||||
@ -2615,8 +2622,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
|
||||
let (def_id, instantiated_predicates) = match aggregate_kind {
|
||||
AggregateKind::Adt(def, _, substs, _, _) => {
|
||||
(def.did, tcx.predicates_of(def.did).instantiate(tcx, substs))
|
||||
AggregateKind::Adt(adt_did, _, substs, _, _) => {
|
||||
(*adt_did, tcx.predicates_of(*adt_did).instantiate(tcx, substs))
|
||||
}
|
||||
|
||||
// For closures, we have some **extra requirements** we
|
||||
|
@ -51,7 +51,7 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
||||
universe_info: UniverseInfo<'tcx>,
|
||||
}
|
||||
|
||||
impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
||||
impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
||||
fn new(
|
||||
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
||||
locations: Locations,
|
||||
@ -62,7 +62,7 @@ impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
|
||||
impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.type_checker.param_env
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
rustc_lexer = { path = "../rustc_lexer" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
rustc_parse = { path = "../rustc_parse" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
|
@ -8,13 +8,14 @@ use rustc_expand::base::{self, *};
|
||||
use rustc_parse::parser::Parser;
|
||||
use rustc_parse_format as parse;
|
||||
use rustc_session::lint;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{InnerSpan, Span};
|
||||
use rustc_target::asm::InlineAsmArch;
|
||||
use smallvec::smallvec;
|
||||
|
||||
struct AsmArgs {
|
||||
pub struct AsmArgs {
|
||||
templates: Vec<P<ast::Expr>>,
|
||||
operands: Vec<(ast::InlineAsmOperand, Span)>,
|
||||
named_args: FxHashMap<Symbol, usize>,
|
||||
@ -31,30 +32,30 @@ fn parse_args<'a>(
|
||||
is_global_asm: bool,
|
||||
) -> Result<AsmArgs, DiagnosticBuilder<'a>> {
|
||||
let mut p = ecx.new_parser_from_tts(tts);
|
||||
let sess = &ecx.sess.parse_sess;
|
||||
parse_asm_args(&mut p, sess, sp, is_global_asm)
|
||||
}
|
||||
|
||||
// Primarily public for rustfmt consumption.
|
||||
// Internal consumers should continue to leverage `expand_asm`/`expand__global_asm`
|
||||
pub fn parse_asm_args<'a>(
|
||||
p: &mut Parser<'a>,
|
||||
sess: &'a ParseSess,
|
||||
sp: Span,
|
||||
is_global_asm: bool,
|
||||
) -> Result<AsmArgs, DiagnosticBuilder<'a>> {
|
||||
let diag = &sess.span_diagnostic;
|
||||
|
||||
if p.token == token::Eof {
|
||||
return Err(ecx.struct_span_err(sp, "requires at least a template string argument"));
|
||||
return Err(diag.struct_span_err(sp, "requires at least a template string argument"));
|
||||
}
|
||||
|
||||
// Detect use of the legacy llvm_asm! syntax (which used to be called asm!)
|
||||
if !is_global_asm && p.look_ahead(1, |t| *t == token::Colon || *t == token::ModSep) {
|
||||
let mut err =
|
||||
ecx.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported");
|
||||
diag.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported");
|
||||
err.note("consider migrating to the new asm! syntax specified in RFC 2873");
|
||||
err.note("alternatively, switch to llvm_asm! to keep your code working as it is");
|
||||
|
||||
// Find the span of the "asm!" so that we can offer an automatic suggestion
|
||||
let asm_span = sp.from_inner(InnerSpan::new(0, 4));
|
||||
if let Ok(s) = ecx.source_map().span_to_snippet(asm_span) {
|
||||
if s == "asm!" {
|
||||
err.span_suggestion(
|
||||
asm_span,
|
||||
"replace with",
|
||||
"llvm_asm!".into(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
@ -74,7 +75,7 @@ fn parse_args<'a>(
|
||||
if !p.eat(&token::Comma) {
|
||||
if allow_templates {
|
||||
// After a template string, we always expect *only* a comma...
|
||||
let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`");
|
||||
let mut err = diag.struct_span_err(p.token.span, "expected token: `,`");
|
||||
err.span_label(p.token.span, "expected `,`");
|
||||
p.maybe_annotate_with_ascription(&mut err, false);
|
||||
return Err(err);
|
||||
@ -89,14 +90,14 @@ fn parse_args<'a>(
|
||||
|
||||
// Parse clobber_abi
|
||||
if p.eat_keyword(sym::clobber_abi) {
|
||||
parse_clobber_abi(&mut p, &mut args)?;
|
||||
parse_clobber_abi(p, &mut args)?;
|
||||
allow_templates = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse options
|
||||
if p.eat_keyword(sym::options) {
|
||||
parse_options(&mut p, &mut args, is_global_asm)?;
|
||||
parse_options(p, &mut args, is_global_asm)?;
|
||||
allow_templates = false;
|
||||
continue;
|
||||
}
|
||||
@ -116,25 +117,25 @@ fn parse_args<'a>(
|
||||
|
||||
let mut explicit_reg = false;
|
||||
let op = if !is_global_asm && p.eat_keyword(kw::In) {
|
||||
let reg = parse_reg(&mut p, &mut explicit_reg)?;
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
|
||||
let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands");
|
||||
return Err(err);
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
ast::InlineAsmOperand::In { reg, expr }
|
||||
} else if !is_global_asm && p.eat_keyword(sym::out) {
|
||||
let reg = parse_reg(&mut p, &mut explicit_reg)?;
|
||||
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) {
|
||||
let reg = parse_reg(&mut p, &mut explicit_reg)?;
|
||||
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) {
|
||||
let reg = parse_reg(&mut p, &mut explicit_reg)?;
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
|
||||
let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands");
|
||||
return Err(err);
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
@ -146,9 +147,9 @@ fn parse_args<'a>(
|
||||
ast::InlineAsmOperand::InOut { reg, expr, late: false }
|
||||
}
|
||||
} else if !is_global_asm && p.eat_keyword(sym::inlateout) {
|
||||
let reg = parse_reg(&mut p, &mut explicit_reg)?;
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
|
||||
let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands");
|
||||
return Err(err);
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
@ -167,7 +168,7 @@ fn parse_args<'a>(
|
||||
match expr.kind {
|
||||
ast::ExprKind::Path(..) => {}
|
||||
_ => {
|
||||
let err = ecx
|
||||
let err = diag
|
||||
.struct_span_err(expr.span, "argument to `sym` must be a path expression");
|
||||
return Err(err);
|
||||
}
|
||||
@ -186,7 +187,7 @@ fn parse_args<'a>(
|
||||
} else {
|
||||
"expected operand, clobber_abi, options, or additional template string"
|
||||
};
|
||||
let mut err = ecx.struct_span_err(template.span, errstr);
|
||||
let mut err = diag.struct_span_err(template.span, errstr);
|
||||
err.span_label(template.span, errstr);
|
||||
return Err(err);
|
||||
}
|
||||
@ -206,31 +207,31 @@ fn parse_args<'a>(
|
||||
// clobber_abi/options. We do this at the end once we have the full span
|
||||
// of the argument available.
|
||||
if !args.options_spans.is_empty() {
|
||||
ecx.struct_span_err(span, "arguments are not allowed after options")
|
||||
diag.struct_span_err(span, "arguments are not allowed after options")
|
||||
.span_labels(args.options_spans.clone(), "previous options")
|
||||
.span_label(span, "argument")
|
||||
.emit();
|
||||
} else if let Some((_, abi_span)) = args.clobber_abis.last() {
|
||||
ecx.struct_span_err(span, "arguments are not allowed after clobber_abi")
|
||||
diag.struct_span_err(span, "arguments are not allowed after clobber_abi")
|
||||
.span_label(*abi_span, "clobber_abi")
|
||||
.span_label(span, "argument")
|
||||
.emit();
|
||||
}
|
||||
if explicit_reg {
|
||||
if name.is_some() {
|
||||
ecx.struct_span_err(span, "explicit register arguments cannot have names").emit();
|
||||
diag.struct_span_err(span, "explicit register arguments cannot have names").emit();
|
||||
}
|
||||
args.reg_args.insert(slot);
|
||||
} else if let Some(name) = name {
|
||||
if let Some(&prev) = args.named_args.get(&name) {
|
||||
ecx.struct_span_err(span, &format!("duplicate argument named `{}`", name))
|
||||
diag.struct_span_err(span, &format!("duplicate argument named `{}`", name))
|
||||
.span_label(args.operands[prev].1, "previously here")
|
||||
.span_label(span, "duplicate argument")
|
||||
.emit();
|
||||
continue;
|
||||
}
|
||||
if !args.reg_args.is_empty() {
|
||||
let mut err = ecx.struct_span_err(
|
||||
let mut err = diag.struct_span_err(
|
||||
span,
|
||||
"named arguments cannot follow explicit register arguments",
|
||||
);
|
||||
@ -243,7 +244,7 @@ fn parse_args<'a>(
|
||||
args.named_args.insert(name, slot);
|
||||
} else {
|
||||
if !args.named_args.is_empty() || !args.reg_args.is_empty() {
|
||||
let mut err = ecx.struct_span_err(
|
||||
let mut err = diag.struct_span_err(
|
||||
span,
|
||||
"positional arguments cannot follow named arguments \
|
||||
or explicit register arguments",
|
||||
@ -264,21 +265,21 @@ fn parse_args<'a>(
|
||||
&& args.options.contains(ast::InlineAsmOptions::READONLY)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
ecx.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive")
|
||||
diag.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive")
|
||||
.emit();
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
ecx.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive")
|
||||
diag.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive")
|
||||
.emit();
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
ecx.struct_span_err(
|
||||
diag.struct_span_err(
|
||||
spans,
|
||||
"the `pure` option must be combined with either `nomem` or `readonly`",
|
||||
)
|
||||
@ -309,14 +310,14 @@ fn parse_args<'a>(
|
||||
}
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
|
||||
ecx.struct_span_err(
|
||||
diag.struct_span_err(
|
||||
args.options_spans.clone(),
|
||||
"asm with the `pure` option must have at least one output",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
|
||||
let err = ecx
|
||||
let err = diag
|
||||
.struct_span_err(outputs_sp, "asm outputs are not allowed with the `noreturn` option");
|
||||
|
||||
// Bail out now since this is likely to confuse MIR
|
||||
@ -325,7 +326,7 @@ fn parse_args<'a>(
|
||||
|
||||
if args.clobber_abis.len() > 0 {
|
||||
if is_global_asm {
|
||||
let err = ecx.struct_span_err(
|
||||
let err = diag.struct_span_err(
|
||||
args.clobber_abis.iter().map(|(_, span)| *span).collect::<Vec<Span>>(),
|
||||
"`clobber_abi` cannot be used with `global_asm!`",
|
||||
);
|
||||
@ -334,7 +335,7 @@ fn parse_args<'a>(
|
||||
return Err(err);
|
||||
}
|
||||
if !regclass_outputs.is_empty() {
|
||||
ecx.struct_span_err(
|
||||
diag.struct_span_err(
|
||||
regclass_outputs.clone(),
|
||||
"asm with `clobber_abi` must specify explicit registers for outputs",
|
||||
)
|
||||
@ -420,6 +421,8 @@ fn parse_options<'a>(
|
||||
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
|
||||
} else if p.eat_keyword(kw::Raw) {
|
||||
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
|
||||
} else if p.eat_keyword(sym::may_unwind) {
|
||||
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
|
||||
} else {
|
||||
return p.unexpected();
|
||||
}
|
||||
@ -570,7 +573,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
template_snippet.as_ref().map(|s| Symbol::intern(s)),
|
||||
template_sp,
|
||||
));
|
||||
let template_str = &template_str.as_str();
|
||||
let template_str = template_str.as_str();
|
||||
|
||||
if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
|
||||
let find_span = |needle: &str| -> Span {
|
||||
@ -710,7 +713,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
Some(&idx) => Some(idx),
|
||||
None => {
|
||||
let msg = format!("there is no argument named `{}`", name);
|
||||
ecx.struct_span_err(span, &msg[..]).emit();
|
||||
ecx.struct_span_err(span, &msg).emit();
|
||||
None
|
||||
}
|
||||
},
|
||||
@ -806,7 +809,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expand_asm<'cx>(
|
||||
pub(super) fn expand_asm<'cx>(
|
||||
ecx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
@ -833,7 +836,7 @@ pub fn expand_asm<'cx>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_global_asm<'cx>(
|
||||
pub(super) fn expand_global_asm<'cx>(
|
||||
ecx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::panic::use_panic_2021;
|
||||
use crate::edition_panic::use_panic_2021;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::util::check_builtin_macro_attribute;
|
||||
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::mut_visit::MutVisitor;
|
||||
@ -11,7 +11,7 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_expand::config::StripUnconfigured;
|
||||
use rustc_expand::configure;
|
||||
use rustc_feature::Features;
|
||||
use rustc_parse::parser::ForceCollect;
|
||||
use rustc_parse::parser::{ForceCollect, Parser};
|
||||
use rustc_session::utils::FlattenNonterminals;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::sym;
|
||||
@ -25,6 +25,7 @@ crate fn expand(
|
||||
annotatable: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval);
|
||||
warn_on_duplicate_attribute(&ecx, &annotatable, sym::cfg_eval);
|
||||
vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable)]
|
||||
}
|
||||
|
||||
@ -77,6 +78,10 @@ fn flat_map_annotatable(
|
||||
Annotatable::Param(param) => vis.flat_map_param(param).pop().map(Annotatable::Param),
|
||||
Annotatable::FieldDef(sf) => vis.flat_map_field_def(sf).pop().map(Annotatable::FieldDef),
|
||||
Annotatable::Variant(v) => vis.flat_map_variant(v).pop().map(Annotatable::Variant),
|
||||
Annotatable::Crate(mut krate) => {
|
||||
vis.visit_crate(&mut krate);
|
||||
Some(Annotatable::Crate(krate))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +106,7 @@ impl CfgFinder {
|
||||
Annotatable::Param(param) => finder.visit_param(¶m),
|
||||
Annotatable::FieldDef(field) => finder.visit_field_def(&field),
|
||||
Annotatable::Variant(variant) => finder.visit_variant(&variant),
|
||||
Annotatable::Crate(krate) => finder.visit_crate(krate),
|
||||
};
|
||||
finder.has_cfg_or_cfg_attr
|
||||
}
|
||||
@ -138,8 +144,34 @@ impl CfgEval<'_, '_> {
|
||||
// the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization
|
||||
// process is lossless, so this process is invisible to proc-macros.
|
||||
|
||||
// FIXME - get rid of this clone
|
||||
let nt = annotatable.clone().into_nonterminal();
|
||||
let parse_annotatable_with: fn(&mut Parser<'_>) -> _ = match annotatable {
|
||||
Annotatable::Item(_) => {
|
||||
|parser| Annotatable::Item(parser.parse_item(ForceCollect::Yes).unwrap().unwrap())
|
||||
}
|
||||
Annotatable::TraitItem(_) => |parser| {
|
||||
Annotatable::TraitItem(
|
||||
parser.parse_trait_item(ForceCollect::Yes).unwrap().unwrap().unwrap(),
|
||||
)
|
||||
},
|
||||
Annotatable::ImplItem(_) => |parser| {
|
||||
Annotatable::ImplItem(
|
||||
parser.parse_impl_item(ForceCollect::Yes).unwrap().unwrap().unwrap(),
|
||||
)
|
||||
},
|
||||
Annotatable::ForeignItem(_) => |parser| {
|
||||
Annotatable::ForeignItem(
|
||||
parser.parse_foreign_item(ForceCollect::Yes).unwrap().unwrap().unwrap(),
|
||||
)
|
||||
},
|
||||
Annotatable::Stmt(_) => |parser| {
|
||||
Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes).unwrap().unwrap()))
|
||||
},
|
||||
Annotatable::Expr(_) => {
|
||||
|parser| Annotatable::Expr(parser.parse_expr_force_collect().unwrap())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let nt = annotatable.into_nonterminal();
|
||||
|
||||
let mut orig_tokens = rustc_parse::nt_to_tokenstream(
|
||||
&nt,
|
||||
@ -173,25 +205,7 @@ impl CfgEval<'_, '_> {
|
||||
let mut parser =
|
||||
rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None);
|
||||
parser.capture_cfg = true;
|
||||
annotatable = match annotatable {
|
||||
Annotatable::Item(_) => {
|
||||
Annotatable::Item(parser.parse_item(ForceCollect::Yes).unwrap().unwrap())
|
||||
}
|
||||
Annotatable::TraitItem(_) => Annotatable::TraitItem(
|
||||
parser.parse_trait_item(ForceCollect::Yes).unwrap().unwrap().unwrap(),
|
||||
),
|
||||
Annotatable::ImplItem(_) => Annotatable::ImplItem(
|
||||
parser.parse_impl_item(ForceCollect::Yes).unwrap().unwrap().unwrap(),
|
||||
),
|
||||
Annotatable::ForeignItem(_) => Annotatable::ForeignItem(
|
||||
parser.parse_foreign_item(ForceCollect::Yes).unwrap().unwrap().unwrap(),
|
||||
),
|
||||
Annotatable::Stmt(_) => {
|
||||
Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes).unwrap().unwrap()))
|
||||
}
|
||||
Annotatable::Expr(_) => Annotatable::Expr(parser.parse_expr_force_collect().unwrap()),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
annotatable = parse_annotatable_with(&mut parser);
|
||||
|
||||
// Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring
|
||||
// our attribute target will correctly the tokens as well.
|
||||
|
@ -21,7 +21,7 @@ pub fn expand_concat(
|
||||
match e.kind {
|
||||
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||
ast::LitKind::Str(ref s, _) | ast::LitKind::Float(ref s, _) => {
|
||||
accumulator.push_str(&s.as_str());
|
||||
accumulator.push_str(s.as_str());
|
||||
}
|
||||
ast::LitKind::Char(c) => {
|
||||
accumulator.push(c);
|
||||
|
192
compiler/rustc_builtin_macros/src/concat_bytes.rs
Normal file
192
compiler/rustc_builtin_macros/src/concat_bytes.rs
Normal file
@ -0,0 +1,192 @@
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::{ptr::P, tokenstream::TokenStream};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_expand::base::{self, DummyResult};
|
||||
|
||||
/// Emits errors for literal expressions that are invalid inside and outside of an array.
|
||||
fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_nested: bool) {
|
||||
let lit = if let ast::ExprKind::Lit(lit) = &expr.kind {
|
||||
lit
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
match lit.kind {
|
||||
ast::LitKind::Char(_) => {
|
||||
let mut err = cx.struct_span_err(expr.span, "cannot concatenate character literals");
|
||||
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
"try using a byte character",
|
||||
format!("b{}", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
ast::LitKind::Str(_, _) => {
|
||||
let mut err = cx.struct_span_err(expr.span, "cannot concatenate string literals");
|
||||
// suggestion would be invalid if we are nested
|
||||
if !is_nested {
|
||||
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
"try using a byte string",
|
||||
format!("b{}", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
ast::LitKind::Float(_, _) => {
|
||||
cx.span_err(expr.span, "cannot concatenate float literals");
|
||||
}
|
||||
ast::LitKind::Bool(_) => {
|
||||
cx.span_err(expr.span, "cannot concatenate boolean literals");
|
||||
}
|
||||
ast::LitKind::Err(_) => {}
|
||||
ast::LitKind::Int(_, _) if !is_nested => {
|
||||
let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
|
||||
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
"try wrapping the number in an array",
|
||||
format!("[{}]", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
ast::LitKind::Int(
|
||||
val,
|
||||
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||
) => {
|
||||
assert!(val > u8::MAX.into()); // must be an error
|
||||
cx.span_err(expr.span, "numeric literal is out of bounds");
|
||||
}
|
||||
ast::LitKind::Int(_, _) => {
|
||||
cx.span_err(expr.span, "numeric literal is not a `u8`");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_array_element(
|
||||
cx: &mut base::ExtCtxt<'_>,
|
||||
has_errors: &mut bool,
|
||||
missing_literals: &mut Vec<rustc_span::Span>,
|
||||
expr: &P<rustc_ast::Expr>,
|
||||
) -> Option<u8> {
|
||||
match expr.kind {
|
||||
ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
|
||||
if !*has_errors {
|
||||
cx.span_err(expr.span, "cannot concatenate doubly nested array");
|
||||
}
|
||||
*has_errors = true;
|
||||
None
|
||||
}
|
||||
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||
ast::LitKind::Int(
|
||||
val,
|
||||
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||
) if val <= u8::MAX.into() => Some(val as u8),
|
||||
|
||||
ast::LitKind::Byte(val) => Some(val),
|
||||
ast::LitKind::ByteStr(_) => {
|
||||
if !*has_errors {
|
||||
cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
|
||||
.note("byte strings are treated as arrays of bytes")
|
||||
.help("try flattening the array")
|
||||
.emit();
|
||||
}
|
||||
*has_errors = true;
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
if !*has_errors {
|
||||
invalid_type_err(cx, expr, true);
|
||||
}
|
||||
*has_errors = true;
|
||||
None
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
missing_literals.push(expr.span);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_concat_bytes(
|
||||
cx: &mut base::ExtCtxt<'_>,
|
||||
sp: rustc_span::Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn base::MacResult + 'static> {
|
||||
let es = match base::get_exprs_from_tts(cx, sp, tts) {
|
||||
Some(e) => e,
|
||||
None => return DummyResult::any(sp),
|
||||
};
|
||||
let mut accumulator = Vec::new();
|
||||
let mut missing_literals = vec![];
|
||||
let mut has_errors = false;
|
||||
for e in es {
|
||||
match e.kind {
|
||||
ast::ExprKind::Array(ref exprs) => {
|
||||
for expr in exprs {
|
||||
if let Some(elem) =
|
||||
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||
{
|
||||
accumulator.push(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Repeat(ref expr, ref count) => {
|
||||
if let ast::ExprKind::Lit(ast::Lit {
|
||||
kind: ast::LitKind::Int(count_val, _), ..
|
||||
}) = count.value.kind
|
||||
{
|
||||
if let Some(elem) =
|
||||
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||
{
|
||||
for _ in 0..count_val {
|
||||
accumulator.push(elem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cx.span_err(count.value.span, "repeat count is not a positive number");
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||
ast::LitKind::Byte(val) => {
|
||||
accumulator.push(val);
|
||||
}
|
||||
ast::LitKind::ByteStr(ref bytes) => {
|
||||
accumulator.extend_from_slice(&bytes);
|
||||
}
|
||||
_ => {
|
||||
if !has_errors {
|
||||
invalid_type_err(cx, &e, false);
|
||||
}
|
||||
has_errors = true;
|
||||
}
|
||||
},
|
||||
ast::ExprKind::Err => {
|
||||
has_errors = true;
|
||||
}
|
||||
_ => {
|
||||
missing_literals.push(e.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
if !missing_literals.is_empty() {
|
||||
let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
|
||||
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
|
||||
err.emit();
|
||||
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||
} else if has_errors {
|
||||
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||
}
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator))))
|
||||
}
|
@ -29,7 +29,7 @@ pub fn expand_concat_idents<'cx>(
|
||||
} else {
|
||||
if let TokenTree::Token(token) = e {
|
||||
if let Some((ident, _)) = token.ident() {
|
||||
res_str.push_str(&ident.name.as_str());
|
||||
res_str.push_str(ident.name.as_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
|
||||
|
||||
fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
|
||||
let help_msg = match lit.token.kind {
|
||||
token::Str if rustc_lexer::is_ident(&lit.token.symbol.as_str()) => {
|
||||
token::Str if rustc_lexer::is_ident(lit.token.symbol.as_str()) => {
|
||||
format!("try using `#[derive({})]`", lit.token.symbol)
|
||||
}
|
||||
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
|
||||
|
@ -567,8 +567,11 @@ impl<'a> TraitDef<'a> {
|
||||
})
|
||||
});
|
||||
|
||||
let Generics { mut params, mut where_clause, span } =
|
||||
let Generics { mut params, mut where_clause, .. } =
|
||||
self.generics.to_generics(cx, self.span, type_ident, generics);
|
||||
where_clause.span = generics.where_clause.span;
|
||||
let ctxt = self.span.ctxt();
|
||||
let span = generics.span.with_ctxt(ctxt);
|
||||
|
||||
// Create the generic parameters
|
||||
params.extend(generics.params.iter().map(|param| match ¶m.kind {
|
||||
@ -589,12 +592,12 @@ impl<'a> TraitDef<'a> {
|
||||
param.bounds.iter().cloned()
|
||||
).collect();
|
||||
|
||||
cx.typaram(self.span, param.ident, vec![], bounds, None)
|
||||
cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, vec![], bounds, None)
|
||||
}
|
||||
GenericParamKind::Const { ty, kw_span, .. } => {
|
||||
let const_nodefault_kind = GenericParamKind::Const {
|
||||
ty: ty.clone(),
|
||||
kw_span: *kw_span,
|
||||
kw_span: kw_span.with_ctxt(ctxt),
|
||||
|
||||
// We can't have default values inside impl block
|
||||
default: None,
|
||||
@ -607,28 +610,27 @@ impl<'a> TraitDef<'a> {
|
||||
|
||||
// and similarly for where clauses
|
||||
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
|
||||
match *clause {
|
||||
ast::WherePredicate::BoundPredicate(ref wb) => {
|
||||
match clause {
|
||||
ast::WherePredicate::BoundPredicate(wb) => {
|
||||
let span = wb.span.with_ctxt(ctxt);
|
||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||
span: self.span,
|
||||
bound_generic_params: wb.bound_generic_params.clone(),
|
||||
bounded_ty: wb.bounded_ty.clone(),
|
||||
bounds: wb.bounds.to_vec(),
|
||||
span,
|
||||
..wb.clone()
|
||||
})
|
||||
}
|
||||
ast::WherePredicate::RegionPredicate(ref rb) => {
|
||||
ast::WherePredicate::RegionPredicate(wr) => {
|
||||
let span = wr.span.with_ctxt(ctxt);
|
||||
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
||||
span: self.span,
|
||||
lifetime: rb.lifetime,
|
||||
bounds: rb.bounds.to_vec(),
|
||||
span,
|
||||
..wr.clone()
|
||||
})
|
||||
}
|
||||
ast::WherePredicate::EqPredicate(ref we) => {
|
||||
ast::WherePredicate::EqPredicate(we) => {
|
||||
let span = we.span.with_ctxt(ctxt);
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
lhs_ty: we.lhs_ty.clone(),
|
||||
rhs_ty: we.rhs_ty.clone(),
|
||||
span,
|
||||
..we.clone()
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -691,13 +693,13 @@ impl<'a> TraitDef<'a> {
|
||||
.iter()
|
||||
.map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
GenericArg::Lifetime(cx.lifetime(self.span, param.ident))
|
||||
GenericArg::Lifetime(cx.lifetime(param.ident.span.with_ctxt(ctxt), param.ident))
|
||||
}
|
||||
GenericParamKind::Type { .. } => {
|
||||
GenericArg::Type(cx.ty_ident(self.span, param.ident))
|
||||
GenericArg::Type(cx.ty_ident(param.ident.span.with_ctxt(ctxt), param.ident))
|
||||
}
|
||||
GenericParamKind::Const { .. } => {
|
||||
GenericArg::Const(cx.const_ident(self.span, param.ident))
|
||||
GenericArg::Const(cx.const_ident(param.ident.span.with_ctxt(ctxt), param.ident))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -764,8 +766,8 @@ impl<'a> TraitDef<'a> {
|
||||
self,
|
||||
struct_def,
|
||||
type_ident,
|
||||
&self_args[..],
|
||||
&nonself_args[..],
|
||||
&self_args,
|
||||
&nonself_args,
|
||||
)
|
||||
} else {
|
||||
method_def.expand_struct_method_body(
|
||||
@ -773,8 +775,8 @@ impl<'a> TraitDef<'a> {
|
||||
self,
|
||||
struct_def,
|
||||
type_ident,
|
||||
&self_args[..],
|
||||
&nonself_args[..],
|
||||
&self_args,
|
||||
&nonself_args,
|
||||
use_temporaries,
|
||||
)
|
||||
};
|
||||
@ -813,8 +815,8 @@ impl<'a> TraitDef<'a> {
|
||||
self,
|
||||
enum_def,
|
||||
type_ident,
|
||||
&self_args[..],
|
||||
&nonself_args[..],
|
||||
&self_args,
|
||||
&nonself_args,
|
||||
)
|
||||
} else {
|
||||
method_def.expand_enum_method_body(
|
||||
@ -823,7 +825,7 @@ impl<'a> TraitDef<'a> {
|
||||
enum_def,
|
||||
type_ident,
|
||||
self_args,
|
||||
&nonself_args[..],
|
||||
&nonself_args,
|
||||
)
|
||||
};
|
||||
|
||||
@ -845,16 +847,17 @@ impl<'a> MethodDef<'a> {
|
||||
nonself_args: &[P<Expr>],
|
||||
fields: &SubstructureFields<'_>,
|
||||
) -> P<Expr> {
|
||||
let span = trait_.span;
|
||||
let substructure = Substructure {
|
||||
type_ident,
|
||||
method_ident: Ident::new(self.name, trait_.span),
|
||||
method_ident: Ident::new(self.name, span),
|
||||
self_args,
|
||||
nonself_args,
|
||||
fields,
|
||||
};
|
||||
let mut f = self.combine_substructure.borrow_mut();
|
||||
let f: &mut CombineSubstructureFunc<'_> = &mut *f;
|
||||
f(cx, trait_.span, &substructure)
|
||||
f(cx, span, &substructure)
|
||||
}
|
||||
|
||||
fn get_ret_ty(
|
||||
@ -882,9 +885,10 @@ impl<'a> MethodDef<'a> {
|
||||
let mut nonself_args = Vec::new();
|
||||
let mut arg_tys = Vec::new();
|
||||
let mut nonstatic = false;
|
||||
let span = trait_.span;
|
||||
|
||||
let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| {
|
||||
let (self_expr, explicit_self) = ty::get_explicit_self(cx, trait_.span, self_ptr);
|
||||
let (self_expr, explicit_self) = ty::get_explicit_self(cx, span, self_ptr);
|
||||
|
||||
self_args.push(self_expr);
|
||||
nonstatic = true;
|
||||
@ -893,11 +897,11 @@ impl<'a> MethodDef<'a> {
|
||||
});
|
||||
|
||||
for (ty, name) in self.args.iter() {
|
||||
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
|
||||
let ident = Ident::new(*name, trait_.span);
|
||||
let ast_ty = ty.to_ty(cx, span, type_ident, generics);
|
||||
let ident = Ident::new(*name, span);
|
||||
arg_tys.push((ident, ast_ty));
|
||||
|
||||
let arg_expr = cx.expr_ident(trait_.span, ident);
|
||||
let arg_expr = cx.expr_ident(span, ident);
|
||||
|
||||
match *ty {
|
||||
// for static methods, just treat any Self
|
||||
@ -906,7 +910,7 @@ impl<'a> MethodDef<'a> {
|
||||
self_args.push(arg_expr);
|
||||
}
|
||||
Ptr(ref ty, _) if matches!(**ty, Self_) && nonstatic => {
|
||||
self_args.push(cx.expr_deref(trait_.span, arg_expr))
|
||||
self_args.push(cx.expr_deref(span, arg_expr))
|
||||
}
|
||||
_ => {
|
||||
nonself_args.push(arg_expr);
|
||||
@ -927,33 +931,33 @@ impl<'a> MethodDef<'a> {
|
||||
arg_types: Vec<(Ident, P<ast::Ty>)>,
|
||||
body: P<Expr>,
|
||||
) -> P<ast::AssocItem> {
|
||||
let span = trait_.span;
|
||||
// Create the generics that aren't for `Self`.
|
||||
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
|
||||
let fn_generics = self.generics.to_generics(cx, span, type_ident, generics);
|
||||
|
||||
let args = {
|
||||
let self_args = explicit_self.map(|explicit_self| {
|
||||
let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(trait_.span);
|
||||
let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(span);
|
||||
ast::Param::from_self(ast::AttrVec::default(), explicit_self, ident)
|
||||
});
|
||||
let nonself_args =
|
||||
arg_types.into_iter().map(|(name, ty)| cx.param(trait_.span, name, ty));
|
||||
let nonself_args = arg_types.into_iter().map(|(name, ty)| cx.param(span, name, ty));
|
||||
self_args.into_iter().chain(nonself_args).collect()
|
||||
};
|
||||
|
||||
let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
|
||||
|
||||
let method_ident = Ident::new(self.name, trait_.span);
|
||||
let method_ident = Ident::new(self.name, span);
|
||||
let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type));
|
||||
let body_block = cx.block_expr(body);
|
||||
|
||||
let unsafety = if self.is_unsafe { ast::Unsafe::Yes(trait_.span) } else { ast::Unsafe::No };
|
||||
let unsafety = if self.is_unsafe { ast::Unsafe::Yes(span) } else { ast::Unsafe::No };
|
||||
|
||||
let trait_lo_sp = trait_.span.shrink_to_lo();
|
||||
let trait_lo_sp = span.shrink_to_lo();
|
||||
|
||||
let sig = ast::FnSig {
|
||||
header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() },
|
||||
decl: fn_decl,
|
||||
span: trait_.span,
|
||||
span,
|
||||
};
|
||||
let defaultness = ast::Defaultness::Final;
|
||||
|
||||
@ -961,7 +965,7 @@ impl<'a> MethodDef<'a> {
|
||||
P(ast::AssocItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
attrs: self.attributes.clone(),
|
||||
span: trait_.span,
|
||||
span,
|
||||
vis: ast::Visibility {
|
||||
span: trait_lo_sp,
|
||||
kind: ast::VisibilityKind::Inherited,
|
||||
@ -1024,11 +1028,11 @@ impl<'a> MethodDef<'a> {
|
||||
nonself_args: &[P<Expr>],
|
||||
use_temporaries: bool,
|
||||
) -> P<Expr> {
|
||||
let mut raw_fields = Vec::new(); // Vec<[fields of self],
|
||||
// [fields of next Self arg], [etc]>
|
||||
let mut raw_fields = Vec::new(); // Vec<[fields of self], [fields of next Self arg], [etc]>
|
||||
let span = trait_.span;
|
||||
let mut patterns = Vec::new();
|
||||
for i in 0..self_args.len() {
|
||||
let struct_path = cx.path(trait_.span, vec![type_ident]);
|
||||
let struct_path = cx.path(span, vec![type_ident]);
|
||||
let (pat, ident_expr) = trait_.create_struct_pattern(
|
||||
cx,
|
||||
struct_path,
|
||||
@ -1048,7 +1052,7 @@ impl<'a> MethodDef<'a> {
|
||||
let mut other_fields: Vec<vec::IntoIter<_>> = raw_fields.collect();
|
||||
first_field
|
||||
.map(|(span, opt_id, field, attrs)| FieldInfo {
|
||||
span,
|
||||
span: span.with_ctxt(trait_.span.ctxt()),
|
||||
name: opt_id,
|
||||
self_: field,
|
||||
other: other_fields
|
||||
@ -1062,7 +1066,7 @@ impl<'a> MethodDef<'a> {
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
cx.span_bug(trait_.span, "no `self` parameter for method in generic `derive`")
|
||||
cx.span_bug(span, "no `self` parameter for method in generic `derive`")
|
||||
};
|
||||
|
||||
// body of the inner most destructuring match
|
||||
@ -1079,11 +1083,7 @@ impl<'a> MethodDef<'a> {
|
||||
// structs. This is actually right-to-left, but it shouldn't
|
||||
// matter.
|
||||
for (arg_expr, pat) in iter::zip(self_args, patterns) {
|
||||
body = cx.expr_match(
|
||||
trait_.span,
|
||||
arg_expr.clone(),
|
||||
vec![cx.arm(trait_.span, pat.clone(), body)],
|
||||
)
|
||||
body = cx.expr_match(span, arg_expr.clone(), vec![cx.arm(span, pat.clone(), body)])
|
||||
}
|
||||
|
||||
body
|
||||
@ -1193,7 +1193,7 @@ impl<'a> MethodDef<'a> {
|
||||
mut self_args: Vec<P<Expr>>,
|
||||
nonself_args: &[P<Expr>],
|
||||
) -> P<Expr> {
|
||||
let sp = trait_.span;
|
||||
let span = trait_.span;
|
||||
let variants = &enum_def.variants;
|
||||
|
||||
let self_arg_names = iter::once("__self".to_string())
|
||||
@ -1208,7 +1208,7 @@ impl<'a> MethodDef<'a> {
|
||||
|
||||
let self_arg_idents = self_arg_names
|
||||
.iter()
|
||||
.map(|name| Ident::from_str_and_span(name, sp))
|
||||
.map(|name| Ident::from_str_and_span(name, span))
|
||||
.collect::<Vec<Ident>>();
|
||||
|
||||
// The `vi_idents` will be bound, solely in the catch-all, to
|
||||
@ -1217,8 +1217,8 @@ impl<'a> MethodDef<'a> {
|
||||
let vi_idents = self_arg_names
|
||||
.iter()
|
||||
.map(|name| {
|
||||
let vi_suffix = format!("{}_vi", &name[..]);
|
||||
Ident::from_str_and_span(&vi_suffix, trait_.span)
|
||||
let vi_suffix = format!("{}_vi", name);
|
||||
Ident::from_str_and_span(&vi_suffix, span)
|
||||
})
|
||||
.collect::<Vec<Ident>>();
|
||||
|
||||
@ -1226,7 +1226,7 @@ impl<'a> MethodDef<'a> {
|
||||
// delegated expression that handles the catch-all case,
|
||||
// using `__variants_tuple` to drive logic if necessary.
|
||||
let catch_all_substructure =
|
||||
EnumNonMatchingCollapsed(self_arg_idents, &variants[..], &vi_idents[..]);
|
||||
EnumNonMatchingCollapsed(self_arg_idents, &variants, &vi_idents);
|
||||
|
||||
let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty());
|
||||
|
||||
@ -1248,7 +1248,7 @@ impl<'a> MethodDef<'a> {
|
||||
self_arg_name,
|
||||
ast::Mutability::Not,
|
||||
);
|
||||
(cx.pat(sp, PatKind::Ref(p, ast::Mutability::Not)), idents)
|
||||
(cx.pat(span, PatKind::Ref(p, ast::Mutability::Not)), idents)
|
||||
};
|
||||
|
||||
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
|
||||
@ -1261,13 +1261,13 @@ impl<'a> MethodDef<'a> {
|
||||
idents
|
||||
};
|
||||
for self_arg_name in &self_arg_names[1..] {
|
||||
let (p, idents) = mk_self_pat(cx, &self_arg_name[..]);
|
||||
let (p, idents) = mk_self_pat(cx, &self_arg_name);
|
||||
subpats.push(p);
|
||||
self_pats_idents.push(idents);
|
||||
}
|
||||
|
||||
// Here is the pat = `(&VariantK, &VariantK, ...)`
|
||||
let single_pat = cx.pat_tuple(sp, subpats);
|
||||
let single_pat = cx.pat_tuple(span, subpats);
|
||||
|
||||
// For the BodyK, we need to delegate to our caller,
|
||||
// passing it an EnumMatching to indicate which case
|
||||
@ -1284,7 +1284,7 @@ impl<'a> MethodDef<'a> {
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
// For each arg field of self, pull out its getter expr ...
|
||||
.map(|(field_index, (sp, opt_ident, self_getter_expr, attrs))| {
|
||||
.map(|(field_index, (span, opt_ident, self_getter_expr, attrs))| {
|
||||
// ... but FieldInfo also wants getter expr
|
||||
// for matching other arguments of Self type;
|
||||
// so walk across the *other* self_pats_idents
|
||||
@ -1307,7 +1307,7 @@ impl<'a> MethodDef<'a> {
|
||||
.collect::<Vec<P<Expr>>>();
|
||||
|
||||
FieldInfo {
|
||||
span: sp,
|
||||
span,
|
||||
name: opt_ident,
|
||||
self_: self_getter_expr,
|
||||
other: others,
|
||||
@ -1330,7 +1330,7 @@ impl<'a> MethodDef<'a> {
|
||||
&substructure,
|
||||
);
|
||||
|
||||
cx.arm(sp, single_pat, arm_expr)
|
||||
cx.arm(span, single_pat, arm_expr)
|
||||
})
|
||||
.collect();
|
||||
|
||||
@ -1353,12 +1353,12 @@ impl<'a> MethodDef<'a> {
|
||||
// Since we know that all the arguments will match if we reach
|
||||
// the match expression we add the unreachable intrinsics as the
|
||||
// result of the catch all which should help llvm in optimizing it
|
||||
Some(deriving::call_unreachable(cx, sp))
|
||||
Some(deriving::call_unreachable(cx, span))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if let Some(arm) = default {
|
||||
match_arms.push(cx.arm(sp, cx.pat_wild(sp), arm));
|
||||
match_arms.push(cx.arm(span, cx.pat_wild(span), arm));
|
||||
}
|
||||
|
||||
// We will usually need the catch-all after matching the
|
||||
@ -1392,23 +1392,23 @@ impl<'a> MethodDef<'a> {
|
||||
|
||||
// We also build an expression which checks whether all discriminants are equal
|
||||
// discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
|
||||
let mut discriminant_test = cx.expr_bool(sp, true);
|
||||
let mut discriminant_test = cx.expr_bool(span, true);
|
||||
|
||||
let mut first_ident = None;
|
||||
for (&ident, self_arg) in iter::zip(&vi_idents, &self_args) {
|
||||
let self_addr = cx.expr_addr_of(sp, self_arg.clone());
|
||||
let self_addr = cx.expr_addr_of(span, self_arg.clone());
|
||||
let variant_value =
|
||||
deriving::call_intrinsic(cx, sp, sym::discriminant_value, vec![self_addr]);
|
||||
let let_stmt = cx.stmt_let(sp, false, ident, variant_value);
|
||||
deriving::call_intrinsic(cx, span, sym::discriminant_value, vec![self_addr]);
|
||||
let let_stmt = cx.stmt_let(span, false, ident, variant_value);
|
||||
index_let_stmts.push(let_stmt);
|
||||
|
||||
match first_ident {
|
||||
Some(first) => {
|
||||
let first_expr = cx.expr_ident(sp, first);
|
||||
let id = cx.expr_ident(sp, ident);
|
||||
let test = cx.expr_binary(sp, BinOpKind::Eq, first_expr, id);
|
||||
let first_expr = cx.expr_ident(span, first);
|
||||
let id = cx.expr_ident(span, ident);
|
||||
let test = cx.expr_binary(span, BinOpKind::Eq, first_expr, id);
|
||||
discriminant_test =
|
||||
cx.expr_binary(sp, BinOpKind::And, discriminant_test, test)
|
||||
cx.expr_binary(span, BinOpKind::And, discriminant_test, test)
|
||||
}
|
||||
None => {
|
||||
first_ident = Some(ident);
|
||||
@ -1430,8 +1430,8 @@ impl<'a> MethodDef<'a> {
|
||||
// them when they are fed as r-values into a tuple
|
||||
// expression; here add a layer of borrowing, turning
|
||||
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
|
||||
self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg));
|
||||
let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args));
|
||||
self_args.map_in_place(|self_arg| cx.expr_addr_of(span, self_arg));
|
||||
let match_arg = cx.expr(span, ast::ExprKind::Tup(self_args));
|
||||
|
||||
// Lastly we create an expression which branches on all discriminants being equal
|
||||
// if discriminant_test {
|
||||
@ -1445,10 +1445,10 @@ impl<'a> MethodDef<'a> {
|
||||
// else {
|
||||
// <delegated expression referring to __self0_vi, et al.>
|
||||
// }
|
||||
let all_match = cx.expr_match(sp, match_arg, match_arms);
|
||||
let arm_expr = cx.expr_if(sp, discriminant_test, all_match, Some(arm_expr));
|
||||
let all_match = cx.expr_match(span, match_arg, match_arms);
|
||||
let arm_expr = cx.expr_if(span, discriminant_test, all_match, Some(arm_expr));
|
||||
index_let_stmts.push(cx.stmt_expr(arm_expr));
|
||||
cx.expr_block(cx.block(sp, index_let_stmts))
|
||||
cx.expr_block(cx.block(span, index_let_stmts))
|
||||
} else if variants.is_empty() {
|
||||
// As an additional wrinkle, For a zero-variant enum A,
|
||||
// currently the compiler
|
||||
@ -1499,16 +1499,16 @@ impl<'a> MethodDef<'a> {
|
||||
// derive Debug on such a type could here generate code
|
||||
// that needs the feature gate enabled.)
|
||||
|
||||
deriving::call_unreachable(cx, sp)
|
||||
deriving::call_unreachable(cx, span)
|
||||
} else {
|
||||
// Final wrinkle: the self_args are expressions that deref
|
||||
// down to desired places, but we cannot actually deref
|
||||
// them when they are fed as r-values into a tuple
|
||||
// expression; here add a layer of borrowing, turning
|
||||
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
|
||||
self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg));
|
||||
let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args));
|
||||
cx.expr_match(sp, match_arg, match_arms)
|
||||
self_args.map_in_place(|self_arg| cx.expr_addr_of(span, self_arg));
|
||||
let match_arg = cx.expr(span, ast::ExprKind::Tup(self_args));
|
||||
cx.expr_match(span, match_arg, match_arms)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1556,11 +1556,9 @@ impl<'a> TraitDef<'a> {
|
||||
|
||||
let is_tuple = matches!(struct_def, ast::VariantData::Tuple(..));
|
||||
match (just_spans.is_empty(), named_idents.is_empty()) {
|
||||
(false, false) => cx.span_bug(
|
||||
self.span,
|
||||
"a struct with named and unnamed \
|
||||
fields in generic `derive`",
|
||||
),
|
||||
(false, false) => {
|
||||
cx.span_bug(self.span, "a struct with named and unnamed fields in generic `derive`")
|
||||
}
|
||||
// named fields
|
||||
(_, false) => Named(named_idents),
|
||||
// unnamed fields
|
||||
|
@ -211,14 +211,6 @@ fn mk_ty_param(
|
||||
cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
|
||||
}
|
||||
|
||||
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
|
||||
Generics {
|
||||
params,
|
||||
where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
/// Bounds on type parameters.
|
||||
#[derive(Clone)]
|
||||
pub struct Bounds {
|
||||
@ -236,7 +228,7 @@ impl Bounds {
|
||||
self_ty: Ident,
|
||||
self_generics: &Generics,
|
||||
) -> Generics {
|
||||
let generic_params = self
|
||||
let params = self
|
||||
.bounds
|
||||
.iter()
|
||||
.map(|t| {
|
||||
@ -245,7 +237,11 @@ impl Bounds {
|
||||
})
|
||||
.collect();
|
||||
|
||||
mk_generics(generic_params, span)
|
||||
Generics {
|
||||
params,
|
||||
where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
|
||||
span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,29 @@ pub fn expand_panic<'cx>(
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'cx> {
|
||||
let panic = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 };
|
||||
let mac = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 };
|
||||
expand(mac, cx, sp, tts)
|
||||
}
|
||||
|
||||
// This expands to either
|
||||
// - `$crate::panic::unreachable_2015!(...)` or
|
||||
// - `$crate::panic::unreachable_2021!(...)`
|
||||
// depending on the edition.
|
||||
pub fn expand_unreachable<'cx>(
|
||||
cx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'cx> {
|
||||
let mac = if use_panic_2021(sp) { sym::unreachable_2021 } else { sym::unreachable_2015 };
|
||||
expand(mac, cx, sp, tts)
|
||||
}
|
||||
|
||||
fn expand<'cx>(
|
||||
mac: rustc_span::Symbol,
|
||||
cx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: TokenStream,
|
||||
) -> Box<dyn MacResult + 'cx> {
|
||||
let sp = cx.with_call_site_ctxt(sp);
|
||||
|
||||
MacEager::expr(
|
||||
@ -31,7 +52,7 @@ pub fn expand_panic<'cx>(
|
||||
path: Path {
|
||||
span: sp,
|
||||
segments: cx
|
||||
.std_path(&[sym::panic, panic])
|
||||
.std_path(&[sym::panic, mac])
|
||||
.into_iter()
|
||||
.map(|ident| PathSegment::from_ident(ident))
|
||||
.collect(),
|
@ -80,11 +80,11 @@ pub fn expand_env<'cx>(
|
||||
}
|
||||
|
||||
let sp = cx.with_def_site_ctxt(sp);
|
||||
let value = env::var(&*var.as_str()).ok().as_deref().map(Symbol::intern);
|
||||
let value = env::var(var.as_str()).ok().as_deref().map(Symbol::intern);
|
||||
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
|
||||
let e = match value {
|
||||
None => {
|
||||
cx.span_err(sp, &msg.as_str());
|
||||
cx.span_err(sp, msg.as_str());
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
Some(value) => cx.expr_str(sp, value),
|
||||
|
@ -23,6 +23,7 @@ enum ArgumentType {
|
||||
|
||||
enum Position {
|
||||
Exact(usize),
|
||||
Capture(usize),
|
||||
Named(Symbol),
|
||||
}
|
||||
|
||||
@ -47,6 +48,8 @@ struct Context<'a, 'b> {
|
||||
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
|
||||
/// * `names` (in JSON): `{"foo": 2}`
|
||||
args: Vec<P<ast::Expr>>,
|
||||
/// The number of arguments that were added by implicit capturing.
|
||||
num_captured_args: usize,
|
||||
/// Placeholder slot numbers indexed by argument.
|
||||
arg_types: Vec<Vec<usize>>,
|
||||
/// Unique format specs seen for each argument.
|
||||
@ -88,8 +91,8 @@ struct Context<'a, 'b> {
|
||||
/// * Implicit argument resolution: `"{1:.0$} {2:.foo$} {1:.3$} {4:.0$}"`
|
||||
/// * Name resolution: `"{1:.0$} {2:.5$} {1:.3$} {4:.0$}"`
|
||||
/// * `count_positions` (in JSON): `{0: 0, 5: 1, 3: 2}`
|
||||
/// * `count_args`: `vec![Exact(0), Exact(5), Exact(3)]`
|
||||
count_args: Vec<Position>,
|
||||
/// * `count_args`: `vec![0, 5, 3]`
|
||||
count_args: Vec<usize>,
|
||||
/// Relative slot numbers for count arguments.
|
||||
count_positions: FxHashMap<usize, usize>,
|
||||
/// Number of count slots assigned.
|
||||
@ -229,6 +232,11 @@ fn parse_args<'a>(
|
||||
}
|
||||
|
||||
impl<'a, 'b> Context<'a, 'b> {
|
||||
/// The number of arguments that were explicitly given.
|
||||
fn num_args(&self) -> usize {
|
||||
self.args.len() - self.num_captured_args
|
||||
}
|
||||
|
||||
fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
|
||||
// NOTE: the `unwrap_or` branch is needed in case of invalid format
|
||||
// arguments, e.g., `format_args!("{foo}")`.
|
||||
@ -343,7 +351,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
}
|
||||
|
||||
fn describe_num_args(&self) -> Cow<'_, str> {
|
||||
match self.args.len() {
|
||||
match self.num_args() {
|
||||
0 => "no arguments were given".into(),
|
||||
1 => "there is 1 argument".into(),
|
||||
x => format!("there are {} arguments", x).into(),
|
||||
@ -369,7 +377,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
|
||||
let count = self.pieces.len()
|
||||
+ self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
|
||||
if self.names.is_empty() && !numbered_position_args && count != self.args.len() {
|
||||
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
|
||||
e = self.ecx.struct_span_err(
|
||||
sp,
|
||||
&format!(
|
||||
@ -417,7 +425,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
if let Some(span) = fmt.precision_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
match fmt.precision {
|
||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
e.span_label(
|
||||
span,
|
||||
&format!(
|
||||
@ -460,7 +468,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
if let Some(span) = fmt.width_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
match fmt.width {
|
||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
e.span_label(
|
||||
span,
|
||||
&format!(
|
||||
@ -492,12 +500,15 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
/// Actually verifies and tracks a given format placeholder
|
||||
/// (a.k.a. argument).
|
||||
fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
|
||||
if let Exact(arg) = arg {
|
||||
if arg >= self.num_args() {
|
||||
self.invalid_refs.push((arg, self.curpiece));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
match arg {
|
||||
Exact(arg) => {
|
||||
if self.args.len() <= arg {
|
||||
self.invalid_refs.push((arg, self.curpiece));
|
||||
return;
|
||||
}
|
||||
Exact(arg) | Capture(arg) => {
|
||||
match ty {
|
||||
Placeholder(_) => {
|
||||
// record every (position, type) combination only once
|
||||
@ -513,7 +524,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
if let Entry::Vacant(e) = self.count_positions.entry(arg) {
|
||||
let i = self.count_positions_count;
|
||||
e.insert(i);
|
||||
self.count_args.push(Exact(arg));
|
||||
self.count_args.push(arg);
|
||||
self.count_positions_count += 1;
|
||||
}
|
||||
}
|
||||
@ -524,7 +535,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
match self.names.get(&name) {
|
||||
Some(&idx) => {
|
||||
// Treat as positional arg.
|
||||
self.verify_arg_type(Exact(idx), ty)
|
||||
self.verify_arg_type(Capture(idx), ty)
|
||||
}
|
||||
None => {
|
||||
// For the moment capturing variables from format strings expanded from macros is
|
||||
@ -539,9 +550,10 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
} else {
|
||||
self.fmtsp
|
||||
};
|
||||
self.num_captured_args += 1;
|
||||
self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
|
||||
self.names.insert(name, idx);
|
||||
self.verify_arg_type(Exact(idx), ty)
|
||||
self.verify_arg_type(Capture(idx), ty)
|
||||
} else {
|
||||
let msg = format!("there is no argument named `{}`", name);
|
||||
let sp = if self.is_literal {
|
||||
@ -549,7 +561,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
} else {
|
||||
self.fmtsp
|
||||
};
|
||||
let mut err = self.ecx.struct_span_err(sp, &msg[..]);
|
||||
let mut err = self.ecx.struct_span_err(sp, &msg);
|
||||
|
||||
err.note(&format!(
|
||||
"did you intend to capture a variable `{}` from \
|
||||
@ -769,13 +781,12 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
for arg_ty in self.arg_unique_types[i].iter() {
|
||||
args.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, i));
|
||||
}
|
||||
heads.push(self.ecx.expr_addr_of(e.span, e));
|
||||
// use the arg span for `&arg` so that borrowck errors
|
||||
// point to the specific expression passed to the macro
|
||||
// (the span is otherwise unavailable in MIR)
|
||||
heads.push(self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e));
|
||||
}
|
||||
for pos in self.count_args {
|
||||
let index = match pos {
|
||||
Exact(i) => i,
|
||||
_ => panic!("should never happen"),
|
||||
};
|
||||
for index in self.count_args {
|
||||
let span = spans_pos[index];
|
||||
args.push(Context::format_arg(self.ecx, self.macsp, span, &Count, index));
|
||||
}
|
||||
@ -956,7 +967,7 @@ pub fn expand_preparsed_format_args(
|
||||
ast::StrStyle::Raw(raw) => Some(raw as usize),
|
||||
};
|
||||
|
||||
let fmt_str = &fmt_str.as_str(); // for the suggestions below
|
||||
let fmt_str = fmt_str.as_str(); // for the suggestions below
|
||||
let fmt_snippet = ecx.source_map().span_to_snippet(fmt_sp).ok();
|
||||
let mut parser = parse::Parser::new(
|
||||
fmt_str,
|
||||
@ -996,8 +1007,9 @@ pub fn expand_preparsed_format_args(
|
||||
e.note(¬e);
|
||||
}
|
||||
if let Some((label, span)) = err.secondary_label {
|
||||
let sp = fmt_span.from_inner(span);
|
||||
e.span_label(sp, label);
|
||||
if efmt_kind_is_lit {
|
||||
e.span_label(fmt_span.from_inner(span), label);
|
||||
}
|
||||
}
|
||||
e.emit();
|
||||
return DummyResult::raw_expr(sp, true);
|
||||
@ -1010,6 +1022,7 @@ pub fn expand_preparsed_format_args(
|
||||
let mut cx = Context {
|
||||
ecx,
|
||||
args,
|
||||
num_captured_args: 0,
|
||||
arg_types,
|
||||
arg_unique_types,
|
||||
names,
|
||||
|
@ -7,28 +7,29 @@ pub(crate) mod printf {
|
||||
pub enum Substitution<'a> {
|
||||
/// A formatted output substitution with its internal byte offset.
|
||||
Format(Format<'a>),
|
||||
/// A literal `%%` escape.
|
||||
Escape,
|
||||
/// A literal `%%` escape, with its start and end indices.
|
||||
Escape((usize, usize)),
|
||||
}
|
||||
|
||||
impl<'a> Substitution<'a> {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match *self {
|
||||
Substitution::Format(ref fmt) => fmt.span,
|
||||
Substitution::Escape => "%%",
|
||||
Substitution::Escape(_) => "%%",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn position(&self) -> Option<InnerSpan> {
|
||||
match *self {
|
||||
Substitution::Format(ref fmt) => Some(fmt.position),
|
||||
_ => None,
|
||||
Substitution::Escape((start, end)) => Some(InnerSpan::new(start, end)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
||||
if let Substitution::Format(ref mut fmt) = self {
|
||||
fmt.position = InnerSpan::new(start, end);
|
||||
match self {
|
||||
Substitution::Format(ref mut fmt) => fmt.position = InnerSpan::new(start, end),
|
||||
Substitution::Escape(ref mut pos) => *pos = (start, end),
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +40,7 @@ pub(crate) mod printf {
|
||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
||||
match *self {
|
||||
Substitution::Format(ref fmt) => fmt.translate(),
|
||||
Substitution::Escape => Err(None),
|
||||
Substitution::Escape(_) => Err(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -304,14 +305,9 @@ pub(crate) mod printf {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (mut sub, tail) = parse_next_substitution(self.s)?;
|
||||
self.s = tail;
|
||||
match sub {
|
||||
Substitution::Format(_) => {
|
||||
if let Some(inner_span) = sub.position() {
|
||||
sub.set_position(inner_span.start + self.pos, inner_span.end + self.pos);
|
||||
self.pos += inner_span.end;
|
||||
}
|
||||
}
|
||||
Substitution::Escape => self.pos += 2,
|
||||
if let Some(InnerSpan { start, end }) = sub.position() {
|
||||
sub.set_position(start + self.pos, end + self.pos);
|
||||
self.pos += end;
|
||||
}
|
||||
Some(sub)
|
||||
}
|
||||
@ -340,7 +336,7 @@ pub(crate) mod printf {
|
||||
let at = {
|
||||
let start = s.find('%')?;
|
||||
if let '%' = s[start + 1..].chars().next()? {
|
||||
return Some((Substitution::Escape, &s[start + 2..]));
|
||||
return Some((Substitution::Escape((start, start + 2)), &s[start + 2..]));
|
||||
}
|
||||
|
||||
Cur::new_at(s, start)
|
||||
|
@ -13,9 +13,9 @@ macro_rules! assert_eq_pnsat {
|
||||
fn test_escape() {
|
||||
assert_eq!(pns("has no escapes"), None);
|
||||
assert_eq!(pns("has no escapes, either %"), None);
|
||||
assert_eq!(pns("*so* has a %% escape"), Some((S::Escape, " escape")));
|
||||
assert_eq!(pns("%% leading escape"), Some((S::Escape, " leading escape")));
|
||||
assert_eq!(pns("trailing escape %%"), Some((S::Escape, "")));
|
||||
assert_eq!(pns("*so* has a %% escape"), Some((S::Escape((11, 13)), " escape")));
|
||||
assert_eq!(pns("%% leading escape"), Some((S::Escape((0, 2)), " leading escape")));
|
||||
assert_eq!(pns("trailing escape %%"), Some((S::Escape((16, 18)), "")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -6,7 +6,6 @@
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(nll)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(proc_macro_quote)]
|
||||
@ -20,28 +19,29 @@ use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
|
||||
use rustc_expand::proc_macro::BangProcMacro;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
mod asm;
|
||||
mod assert;
|
||||
mod cfg;
|
||||
mod cfg_accessible;
|
||||
mod cfg_eval;
|
||||
mod compile_error;
|
||||
mod concat;
|
||||
mod concat_bytes;
|
||||
mod concat_idents;
|
||||
mod derive;
|
||||
mod deriving;
|
||||
mod edition_panic;
|
||||
mod env;
|
||||
mod format;
|
||||
mod format_foreign;
|
||||
mod global_allocator;
|
||||
mod llvm_asm;
|
||||
mod log_syntax;
|
||||
mod panic;
|
||||
mod source_util;
|
||||
mod test;
|
||||
mod trace_macros;
|
||||
mod util;
|
||||
|
||||
pub mod asm;
|
||||
pub mod cmdline_attrs;
|
||||
pub mod proc_macro_harness;
|
||||
pub mod standard_library_imports;
|
||||
@ -65,6 +65,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
||||
cfg: cfg::expand_cfg,
|
||||
column: source_util::expand_column,
|
||||
compile_error: compile_error::expand_compile_error,
|
||||
concat_bytes: concat_bytes::expand_concat_bytes,
|
||||
concat_idents: concat_idents::expand_concat_idents,
|
||||
concat: concat::expand_concat,
|
||||
env: env::expand_env,
|
||||
@ -81,8 +82,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
||||
log_syntax: log_syntax::expand_log_syntax,
|
||||
module_path: source_util::expand_mod,
|
||||
option_env: env::expand_option_env,
|
||||
core_panic: panic::expand_panic,
|
||||
std_panic: panic::expand_panic,
|
||||
core_panic: edition_panic::expand_panic,
|
||||
std_panic: edition_panic::expand_panic,
|
||||
unreachable: edition_panic::expand_unreachable,
|
||||
stringify: source_util::expand_stringify,
|
||||
trace_macros: trace_macros::expand_trace_macros,
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/// The expansion from a test function to the appropriate test struct for libtest
|
||||
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
|
||||
use crate::util::check_builtin_macro_attribute;
|
||||
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::attr;
|
||||
@ -27,6 +27,7 @@ pub fn expand_test_case(
|
||||
anno_item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(ecx, meta_item, sym::test_case);
|
||||
warn_on_duplicate_attribute(&ecx, &anno_item, sym::test_case);
|
||||
|
||||
if !ecx.ecfg.should_test {
|
||||
return vec![];
|
||||
@ -55,6 +56,7 @@ pub fn expand_test(
|
||||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(cx, meta_item, sym::test);
|
||||
warn_on_duplicate_attribute(&cx, &item, sym::test);
|
||||
expand_test_or_bench(cx, attr_sp, item, false)
|
||||
}
|
||||
|
||||
@ -65,6 +67,7 @@ pub fn expand_bench(
|
||||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(cx, meta_item, sym::bench);
|
||||
warn_on_duplicate_attribute(&cx, &item, sym::bench);
|
||||
expand_test_or_bench(cx, attr_sp, item, true)
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,35 @@ struct TestHarnessGenerator<'a> {
|
||||
tests: Vec<Test>,
|
||||
}
|
||||
|
||||
impl TestHarnessGenerator<'_> {
|
||||
fn add_test_cases(&mut self, node_id: ast::NodeId, span: Span, prev_tests: Vec<Test>) {
|
||||
let mut tests = mem::replace(&mut self.tests, prev_tests);
|
||||
|
||||
if !tests.is_empty() {
|
||||
// Create an identifier that will hygienically resolve the test
|
||||
// case name, even in another module.
|
||||
let expn_id = self.cx.ext_cx.resolver.expansion_for_ast_pass(
|
||||
span,
|
||||
AstPass::TestHarness,
|
||||
&[],
|
||||
Some(node_id),
|
||||
);
|
||||
for test in &mut tests {
|
||||
// See the comment on `mk_main` for why we're using
|
||||
// `apply_mark` directly.
|
||||
test.ident.span =
|
||||
test.ident.span.apply_mark(expn_id.to_expn_id(), Transparency::Opaque);
|
||||
}
|
||||
self.cx.test_cases.extend(tests);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
||||
fn visit_crate(&mut self, c: &mut ast::Crate) {
|
||||
let prev_tests = mem::take(&mut self.tests);
|
||||
noop_visit_crate(c, self);
|
||||
self.add_test_cases(ast::CRATE_NODE_ID, c.span, prev_tests);
|
||||
|
||||
// Create a main function to run our tests
|
||||
c.items.push(mk_main(&mut self.cx));
|
||||
@ -103,34 +129,10 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
||||
|
||||
// We don't want to recurse into anything other than mods, since
|
||||
// mods or tests inside of functions will break things
|
||||
if let ast::ItemKind::Mod(..) = item.kind {
|
||||
let tests = mem::take(&mut self.tests);
|
||||
if let ast::ItemKind::Mod(_, ModKind::Loaded(.., span)) = item.kind {
|
||||
let prev_tests = mem::take(&mut self.tests);
|
||||
noop_visit_item_kind(&mut item.kind, self);
|
||||
let mut tests = mem::replace(&mut self.tests, tests);
|
||||
|
||||
if !tests.is_empty() {
|
||||
let parent =
|
||||
if item.id == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { item.id };
|
||||
// Create an identifier that will hygienically resolve the test
|
||||
// case name, even in another module.
|
||||
let inner_span = match item.kind {
|
||||
ast::ItemKind::Mod(_, ModKind::Loaded(.., span)) => span,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let expn_id = self.cx.ext_cx.resolver.expansion_for_ast_pass(
|
||||
inner_span,
|
||||
AstPass::TestHarness,
|
||||
&[],
|
||||
Some(parent),
|
||||
);
|
||||
for test in &mut tests {
|
||||
// See the comment on `mk_main` for why we're using
|
||||
// `apply_mark` directly.
|
||||
test.ident.span =
|
||||
test.ident.span.apply_mark(expn_id.to_expn_id(), Transparency::Opaque);
|
||||
}
|
||||
self.cx.test_cases.extend(tests);
|
||||
}
|
||||
self.add_test_cases(item.id, span, prev_tests);
|
||||
}
|
||||
smallvec![P(item)]
|
||||
}
|
||||
@ -146,7 +148,7 @@ fn entry_point_type(sess: &Session, item: &ast::Item, depth: usize) -> EntryPoin
|
||||
} else if sess.contains_name(&item.attrs, sym::rustc_main) {
|
||||
EntryPointType::MainAttr
|
||||
} else if item.ident.name == sym::main {
|
||||
if depth == 1 {
|
||||
if depth == 0 {
|
||||
// This is a top-level function so can be 'main'
|
||||
EntryPointType::MainNamed
|
||||
} else {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use rustc_ast::MetaItem;
|
||||
use rustc_expand::base::ExtCtxt;
|
||||
use rustc_ast::{Attribute, MetaItem};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_feature::AttributeTemplate;
|
||||
use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
|
||||
use rustc_parse::validate_attr;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
@ -10,3 +11,33 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na
|
||||
let attr = ecx.attribute(meta_item.clone());
|
||||
validate_attr::check_builtin_attribute(&ecx.sess.parse_sess, &attr, name, template);
|
||||
}
|
||||
|
||||
/// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when
|
||||
/// an attribute may have been mistakenly duplicated.
|
||||
pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
|
||||
let attrs: Option<&[Attribute]> = match item {
|
||||
Annotatable::Item(item) => Some(&item.attrs),
|
||||
Annotatable::TraitItem(item) => Some(&item.attrs),
|
||||
Annotatable::ImplItem(item) => Some(&item.attrs),
|
||||
Annotatable::ForeignItem(item) => Some(&item.attrs),
|
||||
Annotatable::Expr(expr) => Some(&expr.attrs),
|
||||
Annotatable::Arm(arm) => Some(&arm.attrs),
|
||||
Annotatable::ExprField(field) => Some(&field.attrs),
|
||||
Annotatable::PatField(field) => Some(&field.attrs),
|
||||
Annotatable::GenericParam(param) => Some(¶m.attrs),
|
||||
Annotatable::Param(param) => Some(¶m.attrs),
|
||||
Annotatable::FieldDef(def) => Some(&def.attrs),
|
||||
Annotatable::Variant(variant) => Some(&variant.attrs),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(attrs) = attrs {
|
||||
if let Some(attr) = ecx.sess.find_by_name(attrs, name) {
|
||||
ecx.parse_sess().buffer_lint(
|
||||
DUPLICATE_MACRO_ATTRIBUTES,
|
||||
attr.span,
|
||||
ecx.current_expansion.lint_node_id,
|
||||
"duplicated attribute",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,21 @@ on:
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
rustfmt:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install rustfmt
|
||||
run: |
|
||||
rustup component add rustfmt
|
||||
|
||||
- name: Rustfmt
|
||||
run: |
|
||||
cargo fmt --check
|
||||
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
@ -65,6 +80,12 @@ jobs:
|
||||
git config --global user.name "User"
|
||||
./y.rs prepare
|
||||
|
||||
- name: Build without unstable features
|
||||
env:
|
||||
TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }}
|
||||
# This is the config rust-lang/rust uses for builds
|
||||
run: ./y.rs build --no-unstable-features
|
||||
|
||||
- name: Build
|
||||
run: ./y.rs build --sysroot none
|
||||
|
||||
@ -152,11 +173,12 @@ jobs:
|
||||
|
||||
./y.exe build
|
||||
|
||||
#- name: Package prebuilt cg_clif
|
||||
# run: tar cvfJ cg_clif.tar.xz build
|
||||
- name: Package prebuilt cg_clif
|
||||
# don't use compression as xzip isn't supported by tar on windows and bzip2 hangs
|
||||
run: tar cvf cg_clif.tar build
|
||||
|
||||
#- name: Upload prebuilt cg_clif
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: cg_clif-${{ runner.os }}
|
||||
# path: cg_clif.tar.xz
|
||||
- name: Upload prebuilt cg_clif
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cg_clif-${{ runner.os }}
|
||||
path: cg_clif.tar
|
||||
|
59
compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
vendored
Normal file
59
compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
name: Test nightly Cranelift
|
||||
|
||||
on:
|
||||
push:
|
||||
schedule:
|
||||
- cron: '17 1 * * *' # At 01:17 UTC every day.
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache cargo installed crates
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/bin
|
||||
key: ubuntu-latest-cargo-installed-crates
|
||||
|
||||
- name: Prepare dependencies
|
||||
run: |
|
||||
git config --global user.email "user@example.com"
|
||||
git config --global user.name "User"
|
||||
./y.rs prepare
|
||||
|
||||
- name: Patch Cranelift
|
||||
run: |
|
||||
sed -i 's/cranelift-codegen = { version = "\w*.\w*.\w*", features = \["unwind", "all-arch"\] }/cranelift-codegen = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", features = ["unwind", "all-arch"] }/' Cargo.toml
|
||||
sed -i 's/cranelift-frontend = "\w*.\w*.\w*"/cranelift-frontend = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||
sed -i 's/cranelift-module = "\w*.\w*.\w*"/cranelift-module = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||
sed -i 's/cranelift-native = "\w*.\w*.\w*"/cranelift-native = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||
sed -i 's/cranelift-jit = { version = "\w*.\w*.\w*", optional = true }/cranelift-jit = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", optional = true }/' Cargo.toml
|
||||
sed -i 's/cranelift-object = "\w*.\w*.\w*"/cranelift-object = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||
|
||||
sed -i 's/gimli = { version = "0.25.0", default-features = false, features = \["write"\]}/gimli = { version = "0.26.1", default-features = false, features = ["write"] }/' Cargo.toml
|
||||
|
||||
cat Cargo.toml
|
||||
|
||||
- name: Build without unstable features
|
||||
# This is the config rust-lang/rust uses for builds
|
||||
run: ./y.rs build --no-unstable-features
|
||||
|
||||
- name: Build
|
||||
run: ./y.rs build --sysroot none
|
||||
- name: Test
|
||||
run: |
|
||||
# Enable backtraces for easier debugging
|
||||
export RUST_BACKTRACE=1
|
||||
|
||||
# Reduce amount of benchmark runs as they are slow
|
||||
export COMPILE_RUNS=2
|
||||
export RUN_RUNS=2
|
||||
|
||||
# Enable extra checks
|
||||
export CG_CLIF_ENABLE_VERIFIER=1
|
||||
|
||||
./test.sh
|
@ -5,6 +5,7 @@
|
||||
"rust-analyzer.assist.importEnforceGranularity": true,
|
||||
"rust-analyzer.assist.importPrefix": "crate",
|
||||
"rust-analyzer.cargo.runBuildScripts": true,
|
||||
"rust-analyzer.cargo.features": ["unstable-features"]
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./Cargo.toml",
|
||||
//"./build_sysroot/sysroot_src/src/libstd/Cargo.toml",
|
||||
|
86
compiler/rustc_codegen_cranelift/Cargo.lock
generated
86
compiler/rustc_codegen_cranelift/Cargo.lock
generated
@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.42"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
|
||||
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||
|
||||
[[package]]
|
||||
name = "ar"
|
||||
@ -21,9 +21,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -33,16 +33,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc0cb7df82c8cf8f2e6a8dd394a0932a71369c160cc9b027dca414fced242513"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4463c15fa42eee909e61e5eac4866b7c6d22d0d8c621e57a0c5380753bfa8c"
|
||||
dependencies = [
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen-meta",
|
||||
@ -57,8 +59,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793f6a94a053a55404ea16e1700202a88101672b8cd6b4df63e13cde950852bf"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity",
|
||||
@ -66,18 +69,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44aa1846df275bce5eb30379d65964c7afc63c05a117076e62a119c25fe174be"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3a45d8d6318bf8fc518154d9298eab2a8154ec068a8885ff113f6db8d69bb3a"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e07339bd461766deb7605169de039e01954768ff730fa1254e149001884a8525"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
@ -87,8 +93,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e8f0d60fb5d67f7a1e5c49db38ba96d1c846921faef02085fc5590b74781747"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -104,8 +111,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "825ac7e0959cbe7ddc9cc21209f0319e611a57f9fcb2b723861fe7ef2017e651"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -115,8 +123,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03e2fca76ff57e0532936a71e3fc267eae6a19a86656716479c66e7f912e3d7b"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
@ -125,8 +134,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.76.0"
|
||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
||||
version = "0.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55500d0fc9bb05c0944fc4506649249d28f55bd4fe95b87f0e55bf41058f0e6d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -138,9 +148,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.1"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
@ -172,9 +182,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.98"
|
||||
version = "0.2.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -206,15 +216,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.26.0"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
|
||||
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"indexmap",
|
||||
@ -223,9 +233,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regalloc"
|
||||
version = "0.0.31"
|
||||
version = "0.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
|
||||
checksum = "a6304468554ed921da3d32c355ea107b8d13d7b8996c3adfb7aab48d3bc321f4"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc-hash",
|
||||
@ -271,15 +281,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.1"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0652da4c4121005e9ed22b79f6c5f2d9e2752906b53a33e9490489ba421a6fb"
|
||||
checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
@ -8,23 +8,23 @@ crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
||||
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
||||
cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
||||
cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", optional = true }
|
||||
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
||||
cranelift-codegen = { version = "0.78.0", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = "0.78.0"
|
||||
cranelift-module = "0.78.0"
|
||||
cranelift-native = "0.78.0"
|
||||
cranelift-jit = { version = "0.78.0", optional = true }
|
||||
cranelift-object = "0.78.0"
|
||||
target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.25.0", default-features = false, features = ["write"]}
|
||||
object = { version = "0.26.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
object = { version = "0.27.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
||||
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||
indexmap = "1.0.2"
|
||||
libloading = { version = "0.6.0", optional = true }
|
||||
smallvec = "1.6.1"
|
||||
|
||||
[patch.crates-io]
|
||||
# Uncomment to use local checkout of cranelift
|
||||
#[patch."https://github.com/bytecodealliance/wasmtime.git"]
|
||||
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
|
||||
#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
|
||||
#cranelift-module = { path = "../wasmtime/cranelift/module" }
|
||||
@ -32,7 +32,6 @@ smallvec = "1.6.1"
|
||||
#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
|
||||
#cranelift-object = { path = "../wasmtime/cranelift/object" }
|
||||
|
||||
#[patch.crates-io]
|
||||
#gimli = { path = "../" }
|
||||
|
||||
[features]
|
||||
@ -41,31 +40,12 @@ unstable-features = ["jit", "inline_asm"]
|
||||
jit = ["cranelift-jit", "libloading"]
|
||||
inline_asm = []
|
||||
|
||||
[profile.dev]
|
||||
# By compiling dependencies with optimizations, performing tests gets much faster.
|
||||
opt-level = 3
|
||||
|
||||
[profile.dev.package.rustc_codegen_cranelift]
|
||||
# Disabling optimizations for cg_clif itself makes compilation after a change faster.
|
||||
opt-level = 0
|
||||
|
||||
[profile.release.package.rustc_codegen_cranelift]
|
||||
incremental = true
|
||||
|
||||
# Disable optimizations and debuginfo of build scripts and some of the heavy build deps, as the
|
||||
# execution time of build scripts is so fast that optimizing them slows down the total build time.
|
||||
[profile.dev.build-override]
|
||||
opt-level = 0
|
||||
debug = false
|
||||
|
||||
[profile.release.build-override]
|
||||
opt-level = 0
|
||||
debug = false
|
||||
|
||||
[profile.dev.package.cranelift-codegen-meta]
|
||||
opt-level = 0
|
||||
debug = false
|
||||
|
||||
[profile.release.package.cranelift-codegen-meta]
|
||||
opt-level = 0
|
||||
debug = false
|
||||
|
@ -37,7 +37,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
|
||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo build
|
||||
$ $cg_clif_dir/build/cargo-clif build
|
||||
```
|
||||
|
||||
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||
|
@ -40,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.70"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -56,7 +56,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.50"
|
||||
version = "0.1.66"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
@ -67,9 +67,9 @@ version = "0.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "dlmalloc"
|
||||
version = "0.2.1"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
|
||||
checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
@ -132,9 +132,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.102"
|
||||
version = "0.2.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
@ -2,9 +2,29 @@ use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
pub(crate) fn build_backend(channel: &str, host_triple: &str) -> PathBuf {
|
||||
pub(crate) fn build_backend(
|
||||
channel: &str,
|
||||
host_triple: &str,
|
||||
use_unstable_features: bool,
|
||||
) -> PathBuf {
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("build").arg("--target").arg(host_triple).arg("--features").arg("unstable-features");
|
||||
cmd.arg("build").arg("--target").arg(host_triple);
|
||||
|
||||
cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode
|
||||
|
||||
let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default();
|
||||
|
||||
if env::var("CI").as_ref().map(|val| &**val) == Ok("true") {
|
||||
// Deny warnings on CI
|
||||
rustflags += " -Dwarnings";
|
||||
|
||||
// Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
|
||||
cmd.env("CARGO_BUILD_INCREMENTAL", "false");
|
||||
}
|
||||
|
||||
if use_unstable_features {
|
||||
cmd.arg("--features").arg("unstable-features");
|
||||
}
|
||||
|
||||
match channel {
|
||||
"debug" => {}
|
||||
@ -14,25 +34,20 @@ pub(crate) fn build_backend(channel: &str, host_triple: &str) -> PathBuf {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
// Set the rpath to make the cg_clif executable find librustc_codegen_cranelift without changing
|
||||
// LD_LIBRARY_PATH
|
||||
if cfg!(unix) {
|
||||
if cfg!(target_os = "macos") {
|
||||
cmd.env(
|
||||
"RUSTFLAGS",
|
||||
"-Csplit-debuginfo=unpacked \
|
||||
rustflags += " -Csplit-debuginfo=unpacked \
|
||||
-Clink-arg=-Wl,-rpath,@loader_path/../lib \
|
||||
-Zosx-rpath-install-name"
|
||||
.to_string()
|
||||
+ env::var("RUSTFLAGS").as_deref().unwrap_or(""),
|
||||
);
|
||||
-Zosx-rpath-install-name";
|
||||
} else {
|
||||
cmd.env(
|
||||
"RUSTFLAGS",
|
||||
"-Clink-arg=-Wl,-rpath=$ORIGIN/../lib ".to_string()
|
||||
+ env::var("RUSTFLAGS").as_deref().unwrap_or(""),
|
||||
);
|
||||
rustflags += " -Clink-arg=-Wl,-rpath=$ORIGIN/../lib ";
|
||||
}
|
||||
}
|
||||
|
||||
cmd.env("RUSTFLAGS", rustflags);
|
||||
|
||||
eprintln!("[BUILD] rustc_codegen_cranelift");
|
||||
crate::utils::spawn_and_wait(cmd);
|
||||
|
||||
|
@ -46,9 +46,9 @@ pub(crate) fn build_sysroot(
|
||||
// Build and copy cargo wrapper
|
||||
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
||||
build_cargo_wrapper_cmd
|
||||
.arg("scripts/cargo.rs")
|
||||
.arg("scripts/cargo-clif.rs")
|
||||
.arg("-o")
|
||||
.arg(target_dir.join("cargo"))
|
||||
.arg(target_dir.join("cargo-clif"))
|
||||
.arg("-g");
|
||||
spawn_and_wait(build_cargo_wrapper_cmd);
|
||||
|
||||
@ -193,8 +193,7 @@ fn build_clif_sysroot_for_triple(
|
||||
"RUSTC",
|
||||
env::current_dir().unwrap().join(target_dir).join("bin").join("cg_clif_build_sysroot"),
|
||||
);
|
||||
// FIXME Enable incremental again once rust-lang/rust#74946 is fixed
|
||||
build_cmd.env("CARGO_INCREMENTAL", "0").env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
|
||||
build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
|
||||
spawn_and_wait(build_cmd);
|
||||
|
||||
// Copy all relevant files to the sysroot
|
||||
|
@ -30,7 +30,7 @@ pub(crate) fn prepare() {
|
||||
clone_repo(
|
||||
"portable-simd",
|
||||
"https://github.com/rust-lang/portable-simd",
|
||||
"8cf7a62e5d2552961df51e5200aaa5b7c890a4bf",
|
||||
"b8d6b6844602f80af79cd96401339ec594d472d8",
|
||||
);
|
||||
apply_patches("portable-simd", Path::new("portable-simd"));
|
||||
|
||||
@ -92,7 +92,7 @@ fn prepare_sysroot() {
|
||||
clone_repo(
|
||||
"build_sysroot/compiler-builtins",
|
||||
"https://github.com/rust-lang/compiler-builtins.git",
|
||||
"0.1.50",
|
||||
"0.1.66",
|
||||
);
|
||||
apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
|
||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo build
|
||||
$ $cg_clif_dir/build/cargo-clif build
|
||||
```
|
||||
|
||||
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||
@ -32,7 +32,7 @@ In jit mode cg_clif will immediately execute your code without creating an execu
|
||||
> The jit mode will probably need cargo integration to make this possible.
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo jit
|
||||
$ $cg_clif_dir/build/cargo-clif jit
|
||||
```
|
||||
|
||||
or
|
||||
@ -45,7 +45,7 @@ There is also an experimental lazy jit mode. In this mode functions are only com
|
||||
first called.
|
||||
|
||||
```bash
|
||||
$ $cg_clif_dir/build/cargo lazy-jit
|
||||
$ $cg_clif_dir/build/cargo-clif lazy-jit
|
||||
```
|
||||
|
||||
## Shell
|
||||
|
@ -0,0 +1,60 @@
|
||||
// Copied from rustc ui test suite
|
||||
|
||||
// run-pass
|
||||
//
|
||||
// Test that we can handle unsized types with an extern type tail part.
|
||||
// Regression test for issue #91827.
|
||||
|
||||
#![feature(const_ptr_offset_from)]
|
||||
#![feature(const_slice_from_raw_parts)]
|
||||
#![feature(extern_types)]
|
||||
|
||||
use std::ptr::addr_of;
|
||||
|
||||
extern "C" {
|
||||
type Opaque;
|
||||
}
|
||||
|
||||
unsafe impl Sync for Opaque {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct List<T> {
|
||||
len: usize,
|
||||
data: [T; 0],
|
||||
tail: Opaque,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ListImpl<T, const N: usize> {
|
||||
len: usize,
|
||||
data: [T; N],
|
||||
}
|
||||
|
||||
impl<T> List<T> {
|
||||
const fn as_slice(&self) -> &[T] {
|
||||
unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const N: usize> ListImpl<T, N> {
|
||||
const fn as_list(&self) -> &List<T> {
|
||||
unsafe { std::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
pub static A: ListImpl<u128, 3> = ListImpl {
|
||||
len: 3,
|
||||
data: [5, 6, 7],
|
||||
};
|
||||
pub static A_REF: &'static List<u128> = A.as_list();
|
||||
pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
|
||||
|
||||
const fn tail_offset<T>(list: &List<T>) -> isize {
|
||||
unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
|
||||
// Check that interpreter and code generation agree about the position of the tail field.
|
||||
assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
|
||||
}
|
@ -129,6 +129,7 @@ fn call_return_u128_pair() {
|
||||
return_u128_pair();
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)] // FIXME false positive
|
||||
fn main() {
|
||||
take_unique(Unique {
|
||||
pointer: 0 as *const (),
|
||||
|
@ -1,41 +1,20 @@
|
||||
From 6bfce5dc2cbf834c74dbccb7538adc08c6eb57e7 Mon Sep 17 00:00:00 2001
|
||||
From 97c473937382a5b5858d9cce3c947855d23b2dc5 Mon Sep 17 00:00:00 2001
|
||||
From: bjorn3 <bjorn3@users.noreply.github.com>
|
||||
Date: Sun, 25 Jul 2021 18:39:31 +0200
|
||||
Date: Thu, 18 Nov 2021 19:28:40 +0100
|
||||
Subject: [PATCH] Disable unsupported tests
|
||||
|
||||
---
|
||||
crates/core_simd/src/vector.rs | 2 ++
|
||||
crates/core_simd/src/math.rs | 4 ++++
|
||||
crates/core_simd/tests/masks.rs | 12 ------------
|
||||
crates/core_simd/tests/ops_macros.rs | 6 ++++++
|
||||
crates/core_simd/tests/round.rs | 2 ++
|
||||
6 files changed, 15 insertions(+), 13 deletions(-)
|
||||
crates/core_simd/src/math.rs | 6 ++++++
|
||||
crates/core_simd/src/vector.rs | 2 ++
|
||||
crates/core_simd/tests/masks.rs | 2 ++
|
||||
crates/core_simd/tests/ops_macros.rs | 4 ++++
|
||||
4 files changed, 14 insertions(+)
|
||||
|
||||
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
|
||||
index 25c5309..2b3d819 100644
|
||||
--- a/crates/core_simd/src/vector.rs
|
||||
+++ b/crates/core_simd/src/vector.rs
|
||||
@@ -22,6 +22,7 @@ where
|
||||
self.0
|
||||
}
|
||||
|
||||
+ /*
|
||||
/// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
|
||||
/// If an index is out of bounds, that lane instead selects the value from the "or" vector.
|
||||
/// ```
|
||||
@@ -150,6 +151,7 @@ where
|
||||
// Cleared ☢️ *mut T Zone
|
||||
}
|
||||
}
|
||||
+ */
|
||||
}
|
||||
|
||||
impl<T, const LANES: usize> Copy for Simd<T, LANES>
|
||||
diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs
|
||||
index 7290a28..e394730 100644
|
||||
index 2bae414..2f87499 100644
|
||||
--- a/crates/core_simd/src/math.rs
|
||||
+++ b/crates/core_simd/src/math.rs
|
||||
@@ -2,6 +2,7 @@ macro_rules! impl_uint_arith {
|
||||
@@ -5,6 +5,7 @@ macro_rules! impl_uint_arith {
|
||||
($($ty:ty),+) => {
|
||||
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
|
||||
|
||||
@ -43,15 +22,15 @@ index 7290a28..e394730 100644
|
||||
/// Lanewise saturating add.
|
||||
///
|
||||
/// # Examples
|
||||
@@ -38,6 +39,7 @@ macro_rules! impl_uint_arith {
|
||||
@@ -43,6 +44,7 @@ macro_rules! impl_uint_arith {
|
||||
pub fn saturating_sub(self, second: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
|
||||
unsafe { simd_saturating_sub(self, second) }
|
||||
}
|
||||
+ */
|
||||
})+
|
||||
}
|
||||
}
|
||||
@@ -46,6 +48,7 @@ macro_rules! impl_int_arith {
|
||||
@@ -51,6 +53,7 @@ macro_rules! impl_int_arith {
|
||||
($($ty:ty),+) => {
|
||||
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
|
||||
|
||||
@ -59,7 +38,23 @@ index 7290a28..e394730 100644
|
||||
/// Lanewise saturating add.
|
||||
///
|
||||
/// # Examples
|
||||
@@ -141,6 +144,7 @@ macro_rules! impl_int_arith {
|
||||
@@ -89,6 +92,7 @@ macro_rules! impl_int_arith {
|
||||
pub fn saturating_sub(self, second: Self) -> Self {
|
||||
unsafe { simd_saturating_sub(self, second) }
|
||||
}
|
||||
+ */
|
||||
|
||||
/// Lanewise absolute value, implemented in Rust.
|
||||
/// Every lane becomes its absolute value.
|
||||
@@ -109,6 +113,7 @@ macro_rules! impl_int_arith {
|
||||
(self^m) - m
|
||||
}
|
||||
|
||||
+ /*
|
||||
/// Lanewise saturating absolute value, implemented in Rust.
|
||||
/// As abs(), except the MIN value becomes MAX instead of itself.
|
||||
///
|
||||
@@ -151,6 +156,7 @@ macro_rules! impl_int_arith {
|
||||
pub fn saturating_neg(self) -> Self {
|
||||
Self::splat(0).saturating_sub(self)
|
||||
}
|
||||
@ -67,51 +62,51 @@ index 7290a28..e394730 100644
|
||||
})+
|
||||
}
|
||||
}
|
||||
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
|
||||
index 7c5ec2b..c8631e8 100644
|
||||
--- a/crates/core_simd/src/vector.rs
|
||||
+++ b/crates/core_simd/src/vector.rs
|
||||
@@ -75,6 +75,7 @@ where
|
||||
Self(array)
|
||||
}
|
||||
|
||||
+ /*
|
||||
/// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
|
||||
/// If an index is out-of-bounds, the lane is instead selected from the `or` vector.
|
||||
///
|
||||
@@ -297,6 +298,7 @@ where
|
||||
// Cleared ☢️ *mut T Zone
|
||||
}
|
||||
}
|
||||
+ */
|
||||
}
|
||||
|
||||
impl<T, const LANES: usize> Copy for Simd<T, LANES>
|
||||
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
|
||||
index 61d8e44..2bccae2 100644
|
||||
index 6a8ecd3..68fcb49 100644
|
||||
--- a/crates/core_simd/tests/masks.rs
|
||||
+++ b/crates/core_simd/tests/masks.rs
|
||||
@@ -67,19 +67,6 @@ macro_rules! test_mask_api {
|
||||
assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]);
|
||||
@@ -68,6 +68,7 @@ macro_rules! test_mask_api {
|
||||
assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
|
||||
}
|
||||
-
|
||||
- #[cfg(feature = "generic_const_exprs")]
|
||||
- #[test]
|
||||
- fn roundtrip_bitmask_conversion() {
|
||||
- let values = [
|
||||
- true, false, false, true, false, false, true, false,
|
||||
- true, true, false, false, false, false, false, true,
|
||||
- ];
|
||||
- let mask = core_simd::Mask::<$type, 16>::from_array(values);
|
||||
- let bitmask = mask.to_bitmask();
|
||||
- assert_eq!(bitmask, [0b01001001, 0b10000011]);
|
||||
- assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
|
||||
- }
|
||||
|
||||
+ /*
|
||||
#[cfg(feature = "generic_const_exprs")]
|
||||
#[test]
|
||||
fn roundtrip_bitmask_conversion() {
|
||||
@@ -80,6 +81,7 @@ macro_rules! test_mask_api {
|
||||
assert_eq!(bitmask, [0b01001001, 0b10000011]);
|
||||
assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
|
||||
}
|
||||
+ */
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
|
||||
index cb39e73..fc0ebe1 100644
|
||||
index 31b7ee2..bd04b3c 100644
|
||||
--- a/crates/core_simd/tests/ops_macros.rs
|
||||
+++ b/crates/core_simd/tests/ops_macros.rs
|
||||
@@ -435,6 +435,7 @@ macro_rules! impl_float_tests {
|
||||
)
|
||||
}
|
||||
|
||||
+ /*
|
||||
fn mul_add<const LANES: usize>() {
|
||||
test_helpers::test_ternary_elementwise(
|
||||
&Vector::<LANES>::mul_add,
|
||||
@@ -442,6 +443,7 @@ macro_rules! impl_float_tests {
|
||||
&|_, _, _| true,
|
||||
)
|
||||
}
|
||||
+ */
|
||||
|
||||
fn recip<const LANES: usize>() {
|
||||
test_helpers::test_unary_elementwise(
|
||||
@@ -581,6 +585,7 @@ macro_rules! impl_float_tests {
|
||||
@@ -567,6 +567,7 @@ macro_rules! impl_float_tests {
|
||||
});
|
||||
}
|
||||
|
||||
@ -119,7 +114,7 @@ index cb39e73..fc0ebe1 100644
|
||||
fn horizontal_max<const LANES: usize>() {
|
||||
test_helpers::test_1(&|x| {
|
||||
let vmax = Vector::<LANES>::from_array(x).horizontal_max();
|
||||
@@ -604,6 +609,7 @@ macro_rules! impl_float_tests {
|
||||
@@ -590,6 +591,7 @@ macro_rules! impl_float_tests {
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
@ -127,26 +122,22 @@ index cb39e73..fc0ebe1 100644
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
|
||||
index 37044a7..4cdc6b7 100644
|
||||
--- a/crates/core_simd/tests/round.rs
|
||||
+++ b/crates/core_simd/tests/round.rs
|
||||
@@ -25,6 +25,7 @@ macro_rules! float_rounding_test {
|
||||
)
|
||||
}
|
||||
@@ -604,6 +606,7 @@ macro_rules! impl_float_tests {
|
||||
)
|
||||
}
|
||||
|
||||
+ /*
|
||||
fn round<const LANES: usize>() {
|
||||
test_helpers::test_unary_elementwise(
|
||||
&Vector::<LANES>::round,
|
||||
@@ -32,6 +33,7 @@ macro_rules! float_rounding_test {
|
||||
&|_| true,
|
||||
)
|
||||
+ /*
|
||||
fn mul_add<const LANES: usize>() {
|
||||
test_helpers::test_ternary_elementwise(
|
||||
&Vector::<LANES>::mul_add,
|
||||
@@ -611,6 +614,7 @@ macro_rules! impl_float_tests {
|
||||
&|_, _, _| true,
|
||||
)
|
||||
}
|
||||
+ */
|
||||
}
|
||||
+ */
|
||||
|
||||
fn trunc<const LANES: usize>() {
|
||||
test_helpers::test_unary_elementwise(
|
||||
}
|
||||
}
|
||||
--
|
||||
2.26.2.7.g19db9cfb68
|
||||
|
||||
|
@ -107,7 +107,7 @@ index fa96b7a..2854f9c 100644
|
||||
inner::monotonize(raw)
|
||||
}
|
||||
|
||||
-#[cfg(all(target_has_atomic = "64", not(target_has_atomic = "128")))]
|
||||
-#[cfg(any(all(target_has_atomic = "64", not(target_has_atomic = "128")), target_arch = "aarch64"))]
|
||||
+#[cfg(target_has_atomic = "64")]
|
||||
pub mod inner {
|
||||
use crate::sync::atomic::AtomicU64;
|
||||
@ -117,7 +117,7 @@ index fa96b7a..2854f9c 100644
|
||||
}
|
||||
|
||||
+/*
|
||||
#[cfg(target_has_atomic = "128")]
|
||||
#[cfg(all(target_has_atomic = "128", not(target_arch = "aarch64")))]
|
||||
pub mod inner {
|
||||
use crate::sync::atomic::AtomicU128;
|
||||
@@ -94,8 +95,9 @@ pub mod inner {
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 0ffdd8eda8df364391c8ac6e1ce92c73ba9254d4 Mon Sep 17 00:00:00 2001
|
||||
From: bjorn3 <bjorn3@users.noreply.github.com>
|
||||
Date: Fri, 3 Dec 2021 12:16:30 +0100
|
||||
Subject: [PATCH] Disable long running tests
|
||||
|
||||
---
|
||||
library/core/tests/slice.rs | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
|
||||
index 2c8f00a..44847ee 100644
|
||||
--- a/library/core/tests/slice.rs
|
||||
+++ b/library/core/tests/slice.rs
|
||||
@@ -2332,7 +2332,8 @@ macro_rules! empty_max_mut {
|
||||
};
|
||||
}
|
||||
|
||||
+/*
|
||||
#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
|
||||
take_tests! {
|
||||
slice: &[(); usize::MAX], method: take,
|
||||
(take_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]),
|
||||
@@ -2345,3 +2347,4 @@ take_tests! {
|
||||
(take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
|
||||
(take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
|
||||
}
|
||||
+*/
|
||||
--
|
||||
2.26.2.7.g19db9cfb68
|
||||
|
@ -1,3 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2021-09-19"
|
||||
channel = "nightly-2021-12-30"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
@ -42,7 +42,7 @@ fn main() {
|
||||
"RUSTFLAGS",
|
||||
env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
|
||||
);
|
||||
std::array::IntoIter::new(["rustc".to_string()])
|
||||
IntoIterator::into_iter(["rustc".to_string()])
|
||||
.chain(env::args().skip(2))
|
||||
.chain([
|
||||
"--".to_string(),
|
||||
@ -56,7 +56,7 @@ fn main() {
|
||||
"RUSTFLAGS",
|
||||
env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
|
||||
);
|
||||
std::array::IntoIter::new(["rustc".to_string()])
|
||||
IntoIterator::into_iter(["rustc".to_string()])
|
||||
.chain(env::args().skip(2))
|
||||
.chain([
|
||||
"--".to_string(),
|
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
./y.rs build
|
||||
./y.rs build --no-unstable-features
|
||||
source scripts/config.sh
|
||||
|
||||
echo "[SETUP] Rust fork"
|
||||
@ -33,7 +33,7 @@ index d95b5b7f17f..00b6f0e3635 100644
|
||||
[dependencies]
|
||||
core = { path = "../core" }
|
||||
-compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
|
||||
+compiler_builtins = { version = "0.1.46", features = ['rustc-dep-of-std', 'no-asm'] }
|
||||
+compiler_builtins = { version = "0.1.66", features = ['rustc-dep-of-std', 'no-asm'] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
@ -53,5 +53,6 @@ local-rebuild = true
|
||||
[rust]
|
||||
codegen-backends = ["cranelift"]
|
||||
deny-warnings = false
|
||||
verbose-tests = false
|
||||
EOF
|
||||
popd
|
||||
|
@ -10,7 +10,7 @@ pushd rust
|
||||
|
||||
cargo install ripgrep
|
||||
|
||||
rm -r src/test/ui/{extern/,panics/,unsized-locals/,thinlto/,simd*,*lto*.rs,linkage*,unwind-*.rs} || true
|
||||
rm -r src/test/ui/{extern/,panics/,unsized-locals/,lto/,simd*,linkage*,unwind-*.rs} || true
|
||||
for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto|// needs-asm-support" src/test/ui); do
|
||||
rm $test
|
||||
done
|
||||
@ -30,22 +30,25 @@ rm src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
|
||||
rm src/test/ui/issues/issue-26655.rs
|
||||
rm src/test/ui/issues/issue-29485.rs
|
||||
rm src/test/ui/issues/issue-30018-panic.rs
|
||||
rm src/test/ui/multi-panic.rs
|
||||
rm src/test/ui/process/multi-panic.rs
|
||||
rm src/test/ui/sepcomp/sepcomp-unwind.rs
|
||||
rm src/test/ui/structs-enums/unit-like-struct-drop-run.rs
|
||||
rm src/test/ui/terminate-in-initializer.rs
|
||||
rm src/test/ui/drop/terminate-in-initializer.rs
|
||||
rm src/test/ui/threads-sendsync/task-stderr.rs
|
||||
rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
|
||||
rm src/test/ui/drop/drop-trait-enum.rs
|
||||
rm src/test/ui/numbers-arithmetic/issue-8460.rs
|
||||
rm src/test/ui/rt-explody-panic-payloads.rs
|
||||
rm src/test/ui/runtime/rt-explody-panic-payloads.rs
|
||||
rm src/test/incremental/change_crate_dep_kind.rs
|
||||
rm src/test/ui/threads-sendsync/unwind-resource.rs
|
||||
|
||||
rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
|
||||
rm src/test/ui/init-large-type.rs # same
|
||||
rm src/test/ui/codegen/init-large-type.rs # same
|
||||
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
||||
rm src/test/ui/issues/issue-33992.rs # unsupported linkages
|
||||
rm src/test/ui/issues/issue-51947.rs # same
|
||||
rm src/test/incremental/hashes/function_interfaces.rs # same
|
||||
rm src/test/incremental/hashes/statics.rs # same
|
||||
rm src/test/ui/numbers-arithmetic/saturating-float-casts.rs # intrinsic gives different but valid result
|
||||
rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
|
||||
rm src/test/ui/mir/mir_raw_fat_ptr.rs # same
|
||||
@ -59,22 +62,22 @@ rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and n
|
||||
|
||||
rm src/test/incremental/hashes/inline_asm.rs # inline asm
|
||||
rm src/test/incremental/issue-72386.rs # same
|
||||
rm src/test/incremental/issue-49482.rs # same
|
||||
rm src/test/incremental/issue-54059.rs # same
|
||||
rm src/test/incremental/lto.rs # requires lto
|
||||
rm src/test/incremental/dirty_clean.rs # TODO
|
||||
|
||||
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
|
||||
rm -r src/test/run-make/unstable-flag-required # same
|
||||
rm -r src/test/run-make/rustdoc-* # same
|
||||
rm -r src/test/run-make/emit-named-files # requires full --emit support
|
||||
|
||||
rm src/test/pretty/asm.rs # inline asm
|
||||
rm src/test/pretty/raw-str-nonexpr.rs # same
|
||||
|
||||
rm -r src/test/run-pass-valgrind/unsized-locals
|
||||
|
||||
rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning
|
||||
rm src/test/ui/json-bom-plus-crlf.rs # same
|
||||
rm src/test/ui/intrinsics/const-eval-select-x86_64.rs # same
|
||||
rm src/test/ui/match/issue-82392.rs # differing error
|
||||
rm src/test/ui/consts/min_const_fn/address_of_const.rs # same
|
||||
rm src/test/ui/consts/issue-miri-1910.rs # same
|
||||
rm src/test/ui/type-alias-impl-trait/cross_crate_ice*.rs # requires removed aux dep
|
||||
|
||||
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
|
||||
@ -88,6 +91,16 @@ rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
|
||||
rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
|
||||
rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support
|
||||
|
||||
rm src/test/ui/command/command-current-dir.rs # can't find libstd.so
|
||||
|
||||
rm src/test/ui/abi/stack-protector.rs # requires stack protector support
|
||||
|
||||
rm src/test/incremental/issue-80691-bad-eval-cache.rs # wrong exit code
|
||||
rm src/test/incremental/spike-neg1.rs # errors out for some reason
|
||||
rm src/test/incremental/spike-neg2.rs # same
|
||||
|
||||
rm src/test/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM
|
||||
|
||||
echo "[TEST] rustc test suite"
|
||||
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui}
|
||||
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
|
||||
popd
|
||||
|
@ -35,6 +35,10 @@ function base_sysroot_tests() {
|
||||
$MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
|
||||
$RUN_WRAPPER ./target/out/arbitrary_self_types_pointers_and_wrappers
|
||||
|
||||
echo "[AOT] issue_91827_extern_types"
|
||||
$MY_RUSTC example/issue-91827-extern-types.rs --crate-name issue_91827_extern_types --crate-type bin --target "$TARGET_TRIPLE"
|
||||
$RUN_WRAPPER ./target/out/issue_91827_extern_types
|
||||
|
||||
echo "[AOT] alloc_system"
|
||||
$MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"
|
||||
|
||||
@ -76,73 +80,73 @@ function base_sysroot_tests() {
|
||||
|
||||
function extended_sysroot_tests() {
|
||||
pushd rand
|
||||
../build/cargo clean
|
||||
../build/cargo-clif clean
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
echo "[TEST] rust-random/rand"
|
||||
../build/cargo test --workspace
|
||||
../build/cargo-clif test --workspace
|
||||
else
|
||||
echo "[AOT] rust-random/rand"
|
||||
../build/cargo build --workspace --target $TARGET_TRIPLE --tests
|
||||
../build/cargo-clif build --workspace --target $TARGET_TRIPLE --tests
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd simple-raytracer
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
echo "[BENCH COMPILE] ebobby/simple-raytracer"
|
||||
hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo clean" \
|
||||
hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo-clif clean" \
|
||||
"RUSTC=rustc RUSTFLAGS='' cargo build" \
|
||||
"../build/cargo build"
|
||||
"../build/cargo-clif build"
|
||||
|
||||
echo "[BENCH RUN] ebobby/simple-raytracer"
|
||||
cp ./target/debug/main ./raytracer_cg_clif
|
||||
hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
|
||||
else
|
||||
../build/cargo clean
|
||||
../build/cargo-clif clean
|
||||
echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
|
||||
echo "[COMPILE] ebobby/simple-raytracer"
|
||||
../build/cargo build --target $TARGET_TRIPLE
|
||||
../build/cargo-clif build --target $TARGET_TRIPLE
|
||||
echo "[BENCH RUN] ebobby/simple-raytracer (skipped)"
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd build_sysroot/sysroot_src/library/core/tests
|
||||
echo "[TEST] libcore"
|
||||
../../../../../build/cargo clean
|
||||
../../../../../build/cargo-clif clean
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
../../../../../build/cargo test
|
||||
../../../../../build/cargo-clif test
|
||||
else
|
||||
../../../../../build/cargo build --target $TARGET_TRIPLE --tests
|
||||
../../../../../build/cargo-clif build --target $TARGET_TRIPLE --tests
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd regex
|
||||
echo "[TEST] rust-lang/regex example shootout-regex-dna"
|
||||
../build/cargo clean
|
||||
../build/cargo-clif clean
|
||||
export RUSTFLAGS="$RUSTFLAGS --cap-lints warn" # newer aho_corasick versions throw a deprecation warning
|
||||
# Make sure `[codegen mono items] start` doesn't poison the diff
|
||||
../build/cargo build --example shootout-regex-dna --target $TARGET_TRIPLE
|
||||
../build/cargo-clif build --example shootout-regex-dna --target $TARGET_TRIPLE
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
cat examples/regexdna-input.txt \
|
||||
| ../build/cargo run --example shootout-regex-dna --target $TARGET_TRIPLE \
|
||||
| ../build/cargo-clif run --example shootout-regex-dna --target $TARGET_TRIPLE \
|
||||
| grep -v "Spawned thread" > res.txt
|
||||
diff -u res.txt examples/regexdna-output.txt
|
||||
fi
|
||||
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
echo "[TEST] rust-lang/regex tests"
|
||||
../build/cargo test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
|
||||
../build/cargo-clif test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
|
||||
else
|
||||
echo "[AOT] rust-lang/regex tests"
|
||||
../build/cargo build --tests --target $TARGET_TRIPLE
|
||||
../build/cargo-clif build --tests --target $TARGET_TRIPLE
|
||||
fi
|
||||
popd
|
||||
|
||||
pushd portable-simd
|
||||
echo "[TEST] rust-lang/portable-simd"
|
||||
../build/cargo clean
|
||||
../build/cargo build --all-targets --target $TARGET_TRIPLE
|
||||
../build/cargo-clif clean
|
||||
../build/cargo-clif build --all-targets --target $TARGET_TRIPLE
|
||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||
../build/cargo test -q
|
||||
../build/cargo-clif test -q
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
@ -18,11 +18,11 @@ pub(crate) use self::returning::codegen_return;
|
||||
|
||||
fn clif_sig_from_fn_abi<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
triple: &target_lexicon::Triple,
|
||||
default_call_conv: CallConv,
|
||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
) -> Signature {
|
||||
let call_conv = match fn_abi.conv {
|
||||
Conv::Rust | Conv::C => CallConv::triple_default(triple),
|
||||
Conv::Rust | Conv::C => default_call_conv,
|
||||
Conv::X86_64SysV => CallConv::SystemV,
|
||||
Conv::X86_64Win64 => CallConv::WindowsFastcall,
|
||||
Conv::ArmAapcs
|
||||
@ -55,7 +55,7 @@ pub(crate) fn get_function_sig<'tcx>(
|
||||
assert!(!inst.substs.needs_infer());
|
||||
clif_sig_from_fn_abi(
|
||||
tcx,
|
||||
triple,
|
||||
CallConv::triple_default(triple),
|
||||
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
|
||||
)
|
||||
}
|
||||
@ -91,7 +91,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
returns: Vec<AbiParam>,
|
||||
args: &[Value],
|
||||
) -> &[Value] {
|
||||
let sig = Signature { params, returns, call_conv: CallConv::triple_default(self.triple()) };
|
||||
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
|
||||
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
|
||||
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
|
||||
let call_inst = self.bcx.ins().call(func_ref, args);
|
||||
@ -420,7 +420,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
}
|
||||
|
||||
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0].value, idx);
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
|
||||
let sig = fx.bcx.import_signature(sig);
|
||||
|
||||
(CallTarget::Indirect(sig, method), Some(ptr))
|
||||
@ -440,7 +440,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
}
|
||||
|
||||
let func = codegen_operand(fx, func).load_scalar(fx);
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
|
||||
let sig = fx.bcx.import_signature(sig);
|
||||
|
||||
(CallTarget::Indirect(sig, func), None)
|
||||
@ -531,7 +531,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
|
||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
|
||||
let sig = fx.bcx.import_signature(sig);
|
||||
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
|
||||
.prefix
|
||||
.iter()
|
||||
.flatten()
|
||||
.map(|&kind| reg_to_abi_param(Reg { kind, size: cast.prefix_chunk_size }))
|
||||
.map(|®| reg_to_abi_param(reg))
|
||||
.chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))
|
||||
.collect::<SmallVec<_>>();
|
||||
|
||||
@ -117,7 +117,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||
PassMode::Cast(cast) => cast_target_to_abi_params(cast),
|
||||
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
|
||||
if on_stack {
|
||||
let size = u32::try_from(self.layout.size.bytes()).unwrap();
|
||||
// Abi requires aligning struct size to pointer size
|
||||
let size = self.layout.size.align_to(tcx.data_layout.pointer_align.abi);
|
||||
let size = u32::try_from(size.bytes()).unwrap();
|
||||
smallvec![apply_arg_attrs_to_abi_param(
|
||||
AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructArgument(size),),
|
||||
attrs
|
||||
@ -204,7 +206,6 @@ pub(super) fn from_casted_value<'tcx>(
|
||||
// It may also be smaller for example when the type is a wrapper around an integer with a
|
||||
// larger alignment than the integer.
|
||||
size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16,
|
||||
offset: None,
|
||||
});
|
||||
let ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0));
|
||||
let mut offset = 0;
|
||||
|
@ -1,7 +1,6 @@
|
||||
//! Creation of ar archives like for the lib and staticlib crate type
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Seek};
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -10,7 +9,7 @@ use rustc_codegen_ssa::back::archive::ArchiveBuilder;
|
||||
use rustc_session::Session;
|
||||
|
||||
use object::read::archive::ArchiveFile;
|
||||
use object::{Object, ObjectSymbol, ReadCache, SymbolKind};
|
||||
use object::{Object, ObjectSymbol, ReadCache};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ArchiveEntry {
|
||||
@ -150,12 +149,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||
object
|
||||
.symbols()
|
||||
.filter_map(|symbol| {
|
||||
if symbol.is_undefined()
|
||||
|| symbol.is_local()
|
||||
|| symbol.kind() != SymbolKind::Data
|
||||
&& symbol.kind() != SymbolKind::Text
|
||||
&& symbol.kind() != SymbolKind::Tls
|
||||
{
|
||||
if symbol.is_undefined() || symbol.is_local() {
|
||||
None
|
||||
} else {
|
||||
symbol.name().map(|name| name.as_bytes().to_vec()).ok()
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Codegen of a single function
|
||||
|
||||
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
|
||||
use rustc_ast::InlineAsmOptions;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
@ -48,13 +49,15 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
(0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
|
||||
|
||||
// Make FunctionCx
|
||||
let pointer_type = module.target_config().pointer_type();
|
||||
let target_config = module.target_config();
|
||||
let pointer_type = target_config.pointer_type();
|
||||
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
|
||||
|
||||
let mut fx = FunctionCx {
|
||||
cx,
|
||||
module,
|
||||
tcx,
|
||||
target_config,
|
||||
pointer_type,
|
||||
constants_cx: ConstantCx::new(),
|
||||
|
||||
@ -71,8 +74,6 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
clif_comments,
|
||||
source_info_set: indexmap::IndexSet::new(),
|
||||
next_ssa_var: 0,
|
||||
|
||||
inline_asm_index: 0,
|
||||
};
|
||||
|
||||
let arg_uninhabited = fx
|
||||
@ -203,7 +204,6 @@ pub(crate) fn verify_func(
|
||||
tcx.sess.err(&format!("{:?}", err));
|
||||
let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error(
|
||||
&func,
|
||||
None,
|
||||
Some(Box::new(writer)),
|
||||
err,
|
||||
);
|
||||
@ -239,7 +239,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||
fx.add_comment(inst, terminator_head);
|
||||
}
|
||||
|
||||
fx.set_debug_loc(bb_data.terminator().source_info);
|
||||
let source_info = bb_data.terminator().source_info;
|
||||
fx.set_debug_loc(source_info);
|
||||
|
||||
match &bb_data.terminator().kind {
|
||||
TerminatorKind::Goto { target } => {
|
||||
@ -294,20 +295,18 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||
AssertKind::BoundsCheck { ref len, ref index } => {
|
||||
let len = codegen_operand(fx, len).load_scalar(fx);
|
||||
let index = codegen_operand(fx, index).load_scalar(fx);
|
||||
let location = fx
|
||||
.get_caller_location(bb_data.terminator().source_info.span)
|
||||
.load_scalar(fx);
|
||||
let location = fx.get_caller_location(source_info.span).load_scalar(fx);
|
||||
|
||||
codegen_panic_inner(
|
||||
fx,
|
||||
rustc_hir::LangItem::PanicBoundsCheck,
|
||||
&[index, len, location],
|
||||
bb_data.terminator().source_info.span,
|
||||
source_info.span,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let msg_str = msg.description();
|
||||
codegen_panic(fx, msg_str, bb_data.terminator().source_info.span);
|
||||
codegen_panic(fx, msg_str, source_info.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -378,10 +377,18 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||
options,
|
||||
destination,
|
||||
line_spans: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
if options.contains(InlineAsmOptions::MAY_UNWIND) {
|
||||
fx.tcx.sess.span_fatal(
|
||||
source_info.span,
|
||||
"cranelift doesn't support unwinding from inline assembly.",
|
||||
);
|
||||
}
|
||||
|
||||
crate::inline_asm::codegen_inline_asm(
|
||||
fx,
|
||||
bb_data.terminator().source_info.span,
|
||||
source_info.span,
|
||||
template,
|
||||
operands,
|
||||
*options,
|
||||
@ -415,7 +422,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||
}
|
||||
TerminatorKind::Drop { place, target, unwind: _ } => {
|
||||
let drop_place = codegen_place(fx, *place);
|
||||
crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place);
|
||||
crate::abi::codegen_drop(fx, source_info.span, drop_place);
|
||||
|
||||
let target_block = fx.get_block(*target);
|
||||
fx.bcx.ins().jump(target_block, &[]);
|
||||
@ -671,7 +678,7 @@ fn codegen_stmt<'tcx>(
|
||||
// FIXME use emit_small_memset where possible
|
||||
let addr = lval.to_ptr().get_addr(fx);
|
||||
let val = operand.load_scalar(fx);
|
||||
fx.bcx.call_memset(fx.module.target_config(), addr, val, times);
|
||||
fx.bcx.call_memset(fx.target_config, addr, val, times);
|
||||
} else {
|
||||
let loop_block = fx.bcx.create_block();
|
||||
let loop_block2 = fx.bcx.create_block();
|
||||
@ -708,30 +715,6 @@ fn codegen_stmt<'tcx>(
|
||||
let operand = operand.load_scalar(fx);
|
||||
lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
|
||||
}
|
||||
Rvalue::NullaryOp(NullOp::Box, content_ty) => {
|
||||
let usize_type = fx.clif_type(fx.tcx.types.usize).unwrap();
|
||||
let content_ty = fx.monomorphize(content_ty);
|
||||
let layout = fx.layout_of(content_ty);
|
||||
let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64);
|
||||
let llalign = fx.bcx.ins().iconst(usize_type, layout.align.abi.bytes() as i64);
|
||||
let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
|
||||
|
||||
// Allocate space:
|
||||
let def_id =
|
||||
match fx.tcx.lang_items().require(rustc_hir::LangItem::ExchangeMalloc) {
|
||||
Ok(id) => id,
|
||||
Err(s) => {
|
||||
fx.tcx
|
||||
.sess
|
||||
.fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
|
||||
}
|
||||
};
|
||||
let instance = ty::Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
|
||||
let func_ref = fx.get_function_ref(instance);
|
||||
let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]);
|
||||
let ptr = fx.bcx.inst_results(call)[0];
|
||||
lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
|
||||
}
|
||||
Rvalue::NullaryOp(null_op, ty) => {
|
||||
assert!(
|
||||
lval.layout()
|
||||
@ -742,10 +725,8 @@ fn codegen_stmt<'tcx>(
|
||||
let val = match null_op {
|
||||
NullOp::SizeOf => layout.size.bytes(),
|
||||
NullOp::AlignOf => layout.align.abi.bytes(),
|
||||
NullOp::Box => unreachable!(),
|
||||
};
|
||||
let val =
|
||||
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
|
||||
let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
|
||||
lval.write_cvalue(fx, val);
|
||||
}
|
||||
Rvalue::Aggregate(ref kind, ref operands) => match kind.as_ref() {
|
||||
@ -793,7 +774,7 @@ fn codegen_stmt<'tcx>(
|
||||
let elem_size: u64 = pointee.size.bytes();
|
||||
let bytes =
|
||||
if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
|
||||
fx.bcx.call_memcpy(fx.module.target_config(), dst, src, bytes);
|
||||
fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
|
||||
@ -235,7 +236,8 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
|
||||
pub(crate) cx: &'clif mut crate::CodegenCx<'tcx>,
|
||||
pub(crate) module: &'m mut dyn Module,
|
||||
pub(crate) tcx: TyCtxt<'tcx>,
|
||||
pub(crate) pointer_type: Type, // Cached from module
|
||||
pub(crate) target_config: TargetFrontendConfig, // Cached from module
|
||||
pub(crate) pointer_type: Type, // Cached from module
|
||||
pub(crate) constants_cx: ConstantCx,
|
||||
|
||||
pub(crate) instance: Instance<'tcx>,
|
||||
@ -255,8 +257,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
|
||||
|
||||
/// This should only be accessed by `CPlace::new_var`.
|
||||
pub(crate) next_ssa_var: u32,
|
||||
|
||||
pub(crate) inline_asm_index: u32,
|
||||
}
|
||||
|
||||
impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
||||
@ -359,10 +359,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty())
|
||||
}
|
||||
|
||||
pub(crate) fn triple(&self) -> &target_lexicon::Triple {
|
||||
self.module.isa().triple()
|
||||
}
|
||||
|
||||
pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value {
|
||||
let mut data_ctx = DataContext::new();
|
||||
data_ctx.define(msg.as_bytes().to_vec().into_boxed_slice());
|
||||
|
@ -369,7 +369,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
TodoItem::Static(def_id) => {
|
||||
//println!("static {:?}", def_id);
|
||||
|
||||
let section_name = tcx.codegen_fn_attrs(def_id).link_section.map(|s| s.as_str());
|
||||
let section_name = tcx.codegen_fn_attrs(def_id).link_section;
|
||||
|
||||
let alloc = tcx.eval_static_initializer(def_id).unwrap();
|
||||
|
||||
@ -388,6 +388,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
|
||||
if let Some(section_name) = section_name {
|
||||
let (segment_name, section_name) = if tcx.sess.target.is_like_osx {
|
||||
let section_name = section_name.as_str();
|
||||
if let Some(names) = section_name.split_once(',') {
|
||||
names
|
||||
} else {
|
||||
@ -397,7 +398,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
));
|
||||
}
|
||||
} else {
|
||||
("", &*section_name)
|
||||
("", section_name.as_str())
|
||||
};
|
||||
data_ctx.set_segment_section(segment_name, section_name);
|
||||
}
|
||||
|
@ -67,10 +67,8 @@ impl WriterRelocate {
|
||||
}
|
||||
|
||||
/// Perform the collected relocations to be usable for JIT usage.
|
||||
#[cfg(feature = "jit")]
|
||||
#[cfg(all(feature = "jit", not(windows)))]
|
||||
pub(super) fn relocate_for_jit(mut self, jit_module: &cranelift_jit::JITModule) -> Vec<u8> {
|
||||
use std::convert::TryInto;
|
||||
|
||||
for reloc in self.relocs.drain(..) {
|
||||
match reloc.name {
|
||||
super::DebugRelocName::Section(_) => unreachable!(),
|
||||
|
@ -10,7 +10,7 @@ use crate::prelude::*;
|
||||
use rustc_index::vec::IndexVec;
|
||||
|
||||
use cranelift_codegen::entity::EntityRef;
|
||||
use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc};
|
||||
use cranelift_codegen::ir::{Endianness, LabelValueLoc, ValueLabel};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::ValueLocRange;
|
||||
|
||||
@ -23,15 +23,6 @@ use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
|
||||
pub(crate) use emit::{DebugReloc, DebugRelocName};
|
||||
pub(crate) use unwind::UnwindContext;
|
||||
|
||||
fn target_endian(tcx: TyCtxt<'_>) -> RunTimeEndian {
|
||||
use rustc_target::abi::Endian;
|
||||
|
||||
match tcx.data_layout.endian {
|
||||
Endian::Big => RunTimeEndian::Big,
|
||||
Endian::Little => RunTimeEndian::Little,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct DebugContext<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
@ -60,6 +51,11 @@ impl<'tcx> DebugContext<'tcx> {
|
||||
address_size: isa.frontend_config().pointer_bytes(),
|
||||
};
|
||||
|
||||
let endian = match isa.endianness() {
|
||||
Endianness::Little => RunTimeEndian::Little,
|
||||
Endianness::Big => RunTimeEndian::Big,
|
||||
};
|
||||
|
||||
let mut dwarf = DwarfUnit::new(encoding);
|
||||
|
||||
let producer = format!(
|
||||
@ -67,7 +63,12 @@ impl<'tcx> DebugContext<'tcx> {
|
||||
rustc_interface::util::version_str().unwrap_or("unknown version"),
|
||||
cranelift_codegen::VERSION,
|
||||
);
|
||||
let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped).into_owned();
|
||||
let comp_dir = tcx
|
||||
.sess
|
||||
.opts
|
||||
.working_dir
|
||||
.to_string_lossy(FileNameDisplayPreference::Remapped)
|
||||
.into_owned();
|
||||
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
|
||||
Some(path) => {
|
||||
let name = path.to_string_lossy().into_owned();
|
||||
@ -103,7 +104,7 @@ impl<'tcx> DebugContext<'tcx> {
|
||||
DebugContext {
|
||||
tcx,
|
||||
|
||||
endian: target_endian(tcx),
|
||||
endian,
|
||||
|
||||
dwarf,
|
||||
unit_range_list: RangeList(Vec::new()),
|
||||
@ -250,7 +251,7 @@ impl<'tcx> DebugContext<'tcx> {
|
||||
|
||||
// FIXME make it more reliable and implement scopes before re-enabling this.
|
||||
if false {
|
||||
let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
|
||||
let value_labels_ranges = std::collections::HashMap::new(); // FIXME
|
||||
|
||||
for (local, _local_decl) in mir.local_decls.iter_enumerated() {
|
||||
let ty = self.tcx.subst_and_normalize_erasing_regions(
|
||||
@ -264,7 +265,6 @@ impl<'tcx> DebugContext<'tcx> {
|
||||
self,
|
||||
isa,
|
||||
symbol,
|
||||
context,
|
||||
&local_map,
|
||||
&value_labels_ranges,
|
||||
Place { local, projection: ty::List::empty() },
|
||||
@ -283,7 +283,6 @@ fn place_location<'tcx>(
|
||||
debug_context: &mut DebugContext<'tcx>,
|
||||
isa: &dyn TargetIsa,
|
||||
symbol: usize,
|
||||
context: &Context,
|
||||
local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
|
||||
#[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
|
||||
ValueLabel,
|
||||
@ -306,12 +305,7 @@ fn place_location<'tcx>(
|
||||
addend: i64::from(value_loc_range.start),
|
||||
},
|
||||
end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
|
||||
data: translate_loc(
|
||||
isa,
|
||||
value_loc_range.loc,
|
||||
&context.func.stack_slots,
|
||||
)
|
||||
.unwrap(),
|
||||
data: translate_loc(isa, value_loc_range.loc).unwrap(),
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
@ -340,34 +334,14 @@ fn place_location<'tcx>(
|
||||
AttributeValue::Exprloc(Expression::new())
|
||||
|
||||
// For PointerBase::Stack:
|
||||
//AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot), &context.func.stack_slots).unwrap())
|
||||
//AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot)).unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
|
||||
fn translate_loc(
|
||||
isa: &dyn TargetIsa,
|
||||
loc: LabelValueLoc,
|
||||
stack_slots: &StackSlots,
|
||||
) -> Option<Expression> {
|
||||
fn translate_loc(isa: &dyn TargetIsa, loc: LabelValueLoc) -> Option<Expression> {
|
||||
match loc {
|
||||
LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => {
|
||||
let machine_reg = isa.map_dwarf_register(reg).unwrap();
|
||||
let mut expr = Expression::new();
|
||||
expr.op_reg(gimli::Register(machine_reg));
|
||||
Some(expr)
|
||||
}
|
||||
LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => {
|
||||
if let Some(ss_offset) = stack_slots[ss].offset {
|
||||
let mut expr = Expression::new();
|
||||
expr.op_breg(X86_64::RBP, i64::from(ss_offset) + 16);
|
||||
Some(expr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
LabelValueLoc::ValueLoc(ValueLoc::Unassigned) => unreachable!(),
|
||||
LabelValueLoc::Reg(reg) => {
|
||||
let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
|
||||
let mut expr = Expression::new();
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use cranelift_module::FuncId;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user