New upstream version 1.59.0+dfsg1

This commit is contained in:
Ximin Luo 2022-03-29 13:22:26 +01:00
parent 3c0e092ef8
commit a2a8927aec
4709 changed files with 200302 additions and 67573 deletions

302
Cargo.lock generated
View File

@ -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",
]

View File

@ -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

View File

@ -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};

View File

@ -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]

View File

@ -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;
}
}

View File

@ -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

View File

@ -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,

View File

@ -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)]

View File

@ -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(),
}
}
}

View File

@ -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| {

View File

@ -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]

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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,
)
}

View File

@ -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
})

View File

@ -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<'_>;`.

View File

@ -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)
}
}

View File

@ -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();
}
}

View File

@ -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 &param.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",
);

View File

@ -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).

View File

@ -6,6 +6,7 @@
#![feature(iter_is_partitioned)]
#![feature(box_patterns)]
#![feature(let_else)]
#![recursion_limit = "256"]
pub mod ast_validation;

View File

@ -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("*/")
}
}

View File

@ -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

View File

@ -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

View File

@ -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>,

View File

@ -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>,
) {
}
}

View File

@ -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

View File

@ -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(

View File

@ -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,
&param.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 {

View File

@ -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);
}
}
}

View File

@ -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 }
});

View File

@ -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));
}
}
}

View File

@ -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(&note);
diag.help("see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance");
}
}

View File

@ -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
{

View File

@ -199,6 +199,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
options: _,
line_spans: _,
destination: _,
cleanup: _,
} => {
for op in operands {
match *op {

View File

@ -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) => {

View File

@ -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,
{

View File

@ -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>,

View File

@ -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 => {}
}

View File

@ -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),

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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>,

View File

@ -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>,

View File

@ -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!(

View File

@ -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

View File

@ -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
}

View File

@ -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" }

View File

@ -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,

View File

@ -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};

View File

@ -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(&param),
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.

View File

@ -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);

View 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))))
}

View File

@ -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;
}
}

View File

@ -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(),

View File

@ -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 &param.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

View File

@ -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,
}
}
}

View File

@ -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(),

View File

@ -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),

View File

@ -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(&note);
}
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,

View File

@ -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)

View File

@ -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]

View File

@ -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,
}

View File

@ -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)
}

View File

@ -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 {

View File

@ -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(&param.attrs),
Annotatable::Param(param) => Some(&param.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",
);
}
}
}

View File

@ -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

View 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

View File

@ -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",

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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",
]

View File

@ -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);

View File

@ -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

View File

@ -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"));
}

View File

@ -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

View File

@ -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));
}

View File

@ -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 (),

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2021-09-19"
channel = "nightly-2021-12-30"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View File

@ -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(),

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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]);
}

View File

@ -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| 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;

View File

@ -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()

View File

@ -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);
}
}
}

View File

@ -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());

View File

@ -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);
}

View File

@ -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!(),

View File

@ -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();

View File

@ -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