mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-06 12:09:03 +00:00
New upstream version 1.59.0+dfsg1
This commit is contained in:
parent
3c0e092ef8
commit
a2a8927aec
302
Cargo.lock
generated
302
Cargo.lock
generated
@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
|
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"gimli",
|
"gimli 0.25.0",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
@ -87,9 +87,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.34"
|
version = "1.0.51"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
|
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "array_tool"
|
name = "array_tool"
|
||||||
@ -175,9 +175,7 @@ dependencies = [
|
|||||||
"filetime",
|
"filetime",
|
||||||
"getopts",
|
"getopts",
|
||||||
"ignore",
|
"ignore",
|
||||||
"lazy_static",
|
|
||||||
"libc",
|
"libc",
|
||||||
"merge",
|
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"opener",
|
"opener",
|
||||||
@ -276,7 +274,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo"
|
name = "cargo"
|
||||||
version = "0.59.0"
|
version = "0.60.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"atty",
|
"atty",
|
||||||
@ -370,7 +368,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"directories",
|
"directories",
|
||||||
"rustc-workspace-hack",
|
"rustc-workspace-hack",
|
||||||
"rustc_version 0.3.3",
|
"rustc_version",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"vergen",
|
"vergen",
|
||||||
@ -419,7 +417,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo-util"
|
name = "cargo-util"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
@ -492,9 +490,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chalk-derive"
|
name = "chalk-derive"
|
||||||
version = "0.55.0"
|
version = "0.75.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3983193cacd81f0f924acb666b7fe5e1a0d81db9f113fa69203eda7ea8ce8b6c"
|
checksum = "d54e3b5f9e3425e6b119ff07568d8d006bfa5a8d6f78a9cbc3530b1e962e316c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -504,9 +502,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chalk-engine"
|
name = "chalk-engine"
|
||||||
version = "0.55.0"
|
version = "0.75.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05a171ce5abbf0fbd06f221ab80ab182c7ef78603d23b858bc44e7ce8a86a396"
|
checksum = "bdc891073396b167163db77123b0a3c00088edc00466cecc5531f33e3e989523"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chalk-derive",
|
"chalk-derive",
|
||||||
"chalk-ir",
|
"chalk-ir",
|
||||||
@ -517,9 +515,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chalk-ir"
|
name = "chalk-ir"
|
||||||
version = "0.55.0"
|
version = "0.75.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a522f53af971e7678f472d687e053120157b3ae26e2ebd5ecbc0f5ab124f2cb6"
|
checksum = "2b79e5a1d04b79311e90c69356a2c62027853906a7e33b3e070b93c055fc3e8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chalk-derive",
|
"chalk-derive",
|
||||||
@ -528,14 +526,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chalk-solve"
|
name = "chalk-solve"
|
||||||
version = "0.55.0"
|
version = "0.75.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdf79fb77a567e456a170f7ec84ea6584163d4ba3f13660cd182013d34ca667c"
|
checksum = "a5d2a1db6605aba70a58820bd80ac422b218913a510f1a40beef9efc5371ea1d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chalk-derive",
|
"chalk-derive",
|
||||||
"chalk-ir",
|
"chalk-ir",
|
||||||
"ena",
|
"ena",
|
||||||
"itertools 0.9.0",
|
"itertools 0.10.1",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -558,11 +556,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.3"
|
version = "2.34.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.11.0",
|
"ansi_term 0.12.1",
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"strsim",
|
"strsim",
|
||||||
@ -574,7 +572,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.1.58"
|
version = "0.1.59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_metadata 0.14.0",
|
"cargo_metadata 0.14.0",
|
||||||
"clippy_lints",
|
"clippy_lints",
|
||||||
@ -584,6 +582,7 @@ dependencies = [
|
|||||||
"filetime",
|
"filetime",
|
||||||
"if_chain",
|
"if_chain",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
|
"parking_lot",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-workspace-hack",
|
"rustc-workspace-hack",
|
||||||
@ -600,6 +599,7 @@ name = "clippy_dev"
|
|||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytecount",
|
"bytecount",
|
||||||
|
"cargo_metadata 0.14.0",
|
||||||
"clap",
|
"clap",
|
||||||
"indoc",
|
"indoc",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
@ -611,13 +611,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.1.58"
|
version = "0.1.59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_metadata 0.14.0",
|
"cargo_metadata 0.14.0",
|
||||||
"clippy_utils",
|
"clippy_utils",
|
||||||
"if_chain",
|
"if_chain",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
"pulldown-cmark 0.8.0",
|
"pulldown-cmark",
|
||||||
"quine-mc_cluskey",
|
"quine-mc_cluskey",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
"rustc-semver",
|
"rustc-semver",
|
||||||
@ -632,7 +632,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_utils"
|
name = "clippy_utils"
|
||||||
version = "0.1.58"
|
version = "0.1.59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"if_chain",
|
"if_chain",
|
||||||
"rustc-semver",
|
"rustc-semver",
|
||||||
@ -678,9 +678,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.53"
|
version = "0.1.67"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2467ff455350a4df7d02f1ed1449d0279605a763de5d586dcf6aa7d732508bcb"
|
checksum = "a68c69e9451f1df4b215c9588c621670c12286b53e60fb5ec4b59aaa1138d18e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
@ -766,7 +766,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crates-io"
|
name = "crates-io"
|
||||||
version = "0.33.0"
|
version = "0.33.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"curl",
|
"curl",
|
||||||
@ -1158,6 +1158,12 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@ -1446,6 +1452,17 @@ dependencies = [
|
|||||||
"rustc-std-workspace-core",
|
"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]]
|
[[package]]
|
||||||
name = "git2"
|
name = "git2"
|
||||||
version = "0.13.23"
|
version = "0.13.23"
|
||||||
@ -1713,9 +1730,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.6"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
@ -1900,9 +1920,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.106"
|
version = "0.2.108"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
|
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
@ -1921,6 +1941,16 @@ dependencies = [
|
|||||||
"pkg-config",
|
"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]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@ -1939,9 +1969,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libssh2-sys"
|
name = "libssh2-sys"
|
||||||
version = "0.2.19"
|
version = "0.2.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca46220853ba1c512fc82826d0834d87b06bcd3c2a42241b7de72f3d2fe17056"
|
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1992,9 +2022,9 @@ version = "0.1.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.1"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
|
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
@ -2092,9 +2122,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.0.1"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
]
|
]
|
||||||
@ -2124,9 +2154,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mdbook"
|
name = "mdbook"
|
||||||
version = "0.4.12"
|
version = "0.4.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0651782b4cc514c3f98c0acf9b5af1101a735bbe1ac6852bb1a90cb91bdf0ed4"
|
checksum = "241f10687eb3b4e0634b3b4e423f97c5f1efbd69dc9522e24a8b94583eeec3c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -2138,8 +2168,8 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"open",
|
"opener",
|
||||||
"pulldown-cmark 0.7.2",
|
"pulldown-cmark",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
@ -2147,6 +2177,7 @@ dependencies = [
|
|||||||
"shlex",
|
"shlex",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"toml",
|
"toml",
|
||||||
|
"topological-sort",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2205,28 +2236,6 @@ dependencies = [
|
|||||||
"autocfg",
|
"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]]
|
[[package]]
|
||||||
name = "minifier"
|
name = "minifier"
|
||||||
version = "0.0.41"
|
version = "0.0.41"
|
||||||
@ -2284,7 +2293,7 @@ dependencies = [
|
|||||||
"measureme 9.1.2",
|
"measureme 9.1.2",
|
||||||
"rand 0.8.4",
|
"rand 0.8.4",
|
||||||
"rustc-workspace-hack",
|
"rustc-workspace-hack",
|
||||||
"rustc_version 0.4.0",
|
"rustc_version",
|
||||||
"shell-escape",
|
"shell-escape",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
@ -2347,6 +2356,18 @@ dependencies = [
|
|||||||
"rustc-std-workspace-core",
|
"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]]
|
[[package]]
|
||||||
name = "odht"
|
name = "odht"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -2374,15 +2395,6 @@ version = "0.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "open"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7c283bf0114efea9e42f1a60edea9859e8c47528eae09d01df4b29c1e489cc48"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opener"
|
name = "opener"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -2511,9 +2523,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.11.1"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"instant",
|
"instant",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
@ -2522,9 +2534,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.8.3"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"instant",
|
"instant",
|
||||||
@ -2796,9 +2808,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark"
|
name = "pulldown-cmark"
|
||||||
version = "0.7.2"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca36dea94d187597e104a5c8e4b07576a8a45aa5db48a65e12940d3eb7461f55"
|
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"getopts",
|
"getopts",
|
||||||
@ -2806,17 +2818,6 @@ dependencies = [
|
|||||||
"unicase",
|
"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]]
|
[[package]]
|
||||||
name = "punycode"
|
name = "punycode"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -3085,15 +3086,15 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo",
|
"cargo",
|
||||||
"cargo-util",
|
"cargo-util",
|
||||||
"cargo_metadata 0.12.0",
|
"cargo_metadata 0.14.0",
|
||||||
"clippy_lints",
|
"clippy_lints",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"difference",
|
"difference",
|
||||||
"env_logger 0.7.1",
|
"env_logger 0.9.0",
|
||||||
"futures 0.3.12",
|
"futures 0.3.12",
|
||||||
"heck",
|
"heck",
|
||||||
"home",
|
"home",
|
||||||
"itertools 0.9.0",
|
"itertools 0.10.1",
|
||||||
"jsonrpc-core",
|
"jsonrpc-core",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
@ -3102,7 +3103,7 @@ dependencies = [
|
|||||||
"num_cpus",
|
"num_cpus",
|
||||||
"ordslice",
|
"ordslice",
|
||||||
"racer",
|
"racer",
|
||||||
"rand 0.7.3",
|
"rand 0.8.4",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"rls-analysis",
|
"rls-analysis",
|
||||||
@ -3692,6 +3693,7 @@ dependencies = [
|
|||||||
"rustc_expand",
|
"rustc_expand",
|
||||||
"rustc_feature",
|
"rustc_feature",
|
||||||
"rustc_lexer",
|
"rustc_lexer",
|
||||||
|
"rustc_lint_defs",
|
||||||
"rustc_parse",
|
"rustc_parse",
|
||||||
"rustc_parse_format",
|
"rustc_parse_format",
|
||||||
"rustc_session",
|
"rustc_session",
|
||||||
@ -3708,6 +3710,7 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
"cstr",
|
"cstr",
|
||||||
"libc",
|
"libc",
|
||||||
|
"libloading",
|
||||||
"measureme 10.0.0",
|
"measureme 10.0.0",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"rustc_arena",
|
"rustc_arena",
|
||||||
@ -3728,7 +3731,6 @@ dependencies = [
|
|||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"snap",
|
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3741,10 +3743,11 @@ dependencies = [
|
|||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
"object",
|
"object 0.26.2",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc_apfloat",
|
"rustc_apfloat",
|
||||||
|
"rustc_arena",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
"rustc_attr",
|
"rustc_attr",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
@ -3763,7 +3766,9 @@ dependencies = [
|
|||||||
"rustc_symbol_mangling",
|
"rustc_symbol_mangling",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"snap",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
"thorin-dwp",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3823,7 +3828,6 @@ dependencies = [
|
|||||||
name = "rustc_driver"
|
name = "rustc_driver"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
|
||||||
"libc",
|
"libc",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
"rustc_ast_pretty",
|
"rustc_ast_pretty",
|
||||||
@ -3837,6 +3841,7 @@ dependencies = [
|
|||||||
"rustc_hir_pretty",
|
"rustc_hir_pretty",
|
||||||
"rustc_interface",
|
"rustc_interface",
|
||||||
"rustc_lint",
|
"rustc_lint",
|
||||||
|
"rustc_log",
|
||||||
"rustc_metadata",
|
"rustc_metadata",
|
||||||
"rustc_middle",
|
"rustc_middle",
|
||||||
"rustc_parse",
|
"rustc_parse",
|
||||||
@ -3848,8 +3853,6 @@ dependencies = [
|
|||||||
"rustc_target",
|
"rustc_target",
|
||||||
"rustc_typeck",
|
"rustc_typeck",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
|
||||||
"tracing-tree",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3967,6 +3970,7 @@ dependencies = [
|
|||||||
"arrayvec",
|
"arrayvec",
|
||||||
"rustc_macros",
|
"rustc_macros",
|
||||||
"rustc_serialize",
|
"rustc_serialize",
|
||||||
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3992,6 +3996,7 @@ name = "rustc_interface"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
|
"libloading",
|
||||||
"rustc-rayon",
|
"rustc-rayon",
|
||||||
"rustc-rayon-core",
|
"rustc-rayon-core",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
@ -4090,6 +4095,17 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_log"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"rustc_span",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"tracing-tree",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_macros"
|
name = "rustc_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -4104,7 +4120,7 @@ dependencies = [
|
|||||||
name = "rustc_metadata"
|
name = "rustc_metadata"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libloading",
|
||||||
"odht",
|
"odht",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
"rustc_attr",
|
"rustc_attr",
|
||||||
@ -4124,7 +4140,6 @@ dependencies = [
|
|||||||
"smallvec",
|
"smallvec",
|
||||||
"snap",
|
"snap",
|
||||||
"tracing",
|
"tracing",
|
||||||
"winapi",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4297,6 +4312,7 @@ dependencies = [
|
|||||||
name = "rustc_plugin_impl"
|
name = "rustc_plugin_impl"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"libloading",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
"rustc_hir",
|
"rustc_hir",
|
||||||
@ -4590,15 +4606,6 @@ dependencies = [
|
|||||||
"tracing",
|
"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]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -4616,7 +4623,7 @@ dependencies = [
|
|||||||
"expect-test",
|
"expect-test",
|
||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
"minifier",
|
"minifier",
|
||||||
"pulldown-cmark 0.8.0",
|
"pulldown-cmark",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"rustdoc-json-types",
|
"rustdoc-json-types",
|
||||||
@ -5006,7 +5013,7 @@ dependencies = [
|
|||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"object",
|
"object 0.26.2",
|
||||||
"panic_abort",
|
"panic_abort",
|
||||||
"panic_unwind",
|
"panic_unwind",
|
||||||
"profiler_builtins",
|
"profiler_builtins",
|
||||||
@ -5070,9 +5077,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "structopt"
|
name = "structopt"
|
||||||
version = "0.3.16"
|
version = "0.3.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
|
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@ -5081,9 +5088,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "structopt-derive"
|
name = "structopt-derive"
|
||||||
version = "0.4.9"
|
version = "0.4.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
|
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
@ -5123,9 +5130,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "synstructure"
|
||||||
version = "0.12.4"
|
version = "0.12.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -5262,24 +5269,36 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.20"
|
version = "1.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
|
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.20"
|
version = "1.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"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]]
|
[[package]]
|
||||||
name = "thread_local"
|
name = "thread_local"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -5393,6 +5412,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "topological-sort"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa7c7f42dea4b1b99439786f5633aeb9c14c1b53f75e282803c2ec2ad545873c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -5401,9 +5426,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.28"
|
version = "0.1.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8"
|
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@ -5413,9 +5438,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.17"
|
version = "0.1.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4f915eb6abf914599c200260efced9203504c4c37380af10cdf3b7d36970650"
|
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -5442,49 +5467,34 @@ dependencies = [
|
|||||||
"tracing-core",
|
"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]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.2.16"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96"
|
checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.12.1",
|
"ansi_term 0.12.1",
|
||||||
"chrono",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"matchers",
|
"matchers",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
"tracing-serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-tree"
|
name = "tracing-tree"
|
||||||
version = "0.1.9"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1712b40907f8d9bc2bc66763ab61dec914b7123d7149e59feb0d4e2a95fc4967"
|
checksum = "3ce989c9962c7f61fe084dd4a230eec784649dfc2392467c790007c3a6e134e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.12.1",
|
"ansi_term 0.12.1",
|
||||||
"atty",
|
"atty",
|
||||||
"termcolor",
|
"tracing-core",
|
||||||
"tracing",
|
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
346
RELEASES.md
346
RELEASES.md
@ -1,3 +1,184 @@
|
|||||||
|
Version 1.59.0 (2022-02-24)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Language
|
||||||
|
--------
|
||||||
|
|
||||||
|
- [Stabilize default arguments for const generics][90207]
|
||||||
|
- [Stabilize destructuring assignment][90521]
|
||||||
|
- [Relax private in public lint on generic bounds and where clauses of trait impls][90586]
|
||||||
|
- [Stabilize asm! and global_asm! for x86, x86_64, ARM, Aarch64, and RISC-V][91728]
|
||||||
|
|
||||||
|
Compiler
|
||||||
|
--------
|
||||||
|
|
||||||
|
- [Stabilize new symbol mangling format, leaving it opt-in (-Csymbol-mangling-version=v0)][90128]
|
||||||
|
- [Emit LLVM optimization remarks when enabled with `-Cremark`][90833]
|
||||||
|
- [Fix sparc64 ABI for aggregates with floating point members][91003]
|
||||||
|
- [Warn when a `#[test]`-like built-in attribute macro is present multiple times.][91172]
|
||||||
|
- [Add support for riscv64gc-unknown-freebsd][91284]
|
||||||
|
- [Stabilize `-Z emit-future-incompat` as `--json future-incompat`][91535]
|
||||||
|
- [Soft disable incremental compilation][94124]
|
||||||
|
|
||||||
|
This release disables incremental compilation, unless the user has explicitly
|
||||||
|
opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable.
|
||||||
|
This is due to a known and relatively frequently occurring bug in incremental
|
||||||
|
compilation, which causes builds to issue internal compiler errors. This
|
||||||
|
particular bug is already fixed on nightly, but that fix has not yet rolled out
|
||||||
|
to stable and is deemed too risky for a direct stable backport.
|
||||||
|
|
||||||
|
As always, we encourage users to test with nightly and report bugs so that we
|
||||||
|
can track failures and fix issues earlier.
|
||||||
|
|
||||||
|
See [94124] for more details.
|
||||||
|
|
||||||
|
[94124]: https://github.com/rust-lang/rust/issues/94124
|
||||||
|
|
||||||
|
Libraries
|
||||||
|
---------
|
||||||
|
|
||||||
|
- [Remove unnecessary bounds for some Hash{Map,Set} methods][91593]
|
||||||
|
|
||||||
|
Stabilized APIs
|
||||||
|
---------------
|
||||||
|
|
||||||
|
- [`std::thread::available_parallelism`][available_parallelism]
|
||||||
|
- [`Result::copied`][result-copied]
|
||||||
|
- [`Result::cloned`][result-cloned]
|
||||||
|
- [`arch::asm!`][asm]
|
||||||
|
- [`arch::global_asm!`][global_asm]
|
||||||
|
- [`ops::ControlFlow::is_break`][is_break]
|
||||||
|
- [`ops::ControlFlow::is_continue`][is_continue]
|
||||||
|
- [`TryFrom<char> for u8`][try_from_char_u8]
|
||||||
|
- [`char::TryFromCharError`][try_from_char_err]
|
||||||
|
implementing `Clone`, `Debug`, `Display`, `PartialEq`, `Copy`, `Eq`, `Error`
|
||||||
|
- [`iter::zip`][zip]
|
||||||
|
- [`NonZeroU8::is_power_of_two`][is_power_of_two8]
|
||||||
|
- [`NonZeroU16::is_power_of_two`][is_power_of_two16]
|
||||||
|
- [`NonZeroU32::is_power_of_two`][is_power_of_two32]
|
||||||
|
- [`NonZeroU64::is_power_of_two`][is_power_of_two64]
|
||||||
|
- [`NonZeroU128::is_power_of_two`][is_power_of_two128]
|
||||||
|
- [`DoubleEndedIterator for ToLowercase`][lowercase]
|
||||||
|
- [`DoubleEndedIterator for ToUppercase`][uppercase]
|
||||||
|
- [`TryFrom<&mut [T]> for [T; N]`][tryfrom_ref_arr]
|
||||||
|
- [`UnwindSafe for Once`][unwindsafe_once]
|
||||||
|
- [`RefUnwindSafe for Once`][refunwindsafe_once]
|
||||||
|
- [armv8 neon intrinsics for aarch64][stdarch/1266]
|
||||||
|
|
||||||
|
Const-stable:
|
||||||
|
|
||||||
|
- [`mem::MaybeUninit::as_ptr`][muninit_ptr]
|
||||||
|
- [`mem::MaybeUninit::assume_init`][muninit_init]
|
||||||
|
- [`mem::MaybeUninit::assume_init_ref`][muninit_init_ref]
|
||||||
|
- [`ffi::CStr::from_bytes_with_nul_unchecked`][cstr_from_bytes]
|
||||||
|
|
||||||
|
Cargo
|
||||||
|
-----
|
||||||
|
|
||||||
|
- [Stabilize the `strip` profile option][cargo/10088]
|
||||||
|
- [Stabilize future-incompat-report][cargo/10165]
|
||||||
|
- [Support abbreviating `--release` as `-r`][cargo/10133]
|
||||||
|
- [Support `term.quiet` configuration][cargo/10152]
|
||||||
|
- [Remove `--host` from cargo {publish,search,login}][cargo/10145]
|
||||||
|
|
||||||
|
Compatibility Notes
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- [Refactor weak symbols in std::sys::unix][90846]
|
||||||
|
This may add new, versioned, symbols when building with a newer glibc, as the
|
||||||
|
standard library uses weak linkage rather than dynamically attempting to load
|
||||||
|
certain symbols at runtime.
|
||||||
|
- [Deprecate crate_type and crate_name nested inside `#![cfg_attr]`][83744]
|
||||||
|
This adds a future compatibility lint to supporting the use of cfg_attr
|
||||||
|
wrapping either crate_type or crate_name specification within Rust files;
|
||||||
|
it is recommended that users migrate to setting the equivalent command line
|
||||||
|
flags.
|
||||||
|
- [Remove effect of `#[no_link]` attribute on name resolution][92034]
|
||||||
|
This may expose new names, leading to conflicts with preexisting names in a
|
||||||
|
given namespace and a compilation failure.
|
||||||
|
- [Cargo will document libraries before binaries.][cargo/10172]
|
||||||
|
- [Respect doc=false in dependencies, not just the root crate][cargo/10201]
|
||||||
|
- [Weaken guarantee around advancing underlying iterators in zip][83791]
|
||||||
|
- [Make split_inclusive() on an empty slice yield an empty output][89825]
|
||||||
|
- [Update std::env::temp_dir to use GetTempPath2 on Windows when available.][89999]
|
||||||
|
- [unreachable! was updated to match other formatting macro behavior on Rust 2021][92137]
|
||||||
|
|
||||||
|
Internal Changes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
These changes provide no direct user facing benefits, but represent significant
|
||||||
|
improvements to the internals and overall performance of rustc
|
||||||
|
and related tools.
|
||||||
|
|
||||||
|
- [Fix many cases of normalization-related ICEs][91255]
|
||||||
|
- [Replace dominators algorithm with simple Lengauer-Tarjan][85013]
|
||||||
|
- [Store liveness in interval sets for region inference][90637]
|
||||||
|
|
||||||
|
- [Remove `in_band_lifetimes` from the compiler and standard library, in preparation for removing this
|
||||||
|
unstable feature.][91867]
|
||||||
|
|
||||||
|
[91867]: https://github.com/rust-lang/rust/issues/91867
|
||||||
|
[83744]: https://github.com/rust-lang/rust/pull/83744/
|
||||||
|
[83791]: https://github.com/rust-lang/rust/pull/83791/
|
||||||
|
[85013]: https://github.com/rust-lang/rust/pull/85013/
|
||||||
|
[89825]: https://github.com/rust-lang/rust/pull/89825/
|
||||||
|
[89999]: https://github.com/rust-lang/rust/pull/89999/
|
||||||
|
[90128]: https://github.com/rust-lang/rust/pull/90128/
|
||||||
|
[90207]: https://github.com/rust-lang/rust/pull/90207/
|
||||||
|
[90521]: https://github.com/rust-lang/rust/pull/90521/
|
||||||
|
[90586]: https://github.com/rust-lang/rust/pull/90586/
|
||||||
|
[90637]: https://github.com/rust-lang/rust/pull/90637/
|
||||||
|
[90833]: https://github.com/rust-lang/rust/pull/90833/
|
||||||
|
[90846]: https://github.com/rust-lang/rust/pull/90846/
|
||||||
|
[91003]: https://github.com/rust-lang/rust/pull/91003/
|
||||||
|
[91172]: https://github.com/rust-lang/rust/pull/91172/
|
||||||
|
[91255]: https://github.com/rust-lang/rust/pull/91255/
|
||||||
|
[91284]: https://github.com/rust-lang/rust/pull/91284/
|
||||||
|
[91535]: https://github.com/rust-lang/rust/pull/91535/
|
||||||
|
[91593]: https://github.com/rust-lang/rust/pull/91593/
|
||||||
|
[91728]: https://github.com/rust-lang/rust/pull/91728/
|
||||||
|
[91878]: https://github.com/rust-lang/rust/pull/91878/
|
||||||
|
[91896]: https://github.com/rust-lang/rust/pull/91896/
|
||||||
|
[91926]: https://github.com/rust-lang/rust/pull/91926/
|
||||||
|
[91984]: https://github.com/rust-lang/rust/pull/91984/
|
||||||
|
[92020]: https://github.com/rust-lang/rust/pull/92020/
|
||||||
|
[92034]: https://github.com/rust-lang/rust/pull/92034/
|
||||||
|
[92483]: https://github.com/rust-lang/rust/pull/92483/
|
||||||
|
[cargo/10088]: https://github.com/rust-lang/cargo/pull/10088/
|
||||||
|
[cargo/10133]: https://github.com/rust-lang/cargo/pull/10133/
|
||||||
|
[cargo/10145]: https://github.com/rust-lang/cargo/pull/10145/
|
||||||
|
[cargo/10152]: https://github.com/rust-lang/cargo/pull/10152/
|
||||||
|
[cargo/10165]: https://github.com/rust-lang/cargo/pull/10165/
|
||||||
|
[cargo/10172]: https://github.com/rust-lang/cargo/pull/10172/
|
||||||
|
[cargo/10201]: https://github.com/rust-lang/cargo/pull/10201/
|
||||||
|
[cargo/10269]: https://github.com/rust-lang/cargo/pull/10269/
|
||||||
|
|
||||||
|
[cstr_from_bytes]: https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_bytes_with_nul_unchecked
|
||||||
|
[muninit_ptr]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr
|
||||||
|
[muninit_init]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init
|
||||||
|
[muninit_init_ref]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
|
||||||
|
[unwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-UnwindSafe
|
||||||
|
[refunwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-RefUnwindSafe
|
||||||
|
[tryfrom_ref_arr]: https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html#impl-TryFrom%3C%26%27_%20mut%20%5BT%5D%3E
|
||||||
|
[lowercase]: https://doc.rust-lang.org/stable/std/char/struct.ToLowercase.html#impl-DoubleEndedIterator
|
||||||
|
[uppercase]: https://doc.rust-lang.org/stable/std/char/struct.ToUppercase.html#impl-DoubleEndedIterator
|
||||||
|
[try_from_char_err]: https://doc.rust-lang.org/stable/std/char/struct.TryFromCharError.html
|
||||||
|
[available_parallelism]: https://doc.rust-lang.org/stable/std/thread/fn.available_parallelism.html
|
||||||
|
[result-copied]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.copied
|
||||||
|
[result-cloned]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.cloned
|
||||||
|
[asm]: https://doc.rust-lang.org/stable/core/arch/macro.asm.html
|
||||||
|
[global_asm]: https://doc.rust-lang.org/stable/core/arch/macro.global_asm.html
|
||||||
|
[is_break]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_break
|
||||||
|
[is_continue]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_continue
|
||||||
|
[try_from_char_u8]: https://doc.rust-lang.org/stable/std/primitive.char.html#impl-TryFrom%3Cchar%3E
|
||||||
|
[zip]: https://doc.rust-lang.org/stable/std/iter/fn.zip.html
|
||||||
|
[is_power_of_two8]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU8.html#method.is_power_of_two
|
||||||
|
[is_power_of_two16]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU16.html#method.is_power_of_two
|
||||||
|
[is_power_of_two32]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU32.html#method.is_power_of_two
|
||||||
|
[is_power_of_two64]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU64.html#method.is_power_of_two
|
||||||
|
[is_power_of_two128]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU128.html#method.is_power_of_two
|
||||||
|
[stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266
|
||||||
|
|
||||||
Version 1.58.1 (2022-01-19)
|
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 wrong error message displayed when some imports are missing][91254]
|
||||||
* [Fix rustfmt not formatting generated files from stdin][92912]
|
* [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
|
[91254]: https://github.com/rust-lang/rust/pull/91254
|
||||||
[92912]: https://github.com/rust-lang/rust/pull/92912
|
[92912]: https://github.com/rust-lang/rust/pull/92912
|
||||||
[clippy/8075]: https://github.com/rust-lang/rust-clippy/pull/8075
|
[clippy/8075]: https://github.com/rust-lang/rust-clippy/pull/8075
|
||||||
@ -58,7 +239,6 @@ Stabilized APIs
|
|||||||
- [`Option::unwrap_unchecked`]
|
- [`Option::unwrap_unchecked`]
|
||||||
- [`Result::unwrap_unchecked`]
|
- [`Result::unwrap_unchecked`]
|
||||||
- [`Result::unwrap_err_unchecked`]
|
- [`Result::unwrap_err_unchecked`]
|
||||||
- [`NonZero{unsigned}::is_power_of_two`]
|
|
||||||
- [`File::options`]
|
- [`File::options`]
|
||||||
|
|
||||||
These APIs are now usable in const contexts:
|
These APIs are now usable in const contexts:
|
||||||
@ -71,10 +251,6 @@ These APIs are now usable in const contexts:
|
|||||||
- [`Duration::checked_mul`]
|
- [`Duration::checked_mul`]
|
||||||
- [`Duration::saturating_mul`]
|
- [`Duration::saturating_mul`]
|
||||||
- [`Duration::checked_div`]
|
- [`Duration::checked_div`]
|
||||||
- [`MaybeUninit::as_ptr`]
|
|
||||||
- [`MaybeUninit::as_mut_ptr`]
|
|
||||||
- [`MaybeUninit::assume_init`]
|
|
||||||
- [`MaybeUninit::assume_init_ref`]
|
|
||||||
|
|
||||||
Cargo
|
Cargo
|
||||||
-----
|
-----
|
||||||
@ -115,19 +291,14 @@ and related tools.
|
|||||||
[87467]: https://github.com/rust-lang/rust/pull/87467/
|
[87467]: https://github.com/rust-lang/rust/pull/87467/
|
||||||
[87704]: https://github.com/rust-lang/rust/pull/87704/
|
[87704]: https://github.com/rust-lang/rust/pull/87704/
|
||||||
[88041]: https://github.com/rust-lang/rust/pull/88041/
|
[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/
|
[88447]: https://github.com/rust-lang/rust/pull/88447/
|
||||||
[88601]: https://github.com/rust-lang/rust/pull/88601/
|
[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/
|
[89062]: https://github.com/rust-lang/rust/pull/89062/
|
||||||
[89174]: https://github.com/rust-lang/rust/pull/89174/
|
[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/
|
[89551]: https://github.com/rust-lang/rust/pull/89551/
|
||||||
[89558]: https://github.com/rust-lang/rust/pull/89558/
|
[89558]: https://github.com/rust-lang/rust/pull/89558/
|
||||||
[89580]: https://github.com/rust-lang/rust/pull/89580/
|
[89580]: https://github.com/rust-lang/rust/pull/89580/
|
||||||
[89652]: https://github.com/rust-lang/rust/pull/89652/
|
[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/
|
[90041]: https://github.com/rust-lang/rust/pull/90041/
|
||||||
[90058]: https://github.com/rust-lang/rust/pull/90058/
|
[90058]: https://github.com/rust-lang/rust/pull/90058/
|
||||||
[90104]: https://github.com/rust-lang/rust/pull/90104/
|
[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/
|
[90733]: https://github.com/rust-lang/rust/pull/90733/
|
||||||
[90833]: https://github.com/rust-lang/rust/pull/90833/
|
[90833]: https://github.com/rust-lang/rust/pull/90833/
|
||||||
[90846]: https://github.com/rust-lang/rust/pull/90846/
|
[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/
|
[91026]: https://github.com/rust-lang/rust/pull/91026/
|
||||||
[91207]: https://github.com/rust-lang/rust/pull/91207/
|
[91207]: https://github.com/rust-lang/rust/pull/91207/
|
||||||
[91255]: https://github.com/rust-lang/rust/pull/91255/
|
[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/10082]: https://github.com/rust-lang/cargo/pull/10082/
|
||||||
[cargo/10107]: https://github.com/rust-lang/cargo/pull/10107/
|
[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
|
[`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
|
[`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_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
|
[`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
|
[`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::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)
|
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]
|
- [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]
|
- [Accept curly-brace macros in expressions, like `m!{ .. }.method()` and `m!{ .. }?`.][88690]
|
||||||
- [Allow panicking in constant evaluation.][89508]
|
- [Allow panicking in constant evaluation.][89508]
|
||||||
|
- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200]
|
||||||
|
|
||||||
Compiler
|
Compiler
|
||||||
--------
|
--------
|
||||||
@ -254,6 +398,9 @@ Cargo
|
|||||||
Compatibility notes
|
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
|
Internal changes
|
||||||
----------------
|
----------------
|
||||||
These changes provide no direct user facing benefits, but represent significant
|
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]
|
- [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/
|
[86191]: https://github.com/rust-lang/rust/pull/86191/
|
||||||
[87220]: https://github.com/rust-lang/rust/pull/87220/
|
[87220]: https://github.com/rust-lang/rust/pull/87220/
|
||||||
[87260]: https://github.com/rust-lang/rust/pull/87260/
|
[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/
|
[88321]: https://github.com/rust-lang/rust/pull/88321/
|
||||||
[88529]: https://github.com/rust-lang/rust/pull/88529/
|
[88529]: https://github.com/rust-lang/rust/pull/88529/
|
||||||
[88690]: https://github.com/rust-lang/rust/pull/88690/
|
[88690]: https://github.com/rust-lang/rust/pull/88690/
|
||||||
@ -421,8 +568,6 @@ and related tools.
|
|||||||
as well as rustdoc.
|
as well as rustdoc.
|
||||||
|
|
||||||
[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
|
[`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
|
[`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
|
[`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
|
[`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#86183]: https://github.com/rust-lang/rust/pull/86183
|
||||||
[rust#87385]: https://github.com/rust-lang/rust/pull/87385
|
[rust#87385]: https://github.com/rust-lang/rust/pull/87385
|
||||||
[rust#88100]: https://github.com/rust-lang/rust/pull/88100
|
[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#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#88069]: https://github.com/rust-lang/rust/pull/88069
|
||||||
[rust#87472]: https://github.com/rust-lang/rust/pull/87472
|
[rust#87472]: https://github.com/rust-lang/rust/pull/87472
|
||||||
[rust#87699]: https://github.com/rust-lang/rust/pull/87699
|
[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#87580]: https://github.com/rust-lang/rust/pull/87580
|
||||||
[rust#83342]: https://github.com/rust-lang/rust/pull/83342
|
[rust#83342]: https://github.com/rust-lang/rust/pull/83342
|
||||||
[rust#83093]: https://github.com/rust-lang/rust/pull/83093
|
[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#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#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#81363]: https://github.com/rust-lang/rust/pull/81363
|
||||||
[rust#84111]: https://github.com/rust-lang/rust/pull/84111
|
[rust#84111]: https://github.com/rust-lang/rust/pull/84111
|
||||||
[rust#85769]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720
|
[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#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#81825]: https://github.com/rust-lang/rust/pull/81825#issuecomment-808406918
|
||||||
[rust#88019]: https://github.com/rust-lang/rust/pull/88019
|
[rust#88019]: https://github.com/rust-lang/rust/pull/88019
|
||||||
[rust#87666]: https://github.com/rust-lang/rust/pull/87666
|
[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
|
[86294]: https://github.com/rust-lang/rust/pull/86294
|
||||||
[86858]: https://github.com/rust-lang/rust/pull/86858
|
[86858]: https://github.com/rust-lang/rust/pull/86858
|
||||||
[86761]: https://github.com/rust-lang/rust/pull/86761
|
[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
|
[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
|
[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
|
[83918]: https://github.com/rust-lang/rust/pull/83918
|
||||||
[79965]: https://github.com/rust-lang/rust/pull/79965
|
[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/9663]: https://github.com/rust-lang/cargo/pull/9663
|
||||||
[cargo/9675]: https://github.com/rust-lang/cargo/pull/9675
|
[cargo/9675]: https://github.com/rust-lang/cargo/pull/9675
|
||||||
[cargo/9550]: https://github.com/rust-lang/cargo/pull/9550
|
[cargo/9550]: https://github.com/rust-lang/cargo/pull/9550
|
||||||
[cargo/9680]: https://github.com/rust-lang/cargo/pull/9680
|
[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
|
[`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
|
[`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
|
[`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_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::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
|
[`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
|
[`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
|
[`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
|
[`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
|
[85574]: https://github.com/rust-lang/rust/issues/85574
|
||||||
[86831]: https://github.com/rust-lang/rust/issues/86831
|
[86831]: https://github.com/rust-lang/rust/issues/86831
|
||||||
[86063]: https://github.com/rust-lang/rust/issues/86063
|
[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
|
[79608]: https://github.com/rust-lang/rust/pull/79608
|
||||||
[84988]: https://github.com/rust-lang/rust/pull/84988
|
[84988]: https://github.com/rust-lang/rust/pull/84988
|
||||||
[84701]: https://github.com/rust-lang/rust/pull/84701
|
[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_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_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
|
[`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::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_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
|
[`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
|
[80053]: https://github.com/rust-lang/rust/pull/80053
|
||||||
[79502]: https://github.com/rust-lang/rust/pull/79502
|
[79502]: https://github.com/rust-lang/rust/pull/79502
|
||||||
[75180]: https://github.com/rust-lang/rust/pull/75180
|
[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
|
[81521]: https://github.com/rust-lang/rust/pull/81521
|
||||||
[80968]: https://github.com/rust-lang/rust/pull/80968
|
[80968]: https://github.com/rust-lang/rust/pull/80968
|
||||||
[80959]: https://github.com/rust-lang/rust/pull/80959
|
[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`]: 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`]: 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
|
[`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_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
|
[`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
|
[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/
|
[74869]: https://github.com/rust-lang/rust/pull/74869/
|
||||||
[73858]: https://github.com/rust-lang/rust/pull/73858/
|
[73858]: https://github.com/rust-lang/rust/pull/73858/
|
||||||
[75716]: https://github.com/rust-lang/rust/pull/75716/
|
[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/
|
[75560]: https://github.com/rust-lang/rust/pull/75560/
|
||||||
[75568]: https://github.com/rust-lang/rust/pull/75568/
|
[75568]: https://github.com/rust-lang/rust/pull/75568/
|
||||||
[75366]: https://github.com/rust-lang/rust/pull/75366/
|
[75366]: https://github.com/rust-lang/rust/pull/75366/
|
||||||
@ -1826,7 +1934,6 @@ Internal Only
|
|||||||
[73583]: https://github.com/rust-lang/rust/pull/73583/
|
[73583]: https://github.com/rust-lang/rust/pull/73583/
|
||||||
[73084]: https://github.com/rust-lang/rust/pull/73084/
|
[73084]: https://github.com/rust-lang/rust/pull/73084/
|
||||||
[73197]: https://github.com/rust-lang/rust/pull/73197/
|
[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/8456]: https://github.com/rust-lang/cargo/pull/8456/
|
||||||
[cargo/8478]: https://github.com/rust-lang/cargo/pull/8478/
|
[cargo/8478]: https://github.com/rust-lang/cargo/pull/8478/
|
||||||
[cargo/8485]: https://github.com/rust-lang/cargo/pull/8485/
|
[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
|
[`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_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
|
[`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
|
[`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
|
[`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
|
[`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
|
- [Visibility modifiers (e.g. `pub`) are now syntactically allowed on trait items and
|
||||||
enum variants.][66183] These are still rejected semantically, but
|
enum variants.][66183] These are still rejected semantically, but
|
||||||
can be seen and parsed by procedural macros and conditional compilation.
|
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
|
Compiler
|
||||||
--------
|
--------
|
||||||
@ -2679,6 +2790,7 @@ Compatibility Notes
|
|||||||
|
|
||||||
[54733]: https://github.com/rust-lang/rust/pull/54733/
|
[54733]: https://github.com/rust-lang/rust/pull/54733/
|
||||||
[61351]: https://github.com/rust-lang/rust/pull/61351/
|
[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/
|
[67255]: https://github.com/rust-lang/rust/pull/67255/
|
||||||
[66661]: https://github.com/rust-lang/rust/pull/66661/
|
[66661]: https://github.com/rust-lang/rust/pull/66661/
|
||||||
[66771]: https://github.com/rust-lang/rust/pull/66771/
|
[66771]: https://github.com/rust-lang/rust/pull/66771/
|
||||||
@ -2815,7 +2927,6 @@ Compatibility Notes
|
|||||||
[63803]: https://github.com/rust-lang/rust/pull/63803/
|
[63803]: https://github.com/rust-lang/rust/pull/63803/
|
||||||
[cargo/7450]: https://github.com/rust-lang/cargo/pull/7450/
|
[cargo/7450]: https://github.com/rust-lang/cargo/pull/7450/
|
||||||
[cargo/7507]: https://github.com/rust-lang/cargo/pull/7507/
|
[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/
|
[cargo/7333]: https://github.com/rust-lang/cargo/pull/7333/
|
||||||
[(rfc 2008)]: https://rust-lang.github.io/rfcs/2008-non-exhaustive.html
|
[(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
|
[`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/
|
[63786]: https://github.com/rust-lang/rust/pull/63786/
|
||||||
[63827]: https://github.com/rust-lang/rust/pull/63827/
|
[63827]: https://github.com/rust-lang/rust/pull/63827/
|
||||||
[63834]: https://github.com/rust-lang/rust/pull/63834/
|
[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/
|
[64010]: https://github.com/rust-lang/rust/pull/64010/
|
||||||
[64028]: https://github.com/rust-lang/rust/pull/64028/
|
[64028]: https://github.com/rust-lang/rust/pull/64028/
|
||||||
[64334]: https://github.com/rust-lang/rust/pull/64334/
|
[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
|
[`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
|
[`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
|
[`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
|
[`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
|
[`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
|
[`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
|
- [Libtest no longer creates a new thread for each test when
|
||||||
`--test-threads=1`. It also runs the tests in deterministic order][56243]
|
`--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
|
[56243]: https://github.com/rust-lang/rust/pull/56243
|
||||||
[56303]: https://github.com/rust-lang/rust/pull/56303/
|
[56303]: https://github.com/rust-lang/rust/pull/56303/
|
||||||
[56351]: https://github.com/rust-lang/rust/pull/56351/
|
[56351]: https://github.com/rust-lang/rust/pull/56351/
|
||||||
@ -4082,7 +4184,6 @@ Cargo
|
|||||||
|
|
||||||
[52813]: https://github.com/rust-lang/rust/pull/52813/
|
[52813]: https://github.com/rust-lang/rust/pull/52813/
|
||||||
[53218]: https://github.com/rust-lang/rust/pull/53218/
|
[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/
|
[54057]: https://github.com/rust-lang/rust/pull/54057/
|
||||||
[54240]: https://github.com/rust-lang/rust/pull/54240/
|
[54240]: https://github.com/rust-lang/rust/pull/54240/
|
||||||
[54430]: https://github.com/rust-lang/rust/pull/54430/
|
[54430]: https://github.com/rust-lang/rust/pull/54430/
|
||||||
@ -4204,7 +4305,6 @@ Misc
|
|||||||
[53044]: https://github.com/rust-lang/rust/pull/53044/
|
[53044]: https://github.com/rust-lang/rust/pull/53044/
|
||||||
[53165]: https://github.com/rust-lang/rust/pull/53165/
|
[53165]: https://github.com/rust-lang/rust/pull/53165/
|
||||||
[53611]: https://github.com/rust-lang/rust/pull/53611/
|
[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/
|
[53236]: https://github.com/rust-lang/rust/pull/53236/
|
||||||
[53272]: https://github.com/rust-lang/rust/pull/53272/
|
[53272]: https://github.com/rust-lang/rust/pull/53272/
|
||||||
[53370]: https://github.com/rust-lang/rust/pull/53370/
|
[53370]: https://github.com/rust-lang/rust/pull/53370/
|
||||||
@ -4212,7 +4312,6 @@ Misc
|
|||||||
[53774]: https://github.com/rust-lang/rust/pull/53774/
|
[53774]: https://github.com/rust-lang/rust/pull/53774/
|
||||||
[53822]: https://github.com/rust-lang/rust/pull/53822/
|
[53822]: https://github.com/rust-lang/rust/pull/53822/
|
||||||
[54057]: https://github.com/rust-lang/rust/pull/54057/
|
[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/
|
[54404]: https://github.com/rust-lang/rust/pull/54404/
|
||||||
[cargo/5877]: https://github.com/rust-lang/cargo/pull/5877/
|
[cargo/5877]: https://github.com/rust-lang/cargo/pull/5877/
|
||||||
[cargo/5878]: https://github.com/rust-lang/cargo/pull/5878/
|
[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/
|
[52330]: https://github.com/rust-lang/rust/pull/52330/
|
||||||
[52354]: https://github.com/rust-lang/rust/pull/52354/
|
[52354]: https://github.com/rust-lang/rust/pull/52354/
|
||||||
[52402]: https://github.com/rust-lang/rust/pull/52402/
|
[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/
|
[52197]: https://github.com/rust-lang/rust/pull/52197/
|
||||||
[51807]: https://github.com/rust-lang/rust/pull/51807/
|
[51807]: https://github.com/rust-lang/rust/pull/51807/
|
||||||
[51899]: https://github.com/rust-lang/rust/pull/51899/
|
[51899]: https://github.com/rust-lang/rust/pull/51899/
|
||||||
[51912]: https://github.com/rust-lang/rust/pull/51912/
|
[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/
|
[51619]: https://github.com/rust-lang/rust/pull/51619/
|
||||||
[51656]: https://github.com/rust-lang/rust/pull/51656/
|
[51656]: https://github.com/rust-lang/rust/pull/51656/
|
||||||
[51178]: https://github.com/rust-lang/rust/pull/51178/
|
[51178]: https://github.com/rust-lang/rust/pull/51178/
|
||||||
@ -4465,7 +4562,6 @@ Compatibility Notes
|
|||||||
[50855]: https://github.com/rust-lang/rust/pull/50855/
|
[50855]: https://github.com/rust-lang/rust/pull/50855/
|
||||||
[51050]: https://github.com/rust-lang/rust/pull/51050/
|
[51050]: https://github.com/rust-lang/rust/pull/51050/
|
||||||
[51196]: https://github.com/rust-lang/rust/pull/51196/
|
[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/
|
[51241]: https://github.com/rust-lang/rust/pull/51241/
|
||||||
[51276]: https://github.com/rust-lang/rust/pull/51276/
|
[51276]: https://github.com/rust-lang/rust/pull/51276/
|
||||||
[51298]: https://github.com/rust-lang/rust/pull/51298/
|
[51298]: https://github.com/rust-lang/rust/pull/51298/
|
||||||
@ -4646,15 +4742,12 @@ Compatibility Notes
|
|||||||
[49664]: https://github.com/rust-lang/rust/pull/49664/
|
[49664]: https://github.com/rust-lang/rust/pull/49664/
|
||||||
[49699]: https://github.com/rust-lang/rust/pull/49699/
|
[49699]: https://github.com/rust-lang/rust/pull/49699/
|
||||||
[49707]: https://github.com/rust-lang/rust/pull/49707/
|
[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/
|
[49896]: https://github.com/rust-lang/rust/pull/49896/
|
||||||
[49968]: https://github.com/rust-lang/rust/pull/49968/
|
[49968]: https://github.com/rust-lang/rust/pull/49968/
|
||||||
[50163]: https://github.com/rust-lang/rust/pull/50163
|
[50163]: https://github.com/rust-lang/rust/pull/50163
|
||||||
[50177]: https://github.com/rust-lang/rust/pull/50177/
|
[50177]: https://github.com/rust-lang/rust/pull/50177/
|
||||||
[50378]: https://github.com/rust-lang/rust/pull/50378/
|
[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/
|
[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/5335]: https://github.com/rust-lang/cargo/pull/5335/
|
||||||
[cargo/5359]: https://github.com/rust-lang/cargo/pull/5359/
|
[cargo/5359]: https://github.com/rust-lang/cargo/pull/5359/
|
||||||
[cargo/5360]: https://github.com/rust-lang/cargo/pull/5360/
|
[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
|
[47813]: https://github.com/rust-lang/rust/pull/47813
|
||||||
[48056]: https://github.com/rust-lang/rust/pull/48056
|
[48056]: https://github.com/rust-lang/rust/pull/48056
|
||||||
[48125]: https://github.com/rust-lang/rust/pull/48125
|
[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
|
[48235]: https://github.com/rust-lang/rust/pull/48235
|
||||||
[48274]: https://github.com/rust-lang/rust/pull/48274
|
[48274]: https://github.com/rust-lang/rust/pull/48274
|
||||||
[48281]: https://github.com/rust-lang/rust/pull/48281
|
[48281]: https://github.com/rust-lang/rust/pull/48281
|
||||||
@ -4873,10 +4965,7 @@ Compatibility Notes
|
|||||||
[48978]: https://github.com/rust-lang/rust/pull/48978
|
[48978]: https://github.com/rust-lang/rust/pull/48978
|
||||||
[49101]: https://github.com/rust-lang/rust/pull/49101
|
[49101]: https://github.com/rust-lang/rust/pull/49101
|
||||||
[49109]: https://github.com/rust-lang/rust/pull/49109
|
[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
|
[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
|
[49255]: https://github.com/rust-lang/rust/pull/49255
|
||||||
[49299]: https://github.com/rust-lang/rust/pull/49299
|
[49299]: https://github.com/rust-lang/rust/pull/49299
|
||||||
[49305]: https://github.com/rust-lang/rust/pull/49305
|
[49305]: https://github.com/rust-lang/rust/pull/49305
|
||||||
@ -5123,7 +5212,6 @@ Compatibility Notes
|
|||||||
[44884]: https://github.com/rust-lang/rust/pull/44884
|
[44884]: https://github.com/rust-lang/rust/pull/44884
|
||||||
[45198]: https://github.com/rust-lang/rust/pull/45198
|
[45198]: https://github.com/rust-lang/rust/pull/45198
|
||||||
[45506]: https://github.com/rust-lang/rust/pull/45506
|
[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
|
[45990]: https://github.com/rust-lang/rust/pull/45990
|
||||||
[46012]: https://github.com/rust-lang/rust/pull/46012
|
[46012]: https://github.com/rust-lang/rust/pull/46012
|
||||||
[46077]: https://github.com/rust-lang/rust/pull/46077
|
[46077]: https://github.com/rust-lang/rust/pull/46077
|
||||||
@ -5135,7 +5223,6 @@ Compatibility Notes
|
|||||||
[46671]: https://github.com/rust-lang/rust/pull/46671
|
[46671]: https://github.com/rust-lang/rust/pull/46671
|
||||||
[46713]: https://github.com/rust-lang/rust/pull/46713
|
[46713]: https://github.com/rust-lang/rust/pull/46713
|
||||||
[46735]: https://github.com/rust-lang/rust/pull/46735
|
[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
|
[46760]: https://github.com/rust-lang/rust/pull/46760
|
||||||
[46798]: https://github.com/rust-lang/rust/pull/46798
|
[46798]: https://github.com/rust-lang/rust/pull/46798
|
||||||
[46828]: https://github.com/rust-lang/rust/pull/46828
|
[46828]: https://github.com/rust-lang/rust/pull/46828
|
||||||
@ -5306,7 +5393,6 @@ Compatibility Notes
|
|||||||
|
|
||||||
|
|
||||||
[42526]: https://github.com/rust-lang/rust/pull/42526
|
[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
|
[43716]: https://github.com/rust-lang/rust/pull/43716
|
||||||
[43949]: https://github.com/rust-lang/rust/pull/43949
|
[43949]: https://github.com/rust-lang/rust/pull/43949
|
||||||
[44015]: https://github.com/rust-lang/rust/pull/44015
|
[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
|
- [Added `--no-fail-fast` flag to cargo to run all benchmarks regardless of
|
||||||
failure.][cargo/4248]
|
failure.][cargo/4248]
|
||||||
- [Changed the convention around which file is the crate root.][cargo/4259]
|
- [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
|
Compatibility Notes
|
||||||
-------------------
|
-------------------
|
||||||
@ -5580,7 +5664,6 @@ Compatibility Notes
|
|||||||
[cargo/4229]: https://github.com/rust-lang/cargo/pull/4229
|
[cargo/4229]: https://github.com/rust-lang/cargo/pull/4229
|
||||||
[cargo/4248]: https://github.com/rust-lang/cargo/pull/4248
|
[cargo/4248]: https://github.com/rust-lang/cargo/pull/4248
|
||||||
[cargo/4259]: https://github.com/rust-lang/cargo/pull/4259
|
[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
|
[`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::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
|
[`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]
|
- [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]
|
- [Rust now uses the official cross compiler for NetBSD][40612]
|
||||||
- [rustdoc now accepts `#` at the start of files][40828]
|
- [rustdoc now accepts `#` at the start of files][40828]
|
||||||
- [Fixed jemalloc support for musl][41168]
|
- [Fixed jemalloc support for musl][41168]
|
||||||
@ -5908,7 +5990,6 @@ Compatibility Notes
|
|||||||
[38165]: https://github.com/rust-lang/rust/pull/38165
|
[38165]: https://github.com/rust-lang/rust/pull/38165
|
||||||
[39799]: https://github.com/rust-lang/rust/pull/39799
|
[39799]: https://github.com/rust-lang/rust/pull/39799
|
||||||
[39891]: https://github.com/rust-lang/rust/pull/39891
|
[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
|
[40043]: https://github.com/rust-lang/rust/pull/40043
|
||||||
[40241]: https://github.com/rust-lang/rust/pull/40241
|
[40241]: https://github.com/rust-lang/rust/pull/40241
|
||||||
[40338]: https://github.com/rust-lang/rust/pull/40338
|
[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/3691]: https://github.com/rust-lang/cargo/pull/3691
|
||||||
[cargo/3699]: https://github.com/rust-lang/cargo/pull/3699
|
[cargo/3699]: https://github.com/rust-lang/cargo/pull/3699
|
||||||
[cargo/3731]: https://github.com/rust-lang/cargo/pull/3731
|
[cargo/3731]: https://github.com/rust-lang/cargo/pull/3731
|
||||||
[mdbook]: https://crates.io/crates/mdbook
|
|
||||||
[ubook]: https://doc.rust-lang.org/unstable-book/
|
[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
|
* [Ctrl-Z returns from `Stdin.read()` when reading from the console on
|
||||||
Windows][38274]
|
Windows][38274]
|
||||||
* [std: Fix partial writes in `LineWriter`][38062]
|
* [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]
|
* [Use more specific panic message for `&str` slicing errors][38066]
|
||||||
* [`TcpListener::set_only_v6` is deprecated][38304]. This
|
* [`TcpListener::set_only_v6` is deprecated][38304]. This
|
||||||
functionality cannot be achieved in std currently.
|
functionality cannot be achieved in std currently.
|
||||||
@ -6341,7 +6421,7 @@ Compatibility Notes
|
|||||||
[38006]: https://github.com/rust-lang/rust/pull/38006
|
[38006]: https://github.com/rust-lang/rust/pull/38006
|
||||||
[38051]: https://github.com/rust-lang/rust/pull/38051
|
[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/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
|
[38066]: https://github.com/rust-lang/rust/pull/38066
|
||||||
[38069]: https://github.com/rust-lang/rust/pull/38069
|
[38069]: https://github.com/rust-lang/rust/pull/38069
|
||||||
[38131]: https://github.com/rust-lang/rust/pull/38131
|
[38131]: https://github.com/rust-lang/rust/pull/38131
|
||||||
@ -6349,7 +6429,6 @@ Compatibility Notes
|
|||||||
[38274]: https://github.com/rust-lang/rust/pull/38274
|
[38274]: https://github.com/rust-lang/rust/pull/38274
|
||||||
[38304]: https://github.com/rust-lang/rust/pull/38304
|
[38304]: https://github.com/rust-lang/rust/pull/38304
|
||||||
[38313]: https://github.com/rust-lang/rust/pull/38313
|
[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
|
[38327]: https://github.com/rust-lang/rust/pull/38327
|
||||||
[38401]: https://github.com/rust-lang/rust/pull/38401
|
[38401]: https://github.com/rust-lang/rust/pull/38401
|
||||||
[38413]: https://github.com/rust-lang/rust/pull/38413
|
[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/3546]: https://github.com/rust-lang/cargo/pull/3546
|
||||||
[cargo/3557]: https://github.com/rust-lang/cargo/pull/3557
|
[cargo/3557]: https://github.com/rust-lang/cargo/pull/3557
|
||||||
[cargo/3604]: https://github.com/rust-lang/cargo/pull/3604
|
[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)
|
Version 1.15.1 (2017-02-09)
|
||||||
@ -6614,7 +6692,6 @@ Compatibility Notes
|
|||||||
[38192]: https://github.com/rust-lang/rust/pull/38192
|
[38192]: https://github.com/rust-lang/rust/pull/38192
|
||||||
[38279]: https://github.com/rust-lang/rust/pull/38279
|
[38279]: https://github.com/rust-lang/rust/pull/38279
|
||||||
[38835]: https://github.com/rust-lang/rust/pull/38835
|
[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 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 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
|
[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
|
[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
|
[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
|
||||||
[36595]: https://github.com/rust-lang/rust/pull/36595
|
|
||||||
[36692]: https://github.com/rust-lang/rust/pull/36692
|
[36692]: https://github.com/rust-lang/rust/pull/36692
|
||||||
[36767]: https://github.com/rust-lang/rust/pull/36767
|
[36767]: https://github.com/rust-lang/rust/pull/36767
|
||||||
[36794]: https://github.com/rust-lang/rust/pull/36794
|
[36794]: https://github.com/rust-lang/rust/pull/36794
|
||||||
@ -7031,7 +7107,6 @@ Compatibility Notes
|
|||||||
[34623]: https://github.com/rust-lang/rust/pull/34623
|
[34623]: https://github.com/rust-lang/rust/pull/34623
|
||||||
[34923]: https://github.com/rust-lang/rust/pull/34923
|
[34923]: https://github.com/rust-lang/rust/pull/34923
|
||||||
[34942]: https://github.com/rust-lang/rust/pull/34942
|
[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
|
[35021]: https://github.com/rust-lang/rust/pull/35021
|
||||||
[35048]: https://github.com/rust-lang/rust/pull/35048
|
[35048]: https://github.com/rust-lang/rust/pull/35048
|
||||||
[35074]: https://github.com/rust-lang/rust/pull/35074
|
[35074]: https://github.com/rust-lang/rust/pull/35074
|
||||||
@ -7088,7 +7163,6 @@ Compatibility Notes
|
|||||||
[36586]: https://github.com/rust-lang/rust/pull/36586
|
[36586]: https://github.com/rust-lang/rust/pull/36586
|
||||||
[36592]: https://github.com/rust-lang/rust/pull/36592
|
[36592]: https://github.com/rust-lang/rust/pull/36592
|
||||||
[36631]: https://github.com/rust-lang/rust/pull/36631
|
[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
|
[36721]: https://github.com/rust-lang/rust/pull/36721
|
||||||
[36727]: https://github.com/rust-lang/rust/pull/36727
|
[36727]: https://github.com/rust-lang/rust/pull/36727
|
||||||
[36730]: https://github.com/rust-lang/rust/pull/36730
|
[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/3205]: https://github.com/rust-lang/cargo/pull/3205
|
||||||
[cargo/3241]: https://github.com/rust-lang/cargo/pull/3241
|
[cargo/3241]: https://github.com/rust-lang/cargo/pull/3241
|
||||||
[cargo/3242]: https://github.com/rust-lang/cargo/pull/3242
|
[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
|
[`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
|
[`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
|
[`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].
|
targets can be specified together. [RFC 1361].
|
||||||
* [The environment variables `CARGO_TARGET_ROOT`, `RUSTC`, and
|
* [The environment variables `CARGO_TARGET_ROOT`, `RUSTC`, and
|
||||||
`RUSTDOC` take precedence over the `build.target-dir`,
|
`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
|
* [The child process tree is killed on Windows when Cargo is
|
||||||
killed][1.8ck].
|
killed][1.8ck].
|
||||||
* [The `build.target` configuration value sets the target platform,
|
* [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.8ck]: https://github.com/rust-lang/cargo/pull/2370
|
||||||
[1.8ct]: https://github.com/rust-lang/cargo/pull/2335
|
[1.8ct]: https://github.com/rust-lang/cargo/pull/2335
|
||||||
[1.8cu]: https://github.com/rust-lang/rust/pull/31390
|
[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.8cv]: https://github.com/rust-lang/rust/pull/30998
|
||||||
[1.8h]: https://github.com/rust-lang/rust/pull/31460
|
[1.8h]: https://github.com/rust-lang/rust/pull/31460
|
||||||
[1.8l]: https://github.com/rust-lang/rust/pull/31668
|
[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
|
* The compiler gained many new extended error descriptions, which can
|
||||||
be accessed with the `--explain` flag.
|
be accessed with the `--explain` flag.
|
||||||
* The `dropck` pass, which checks that destructors can't access
|
* 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
|
soundness holes, and as such will cause some previously-compiling
|
||||||
code to no longer build.
|
code to no longer build.
|
||||||
* `rustc` now uses [LLVM to write archive files where possible][ar].
|
* `rustc` now uses [LLVM to write archive files where possible][ar].
|
||||||
Eventually this will eliminate the compiler's dependency on the ar
|
Eventually this will eliminate the compiler's dependency on the ar
|
||||||
utility.
|
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).
|
supported FreeBSD on x86_64).
|
||||||
* The [`unused_mut`][lum], [`unconditional_recursion`][lur],
|
* The [`unused_mut`][lum], [`unconditional_recursion`][lur],
|
||||||
[`improper_ctypes`][lic], and [`negate_unsigned`][lnu] lints are
|
[`improper_ctypes`][lic], and [`negate_unsigned`][lnu] lints are
|
||||||
@ -9056,7 +9129,7 @@ Misc
|
|||||||
[ar]: https://github.com/rust-lang/rust/pull/26926
|
[ar]: https://github.com/rust-lang/rust/pull/26926
|
||||||
[b14]: https://static.rust-lang.org/dist/rust-beta-x86_64-pc-windows-msvc.msi
|
[b14]: https://static.rust-lang.org/dist/rust-beta-x86_64-pc-windows-msvc.msi
|
||||||
[dms]: https://github.com/rust-lang/rust/pull/26241
|
[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
|
[dropckrfc]: https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md
|
||||||
[ds]: https://github.com/rust-lang/rust/pull/26818
|
[ds]: https://github.com/rust-lang/rust/pull/26818
|
||||||
[dst1]: http://doc.rust-lang.org/nightly/std/mem/fn.size_of_val.html
|
[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
|
[dst3]: https://github.com/rust-lang/rust/pull/27351
|
||||||
[e]: https://github.com/rust-lang/rust/pull/24793
|
[e]: https://github.com/rust-lang/rust/pull/24793
|
||||||
[f]: https://github.com/rust-lang/rust/pull/26588
|
[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
|
[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
|
[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
|
[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
|
[iegm]: http://doc.rust-lang.org/nightly/std/io/struct.Error.html#method.get_mut
|
||||||
@ -9337,7 +9409,7 @@ Misc
|
|||||||
to rustc.
|
to rustc.
|
||||||
* [Android executables are always position independent][pie].
|
* [Android executables are always position independent][pie].
|
||||||
* [The `drop_with_repr_extern` lint warns about mixing `repr(C)`
|
* [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
|
[`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
|
[`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
|
[`BinaryHeap`]: https://doc.rust-lang.org/nightly/std/collections/struct.BinaryHeap.html
|
||||||
[ll]: https://github.com/rust-lang/rust/pull/26022
|
[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
|
[`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)
|
Version 1.0.0 (2015-05-15)
|
||||||
========================
|
========================
|
||||||
@ -9420,7 +9492,7 @@ Language
|
|||||||
property: generic code cannot behave differently for different type
|
property: generic code cannot behave differently for different type
|
||||||
arguments except in minor ways.
|
arguments except in minor ways.
|
||||||
* The `unsafe_destructor` feature is now deprecated in favor of the
|
* 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.
|
code.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
@ -9428,7 +9500,7 @@ Libraries
|
|||||||
|
|
||||||
* The `thread_local` module [has been renamed to `std::thread`][th].
|
* The `thread_local` module [has been renamed to `std::thread`][th].
|
||||||
* The methods of `IteratorExt` [have been moved to the `Iterator`
|
* 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
|
* Several traits that implement Rust's conventions for type
|
||||||
conversions, `AsMut`, `AsRef`, `From`, and `Into` have been
|
conversions, `AsMut`, `AsRef`, `From`, and `Into` have been
|
||||||
[centralized in the `std::convert` module][con].
|
[centralized in the `std::convert` module][con].
|
||||||
@ -9447,7 +9519,7 @@ Libraries
|
|||||||
* [In method resolution, object methods are resolved before inherent
|
* [In method resolution, object methods are resolved before inherent
|
||||||
methods][meth].
|
methods][meth].
|
||||||
* [`String::from_str` has been deprecated in favor of the `From` impl,
|
* [`String::from_str` has been deprecated in favor of the `From` impl,
|
||||||
`String::from`][sf].
|
`String::from`][24517].
|
||||||
* [`io::Error` implements `Sync`][ios].
|
* [`io::Error` implements `Sync`][ios].
|
||||||
* [The `words` method on `&str` has been replaced with
|
* [The `words` method on `&str` has been replaced with
|
||||||
`split_whitespace`][sw], to avoid answering the tricky question, 'what is
|
`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
|
[con]: https://github.com/rust-lang/rust/pull/23875
|
||||||
[cr]: https://github.com/rust-lang/rust/pull/23419
|
[cr]: https://github.com/rust-lang/rust/pull/23419
|
||||||
[fe]: https://github.com/rust-lang/rust/pull/23879
|
[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
|
[inv]: https://github.com/rust-lang/rust/pull/23938
|
||||||
[ios]: https://github.com/rust-lang/rust/pull/24133
|
[ios]: https://github.com/rust-lang/rust/pull/24133
|
||||||
[lex]: https://github.com/rust-lang/rfcs/blob/master/text/0879-small-base-lexing.md
|
[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
|
[meth]: https://github.com/rust-lang/rust/pull/24056
|
||||||
[pat]: https://github.com/rust-lang/rfcs/blob/master/text/0528-string-patterns.md
|
[pat]: https://github.com/rust-lang/rfcs/blob/master/text/0528-string-patterns.md
|
||||||
[po]: https://github.com/rust-lang/rust/pull/24270
|
[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
|
[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
|
[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
|
[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
|
[conversion]: https://github.com/rust-lang/rfcs/pull/529
|
||||||
[num-traits]: https://github.com/rust-lang/rust/pull/23549
|
[num-traits]: https://github.com/rust-lang/rust/pull/23549
|
||||||
[index-value]: https://github.com/rust-lang/rust/pull/23601
|
[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
|
[ci-compare]: https://gist.github.com/brson/a30a77836fbec057cbee
|
||||||
[fn-inherit]: https://github.com/rust-lang/rust/pull/23282
|
[fn-inherit]: https://github.com/rust-lang/rust/pull/23282
|
||||||
[fn-blanket]: https://github.com/rust-lang/rust/pull/23895
|
[fn-blanket]: https://github.com/rust-lang/rust/pull/23895
|
||||||
|
@ -1,25 +1,32 @@
|
|||||||
// Configure jemalloc as the `global_allocator` when configured. This is
|
// A note about jemalloc: rustc uses jemalloc when built for CI and
|
||||||
// so that we use the sized deallocation apis jemalloc provides
|
// distribution. The obvious way to do this is with the `#[global_allocator]`
|
||||||
// (namely `sdallocx`).
|
// 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
|
// Instead, we use a lower-level mechanism. rustc is linked with jemalloc in a
|
||||||
// ensure that we use a consistent allocator across the rustc <-> llvm boundary
|
// way such that jemalloc's implementation of `malloc`, `free`, etc., override
|
||||||
#[cfg(feature = "jemalloc")]
|
// the libc allocator's implementation. This means that Rust's `System`
|
||||||
#[global_allocator]
|
// allocator, which calls `libc::malloc()` et al., is actually calling into
|
||||||
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
// 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")]
|
#[cfg(feature = "tikv-jemalloc-sys")]
|
||||||
use tikv_jemalloc_sys as jemalloc_sys;
|
use tikv_jemalloc_sys as jemalloc_sys;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Pull in jemalloc when enabled.
|
// See the comment at the top of this file for an explanation of this.
|
||||||
//
|
|
||||||
// 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).
|
|
||||||
#[cfg(feature = "tikv-jemalloc-sys")]
|
#[cfg(feature = "tikv-jemalloc-sys")]
|
||||||
{
|
{
|
||||||
use std::os::raw::{c_int, c_void};
|
use std::os::raw::{c_int, c_void};
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![feature(iter_zip)]
|
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -332,10 +332,7 @@ pub type GenericBounds = Vec<GenericBound>;
|
|||||||
pub enum ParamKindOrd {
|
pub enum ParamKindOrd {
|
||||||
Lifetime,
|
Lifetime,
|
||||||
Type,
|
Type,
|
||||||
// `unordered` is only `true` if `sess.unordered_const_ty_params()`
|
Const,
|
||||||
// returns true. Specifically, if it's only `min_const_generics`, it will still require
|
|
||||||
// ordering consts after types.
|
|
||||||
Const { unordered: bool },
|
|
||||||
// `Infer` is not actually constructed directly from the AST, but is implicitly constructed
|
// `Infer` is not actually constructed directly from the AST, but is implicitly constructed
|
||||||
// during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
|
// during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
|
||||||
Infer,
|
Infer,
|
||||||
@ -346,11 +343,7 @@ impl Ord for ParamKindOrd {
|
|||||||
use ParamKindOrd::*;
|
use ParamKindOrd::*;
|
||||||
let to_int = |v| match v {
|
let to_int = |v| match v {
|
||||||
Lifetime => 0,
|
Lifetime => 0,
|
||||||
Infer | Type | Const { unordered: true } => 1,
|
Infer | Type | Const => 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,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
to_int(*self).cmp(&to_int(*other))
|
to_int(*self).cmp(&to_int(*other))
|
||||||
@ -517,6 +510,10 @@ pub struct Crate {
|
|||||||
pub attrs: Vec<Attribute>,
|
pub attrs: Vec<Attribute>,
|
||||||
pub items: Vec<P<Item>>,
|
pub items: Vec<P<Item>>,
|
||||||
pub span: Span,
|
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.
|
/// Possible values inside of compile-time attribute lists.
|
||||||
@ -1979,7 +1976,7 @@ pub enum InlineAsmRegOrRegClass {
|
|||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||||
pub struct InlineAsmOptions: u8 {
|
pub struct InlineAsmOptions: u16 {
|
||||||
const PURE = 1 << 0;
|
const PURE = 1 << 0;
|
||||||
const NOMEM = 1 << 1;
|
const NOMEM = 1 << 1;
|
||||||
const READONLY = 1 << 2;
|
const READONLY = 1 << 2;
|
||||||
@ -1988,6 +1985,7 @@ bitflags::bitflags! {
|
|||||||
const NOSTACK = 1 << 5;
|
const NOSTACK = 1 << 5;
|
||||||
const ATT_SYNTAX = 1 << 6;
|
const ATT_SYNTAX = 1 << 6;
|
||||||
const RAW = 1 << 7;
|
const RAW = 1 << 7;
|
||||||
|
const MAY_UNWIND = 1 << 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::ptr::P;
|
use super::ptr::P;
|
||||||
use super::token::Nonterminal;
|
use super::token::Nonterminal;
|
||||||
use super::tokenstream::LazyTokenStream;
|
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::{AssocItem, Expr, ForeignItem, Item, Local, MacCallStmt};
|
||||||
use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
|
use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
|
||||||
use super::{AttrVec, Attribute, Stmt, StmtKind};
|
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
|
// These ast nodes only support inert attributes, so they don't
|
||||||
// store tokens (since nothing can observe them)
|
// store tokens (since nothing can observe them)
|
||||||
derive_has_attrs_no_tokens! {
|
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
|
// These AST nodes don't support attributes, but can
|
||||||
|
@ -136,15 +136,15 @@ impl Attribute {
|
|||||||
|
|
||||||
pub fn value_str(&self) -> Option<Symbol> {
|
pub fn value_str(&self) -> Option<Symbol> {
|
||||||
match self.kind {
|
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,
|
AttrKind::DocComment(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
|
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
AttrKind::Normal(ref item, _) => match item.meta(self.span) {
|
AttrKind::Normal(ref item, _) => match item.meta_kind() {
|
||||||
Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
|
Some(MetaItemKind::List(list)) => Some(list),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
AttrKind::DocComment(..) => None,
|
AttrKind::DocComment(..) => None,
|
||||||
@ -228,6 +228,10 @@ impl AttrItem {
|
|||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||||
|
Some(MetaItemKind::from_mac_args(&self.args)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Attribute {
|
impl Attribute {
|
||||||
@ -242,7 +246,7 @@ impl Attribute {
|
|||||||
match self.kind {
|
match self.kind {
|
||||||
AttrKind::DocComment(.., data) => Some(data),
|
AttrKind::DocComment(.., data) => Some(data),
|
||||||
AttrKind::Normal(ref item, _) if item.path == sym::doc => {
|
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,
|
_ => 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 {
|
pub fn tokens(&self) -> AttrAnnotatedTokenStream {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
AttrKind::Normal(_, ref tokens) => tokens
|
AttrKind::Normal(_, ref tokens) => tokens
|
||||||
@ -436,6 +447,16 @@ impl MetaItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MetaItemKind {
|
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 {
|
pub fn mac_args(&self, span: Span) -> MacArgs {
|
||||||
match self {
|
match self {
|
||||||
MetaItemKind::Word => MacArgs::Empty,
|
MetaItemKind::Word => MacArgs::Empty,
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(iter_zip)]
|
|
||||||
#![feature(label_break_value)]
|
#![feature(label_break_value)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! A `MutVisitor` represents an AST modification; it accepts an AST piece and
|
//! 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.
|
//! that walks over an AST and modifies it.
|
||||||
//!
|
//!
|
||||||
//! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on
|
//! 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::map_in_place::MapInPlace;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_data_structures::thin_vec::ThinVec;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use smallvec::{smallvec, Array, SmallVec};
|
use smallvec::{smallvec, Array, SmallVec};
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use std::{panic, process, ptr};
|
use std::{panic, ptr};
|
||||||
|
|
||||||
pub trait ExpectOne<A: Array> {
|
pub trait ExpectOne<A: Array> {
|
||||||
fn expect_one(self, err: &'static str) -> A::Item;
|
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
|
/// 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_`
|
/// 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`.
|
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||||
pub fn visit_clobber<T, F>(t: &mut T, f: F)
|
pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) {
|
||||||
where
|
|
||||||
F: FnOnce(T) -> T,
|
|
||||||
{
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// Safe because `t` is used in a read-only fashion by `read()` before
|
// Safe because `t` is used in a read-only fashion by `read()` before
|
||||||
// being overwritten by `write()`.
|
// being overwritten by `write()`.
|
||||||
let old_t = ptr::read(t);
|
let old_t = ptr::read(t);
|
||||||
let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t)))
|
let new_t =
|
||||||
.unwrap_or_else(|_| process::abort());
|
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);
|
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);
|
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) {
|
pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
|
||||||
visit_clobber(krate, |Crate { attrs, items, span }| {
|
let Crate { attrs, items, span, id, is_placeholder: _ } = krate;
|
||||||
let item_vis =
|
vis.visit_id(id);
|
||||||
Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None };
|
visit_attrs(attrs, vis);
|
||||||
let item = P(Item {
|
items.flat_map_in_place(|item| vis.flat_map_item(item));
|
||||||
ident: Ident::empty(),
|
vis.visit_span(span);
|
||||||
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");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutates one item into possibly many items.
|
// 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);
|
vis.visit_span(&mut visibility.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some value for the AST node that is valid but possibly meaningless.
|
||||||
|
pub trait DummyAstNode {
|
||||||
|
fn dummy() -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DummyAstNode for Option<T> {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
P(DummyAstNode::dummy())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DummyAstNode for ThinVec<T> {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Item {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Item {
|
||||||
|
attrs: Default::default(),
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
span: Default::default(),
|
||||||
|
vis: Visibility {
|
||||||
|
kind: VisibilityKind::Public,
|
||||||
|
span: Default::default(),
|
||||||
|
tokens: Default::default(),
|
||||||
|
},
|
||||||
|
ident: Ident::empty(),
|
||||||
|
kind: ItemKind::ExternCrate(None),
|
||||||
|
tokens: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Expr {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Expr {
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
kind: ExprKind::Err,
|
||||||
|
span: Default::default(),
|
||||||
|
attrs: Default::default(),
|
||||||
|
tokens: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Ty {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Ty {
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
kind: TyKind::Err,
|
||||||
|
span: Default::default(),
|
||||||
|
tokens: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Pat {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Pat {
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
kind: PatKind::Wild,
|
||||||
|
span: Default::default(),
|
||||||
|
tokens: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Stmt {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Block {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Block {
|
||||||
|
stmts: Default::default(),
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
rules: BlockCheckMode::Default,
|
||||||
|
span: Default::default(),
|
||||||
|
tokens: Default::default(),
|
||||||
|
could_be_bare_literal: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyAstNode for Crate {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Crate {
|
||||||
|
attrs: Default::default(),
|
||||||
|
items: Default::default(),
|
||||||
|
span: Default::default(),
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
is_placeholder: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,12 +35,12 @@ impl LitKind {
|
|||||||
LitKind::Bool(symbol == kw::True)
|
LitKind::Bool(symbol == kw::True)
|
||||||
}
|
}
|
||||||
token::Byte => {
|
token::Byte => {
|
||||||
return unescape_byte(&symbol.as_str())
|
return unescape_byte(symbol.as_str())
|
||||||
.map(LitKind::Byte)
|
.map(LitKind::Byte)
|
||||||
.map_err(|_| LitError::LexerError);
|
.map_err(|_| LitError::LexerError);
|
||||||
}
|
}
|
||||||
token::Char => {
|
token::Char => {
|
||||||
return unescape_char(&symbol.as_str())
|
return unescape_char(symbol.as_str())
|
||||||
.map(LitKind::Char)
|
.map(LitKind::Char)
|
||||||
.map_err(|_| LitError::LexerError);
|
.map_err(|_| LitError::LexerError);
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ impl LitKind {
|
|||||||
// string in the token.
|
// string in the token.
|
||||||
let s = symbol.as_str();
|
let s = symbol.as_str();
|
||||||
let symbol =
|
let symbol =
|
||||||
if s.contains(&['\\', '\r'][..]) {
|
if s.contains(&['\\', '\r']) {
|
||||||
let mut buf = String::with_capacity(s.len());
|
let mut buf = String::with_capacity(s.len());
|
||||||
let mut error = Ok(());
|
let mut error = Ok(());
|
||||||
unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| {
|
unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| {
|
||||||
|
@ -211,6 +211,9 @@ pub trait Visitor<'ast>: Sized {
|
|||||||
fn visit_pat_field(&mut self, fp: &'ast PatField) {
|
fn visit_pat_field(&mut self, fp: &'ast PatField) {
|
||||||
walk_pat_field(self, fp)
|
walk_pat_field(self, fp)
|
||||||
}
|
}
|
||||||
|
fn visit_crate(&mut self, krate: &'ast Crate) {
|
||||||
|
walk_crate(self, krate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -49,11 +49,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
|
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
|
||||||
.emit();
|
.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();
|
let mut clobber_abis = FxHashMap::default();
|
||||||
if let Some(asm_arch) = asm_arch {
|
if let Some(asm_arch) = asm_arch {
|
||||||
for (abi_name, abi_span) in &asm.clobber_abis {
|
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) => {
|
Ok(abi) => {
|
||||||
// If the abi was already in the list, emit an error
|
// If the abi was already in the list, emit an error
|
||||||
match clobber_abis.get(&abi) {
|
match clobber_abis.get(&abi) {
|
||||||
|
@ -2,7 +2,6 @@ use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
|
|||||||
use rustc_ast::{AttrVec, Block, BlockCheckMode, Expr, Local, LocalKind, Stmt, StmtKind};
|
use rustc_ast::{AttrVec, Block, BlockCheckMode, Expr, Local, LocalKind, Stmt, StmtKind};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::Ident;
|
|
||||||
use rustc_span::{sym, DesugaringKind};
|
use rustc_span::{sym, DesugaringKind};
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -39,8 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
let hir_id = self.lower_node_id(s.id);
|
let hir_id = self.lower_node_id(s.id);
|
||||||
match &local.kind {
|
match &local.kind {
|
||||||
LocalKind::InitElse(init, els) => {
|
LocalKind::InitElse(init, els) => {
|
||||||
let (s, e) = self.lower_let_else(hir_id, local, init, els, tail);
|
let e = self.lower_let_else(hir_id, local, init, els, tail);
|
||||||
stmts.push(s);
|
|
||||||
expr = Some(e);
|
expr = Some(e);
|
||||||
// remaining statements are in let-else expression
|
// remaining statements are in let-else expression
|
||||||
break;
|
break;
|
||||||
@ -125,36 +123,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
init: &Expr,
|
init: &Expr,
|
||||||
els: &Block,
|
els: &Block,
|
||||||
tail: &[Stmt],
|
tail: &[Stmt],
|
||||||
) -> (hir::Stmt<'hir>, &'hir hir::Expr<'hir>) {
|
) -> &'hir hir::Expr<'hir> {
|
||||||
let ty = local
|
let ty = local
|
||||||
.ty
|
.ty
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
|
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
|
||||||
let span = self.lower_span(local.span);
|
let span = self.lower_span(local.span);
|
||||||
let span = self.mark_span_with_reason(DesugaringKind::LetElse, span, None);
|
let span = self.mark_span_with_reason(DesugaringKind::LetElse, span, None);
|
||||||
let init = Some(self.lower_expr(init));
|
let init = 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 local_hir_id = self.lower_node_id(local.id);
|
let local_hir_id = self.lower_node_id(local.id);
|
||||||
self.lower_attrs(local_hir_id, &local.attrs);
|
self.lower_attrs(local_hir_id, &local.attrs);
|
||||||
// first statement which basically exists for the type annotation
|
let let_expr = {
|
||||||
let stmt = {
|
let lex = self.arena.alloc(hir::Let {
|
||||||
let local = self.arena.alloc(hir::Local {
|
|
||||||
hir_id: local_hir_id,
|
hir_id: local_hir_id,
|
||||||
|
pat: self.lower_pat(&local.pat),
|
||||||
ty,
|
ty,
|
||||||
pat,
|
|
||||||
init,
|
init,
|
||||||
span,
|
span,
|
||||||
source: hir::LocalSource::Normal,
|
|
||||||
});
|
});
|
||||||
let kind = hir::StmtKind::Local(local);
|
self.arena.alloc(self.expr(span, hir::ExprKind::Let(lex), AttrVec::new()))
|
||||||
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()))
|
|
||||||
};
|
};
|
||||||
let then_expr = {
|
let then_expr = {
|
||||||
let (stmts, expr) = self.lower_stmts(tail);
|
let (stmts, expr) = self.lower_stmts(tail);
|
||||||
@ -165,9 +152,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
let block = self.lower_block(els, false);
|
let block = self.lower_block(els, false);
|
||||||
self.arena.alloc(self.expr_block(block, AttrVec::new()))
|
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);
|
self.alias_attrs(else_expr.hir_id, local_hir_id);
|
||||||
let if_expr = self.arena.alloc(hir::Expr {
|
let if_expr = self.arena.alloc(hir::Expr {
|
||||||
hir_id: self.next_id(),
|
hir_id: stmt_hir_id,
|
||||||
span,
|
span,
|
||||||
kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)),
|
kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)),
|
||||||
});
|
});
|
||||||
@ -180,6 +168,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
(stmt, if_expr)
|
if_expr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ use rustc_errors::struct_span_err;
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::definitions::DefPathData;
|
use rustc_hir::definitions::DefPathData;
|
||||||
use rustc_session::parse::feature_err;
|
|
||||||
use rustc_span::hygiene::ExpnId;
|
use rustc_span::hygiene::ExpnId;
|
||||||
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
|
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
|
||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
@ -35,7 +34,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
}
|
}
|
||||||
ExprKind::Repeat(ref expr, ref count) => {
|
ExprKind::Repeat(ref expr, ref count) => {
|
||||||
let expr = self.lower_expr(expr);
|
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)
|
hir::ExprKind::Repeat(expr, count)
|
||||||
}
|
}
|
||||||
ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
|
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);
|
let ohs = self.lower_expr(ohs);
|
||||||
hir::ExprKind::AddrOf(k, m, ohs)
|
hir::ExprKind::AddrOf(k, m, ohs)
|
||||||
}
|
}
|
||||||
ExprKind::Let(ref pat, ref scrutinee, span) => hir::ExprKind::Let(
|
ExprKind::Let(ref pat, ref scrutinee, span) => {
|
||||||
self.lower_pat(pat),
|
hir::ExprKind::Let(self.arena.alloc(hir::Let {
|
||||||
self.lower_expr(scrutinee),
|
hir_id: self.next_id(),
|
||||||
self.lower_span(span),
|
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) => {
|
ExprKind::If(ref cond, ref then, ref else_opt) => {
|
||||||
self.lower_expr_if(cond, then, else_opt.as_deref())
|
self.lower_expr_if(cond, then, else_opt.as_deref())
|
||||||
}
|
}
|
||||||
@ -130,7 +133,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
hir::AsyncGeneratorKind::Block,
|
hir::AsyncGeneratorKind::Block,
|
||||||
|this| this.with_new_scopes(|this| this.lower_block_expr(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(
|
ExprKind::Closure(
|
||||||
capture_clause,
|
capture_clause,
|
||||||
asyncness,
|
asyncness,
|
||||||
@ -479,8 +490,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
expr: &'hir hir::Expr<'hir>,
|
expr: &'hir hir::Expr<'hir>,
|
||||||
overall_span: Span,
|
overall_span: Span,
|
||||||
) -> &'hir hir::Expr<'hir> {
|
) -> &'hir hir::Expr<'hir> {
|
||||||
let constructor =
|
let constructor = self.arena.alloc(self.expr_lang_item_path(
|
||||||
self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new()));
|
method_span,
|
||||||
|
lang_item,
|
||||||
|
ThinVec::new(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,8 +599,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
// `future::from_generator`:
|
// `future::from_generator`:
|
||||||
let unstable_span =
|
let unstable_span =
|
||||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||||
let gen_future =
|
let gen_future = self.expr_lang_item_path(
|
||||||
self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new());
|
unstable_span,
|
||||||
|
hir::LangItem::FromGenerator,
|
||||||
|
ThinVec::new(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
// `future::from_generator(generator)`:
|
// `future::from_generator(generator)`:
|
||||||
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; 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:
|
/// Desugar `<expr>.await` into:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// match <expr> {
|
/// match ::std::future::IntoFuture::into_future(<expr>) {
|
||||||
/// mut pinned => loop {
|
/// mut pinned => loop {
|
||||||
/// match unsafe { ::std::future::Future::poll(
|
/// match unsafe { ::std::future::Future::poll(
|
||||||
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
|
/// <::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> {
|
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 {
|
match self.generator_kind {
|
||||||
Some(hir::GeneratorKind::Async(_)) => {}
|
Some(hir::GeneratorKind::Async(_)) => {}
|
||||||
Some(hir::GeneratorKind::Gen) | None => {
|
Some(hir::GeneratorKind::Gen) | None => {
|
||||||
@ -623,13 +643,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
err.emit();
|
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(
|
let gen_future_span = self.mark_span_with_reason(
|
||||||
DesugaringKind::Await,
|
DesugaringKind::Await,
|
||||||
await_span,
|
await_span,
|
||||||
self.allow_gen_future.clone(),
|
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_ident = Ident::with_dummy_span(sym::pinned);
|
||||||
let (pinned_pat, pinned_pat_hid) =
|
let (pinned_pat, pinned_pat_hid) =
|
||||||
@ -656,16 +677,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
span,
|
span,
|
||||||
hir::LangItem::PinNewUnchecked,
|
hir::LangItem::PinNewUnchecked,
|
||||||
arena_vec![self; ref_mut_pinned],
|
arena_vec![self; ref_mut_pinned],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
let get_context = self.expr_call_lang_item_fn_mut(
|
let get_context = self.expr_call_lang_item_fn_mut(
|
||||||
gen_future_span,
|
gen_future_span,
|
||||||
hir::LangItem::GetContext,
|
hir::LangItem::GetContext,
|
||||||
arena_vec![self; task_context],
|
arena_vec![self; task_context],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
let call = self.expr_call_lang_item_fn(
|
let call = self.expr_call_lang_item_fn(
|
||||||
span,
|
span,
|
||||||
hir::LangItem::FuturePoll,
|
hir::LangItem::FuturePoll,
|
||||||
arena_vec![self; new_unchecked, get_context],
|
arena_vec![self; new_unchecked, get_context],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
self.arena.alloc(self.expr_unsafe(call))
|
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_pat, x_pat_hid) = self.pat_ident(span, x_ident);
|
||||||
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
|
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
|
||||||
let ready_field = self.single_pat_field(span, x_pat);
|
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 break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||||
let expr_break =
|
let expr_break =
|
||||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
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)
|
self.arm(ready_pat, break_x)
|
||||||
};
|
};
|
||||||
|
|
||||||
// `::std::task::Poll::Pending => {}`
|
// `::std::task::Poll::Pending => {}`
|
||||||
let pending_arm = {
|
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);
|
let empty_block = self.expr_block_empty(span);
|
||||||
self.arm(pending_pat, empty_block)
|
self.arm(pending_pat, empty_block)
|
||||||
};
|
};
|
||||||
@ -709,7 +743,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
let unit = self.expr_unit(span);
|
let unit = self.expr_unit(span);
|
||||||
let yield_expr = self.expr(
|
let yield_expr = self.expr(
|
||||||
span,
|
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(),
|
ThinVec::new(),
|
||||||
);
|
);
|
||||||
let yield_expr = self.arena.alloc(yield_expr);
|
let yield_expr = self.arena.alloc(yield_expr);
|
||||||
@ -746,10 +780,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
// mut pinned => loop { ... }
|
// mut pinned => loop { ... }
|
||||||
let pinned_arm = self.arm(pinned_pat, loop_expr);
|
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 { .. }
|
// 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(
|
fn lower_expr_closure(
|
||||||
@ -914,24 +965,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
self.lower_span(eq_sign_span),
|
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![];
|
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> {
|
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
|
||||||
let e1 = self.lower_expr_mut(e1);
|
let e1 = self.lower_expr_mut(e1);
|
||||||
let e2 = self.lower_expr_mut(e2);
|
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 =
|
let fn_expr =
|
||||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
|
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
|
||||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||||
@ -1178,7 +1212,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
hir::ExprKind::Struct(
|
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,
|
fields,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
@ -1373,6 +1407,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
head_span,
|
head_span,
|
||||||
hir::LangItem::IteratorNext,
|
hir::LangItem::IteratorNext,
|
||||||
arena_vec![self; ref_mut_iter],
|
arena_vec![self; ref_mut_iter],
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
let arms = arena_vec![self; none_arm, some_arm];
|
let arms = arena_vec![self; none_arm, some_arm];
|
||||||
|
|
||||||
@ -1401,6 +1436,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
head_span,
|
head_span,
|
||||||
hir::LangItem::IntoIterIntoIter,
|
hir::LangItem::IntoIterIntoIter,
|
||||||
arena_vec![self; head],
|
arena_vec![self; head],
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1456,6 +1492,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
unstable_span,
|
unstable_span,
|
||||||
hir::LangItem::TryTraitBranch,
|
hir::LangItem::TryTraitBranch,
|
||||||
arena_vec![self; sub_expr],
|
arena_vec![self; sub_expr],
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1612,8 +1649,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: &'hir [hir::Expr<'hir>],
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> hir::Expr<'hir> {
|
) -> 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)
|
self.expr_call_mut(span, path, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1622,8 +1661,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: &'hir [hir::Expr<'hir>],
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> &'hir hir::Expr<'hir> {
|
) -> &'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(
|
fn expr_lang_item_path(
|
||||||
@ -1631,10 +1671,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
attrs: AttrVec,
|
attrs: AttrVec,
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
self.expr(
|
self.expr(
|
||||||
span,
|
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,
|
attrs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -247,12 +247,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
AnonymousLifetimeMode::PassThrough,
|
AnonymousLifetimeMode::PassThrough,
|
||||||
|this, idty| {
|
|this, idty| {
|
||||||
let ret_id = asyncness.opt_return_id();
|
let ret_id = asyncness.opt_return_id();
|
||||||
this.lower_fn_decl(
|
this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
|
||||||
&decl,
|
|
||||||
Some((fn_def_id.to_def_id(), idty)),
|
|
||||||
true,
|
|
||||||
ret_id,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let sig = hir::FnSig {
|
let sig = hir::FnSig {
|
||||||
@ -1264,7 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
|this, idty| {
|
|this, idty| {
|
||||||
this.lower_fn_decl(
|
this.lower_fn_decl(
|
||||||
&sig.decl,
|
&sig.decl,
|
||||||
Some((fn_def_id.to_def_id(), idty)),
|
Some((fn_def_id, idty)),
|
||||||
impl_trait_return_allow,
|
impl_trait_return_allow,
|
||||||
is_async,
|
is_async,
|
||||||
)
|
)
|
||||||
@ -1283,7 +1278,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
|
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);
|
self.error_on_invalid_abi(abi);
|
||||||
abi::Abi::Rust
|
abi::Abi::Rust
|
||||||
})
|
})
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(iter_zip)]
|
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
@ -47,20 +46,19 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::Lrc;
|
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 as hir;
|
||||||
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
|
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
|
||||||
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
|
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
|
||||||
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
||||||
use rustc_hir::intravisit;
|
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_index::vec::{Idx, IndexVec};
|
||||||
use rustc_query_system::ich::StableHashingContext;
|
use rustc_query_system::ich::StableHashingContext;
|
||||||
use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
|
use rustc_session::lint::LintBuffer;
|
||||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
|
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::edition::Edition;
|
|
||||||
use rustc_span::hygiene::ExpnId;
|
use rustc_span::hygiene::ExpnId;
|
||||||
use rustc_span::source_map::{respan, DesugaringKind};
|
use rustc_span::source_map::{respan, DesugaringKind};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
@ -70,10 +68,9 @@ use smallvec::SmallVec;
|
|||||||
use tracing::{debug, trace};
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
macro_rules! arena_vec {
|
macro_rules! arena_vec {
|
||||||
($this:expr; $($x:expr),*) => ({
|
($this:expr; $($x:expr),*) => (
|
||||||
let a = [$($x),*];
|
$this.arena.alloc_from_iter([$($x),*])
|
||||||
$this.arena.alloc_from_iter(std::array::IntoIter::new(a))
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod asm;
|
mod asm;
|
||||||
@ -162,6 +159,7 @@ struct LoweringContext<'a, 'hir: 'a> {
|
|||||||
|
|
||||||
allow_try_trait: Option<Lrc<[Symbol]>>,
|
allow_try_trait: Option<Lrc<[Symbol]>>,
|
||||||
allow_gen_future: Option<Lrc<[Symbol]>>,
|
allow_gen_future: Option<Lrc<[Symbol]>>,
|
||||||
|
allow_into_future: Option<Lrc<[Symbol]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ResolverAstLowering {
|
pub trait ResolverAstLowering {
|
||||||
@ -228,7 +226,7 @@ enum ImplTraitContext<'b, 'a> {
|
|||||||
ReturnPositionOpaqueTy {
|
ReturnPositionOpaqueTy {
|
||||||
/// `DefId` for the parent function, used to look up necessary
|
/// `DefId` for the parent function, used to look up necessary
|
||||||
/// information later.
|
/// information later.
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
},
|
},
|
||||||
@ -320,6 +318,7 @@ pub fn lower_crate<'a, 'hir>(
|
|||||||
in_scope_lifetimes: Vec::new(),
|
in_scope_lifetimes: Vec::new(),
|
||||||
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
||||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||||
|
allow_into_future: Some([sym::into_future][..].into()),
|
||||||
}
|
}
|
||||||
.lower_crate(krate)
|
.lower_crate(krate)
|
||||||
}
|
}
|
||||||
@ -645,31 +644,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
/// parameter while `f` is running (and restored afterwards).
|
/// parameter while `f` is running (and restored afterwards).
|
||||||
fn collect_in_band_defs<T>(
|
fn collect_in_band_defs<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_def_id: LocalDefId,
|
f: impl FnOnce(&mut Self) -> T,
|
||||||
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
) -> (Vec<(Span, ParamName)>, T) {
|
||||||
f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
|
let was_collecting = std::mem::replace(&mut self.is_collecting_in_band_lifetimes, true);
|
||||||
) -> (Vec<hir::GenericParam<'hir>>, T) {
|
let len = self.lifetimes_to_define.len();
|
||||||
assert!(!self.is_collecting_in_band_lifetimes);
|
|
||||||
assert!(self.lifetimes_to_define.is_empty());
|
|
||||||
let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
|
|
||||||
|
|
||||||
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
|
let res = f(self);
|
||||||
self.is_collecting_in_band_lifetimes = true;
|
|
||||||
|
|
||||||
let (in_band_ty_params, res) = f(self);
|
let lifetimes_to_define = self.lifetimes_to_define.split_off(len);
|
||||||
|
self.is_collecting_in_band_lifetimes = was_collecting;
|
||||||
self.is_collecting_in_band_lifetimes = false;
|
(lifetimes_to_define, res)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a lifetime into a new generic parameter.
|
/// Converts a lifetime into a new generic parameter.
|
||||||
@ -784,27 +768,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
||||||
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
|
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
|
||||||
) -> (hir::Generics<'hir>, T) {
|
) -> (hir::Generics<'hir>, T) {
|
||||||
let (in_band_defs, (mut lowered_generics, res)) =
|
let (lifetimes_to_define, (mut lowered_generics, impl_trait_defs, res)) = self
|
||||||
self.with_in_scope_lifetime_defs(&generics.params, |this| {
|
.collect_in_band_defs(|this| {
|
||||||
this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
|
this.with_anonymous_lifetime_mode(anonymous_lifetime_mode, |this| {
|
||||||
let mut params = Vec::new();
|
this.with_in_scope_lifetime_defs(&generics.params, |this| {
|
||||||
// Note: it is necessary to lower generics *before* calling `f`.
|
let mut impl_trait_defs = Vec::new();
|
||||||
// When lowering `async fn`, there's a final step when lowering
|
// Note: it is necessary to lower generics *before* calling `f`.
|
||||||
// the return type that assumes that all in-scope lifetimes have
|
// When lowering `async fn`, there's a final step when lowering
|
||||||
// already been added to either `in_scope_lifetimes` or
|
// the return type that assumes that all in-scope lifetimes have
|
||||||
// `lifetimes_to_define`. If we swapped the order of these two,
|
// already been added to either `in_scope_lifetimes` or
|
||||||
// in-band-lifetimes introduced by generics or where-clauses
|
// `lifetimes_to_define`. If we swapped the order of these two,
|
||||||
// wouldn't have been added yet.
|
// in-band-lifetimes introduced by generics or where-clauses
|
||||||
let generics = this.lower_generics_mut(
|
// wouldn't have been added yet.
|
||||||
generics,
|
let generics = this.lower_generics_mut(
|
||||||
ImplTraitContext::Universal(&mut params, this.current_hir_id_owner),
|
generics,
|
||||||
);
|
ImplTraitContext::Universal(
|
||||||
let res = f(this, &mut params);
|
&mut impl_trait_defs,
|
||||||
(params, (generics, res))
|
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);
|
let lowered_generics = lowered_generics.into_generics(self.arena);
|
||||||
(lowered_generics, res)
|
(lowered_generics, res)
|
||||||
@ -1116,7 +1112,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
return GenericArg::Infer(hir::InferArg {
|
return GenericArg::Infer(hir::InferArg {
|
||||||
hir_id: self.lower_node_id(ty.id),
|
hir_id: self.lower_node_id(ty.id),
|
||||||
span: self.lower_span(ty.span),
|
span: self.lower_span(ty.span),
|
||||||
kind: InferKind::Type,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// We parse const arguments as path types as we cannot distinguish them during
|
// 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> {
|
) -> hir::Ty<'hir> {
|
||||||
let id = self.lower_node_id(t.id);
|
let id = self.lower_node_id(t.id);
|
||||||
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
|
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
|
||||||
let ty = self.ty_path(id, t.span, qpath);
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
|
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) => {
|
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::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
|
||||||
TyKind::TraitObject(ref bounds, kind) => {
|
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));
|
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
|
||||||
(bounds, lifetime_bound)
|
(bounds, lifetime_bound)
|
||||||
});
|
});
|
||||||
if kind != TraitObjectSyntax::Dyn {
|
|
||||||
self.maybe_lint_bare_trait(t.span, t.id, false);
|
|
||||||
}
|
|
||||||
hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
|
hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
|
||||||
}
|
}
|
||||||
TyKind::ImplTrait(def_node_id, ref bounds) => {
|
TyKind::ImplTrait(def_node_id, ref bounds) => {
|
||||||
@ -1379,7 +1367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_opaque_impl_trait(
|
fn lower_opaque_impl_trait(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_def_id: Option<DefId>,
|
fn_def_id: Option<LocalDefId>,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
||||||
@ -1451,7 +1439,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
span: lctx.lower_span(span),
|
span: lctx.lower_span(span),
|
||||||
},
|
},
|
||||||
bounds: hir_bounds,
|
bounds: hir_bounds,
|
||||||
impl_trait_fn: fn_def_id,
|
|
||||||
origin,
|
origin,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1521,7 +1508,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_fn_decl(
|
fn lower_fn_decl(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &FnDecl,
|
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,
|
impl_trait_return_allow: bool,
|
||||||
make_ret_async: Option<NodeId>,
|
make_ret_async: Option<NodeId>,
|
||||||
) -> &'hir hir::FnDecl<'hir> {
|
) -> &'hir hir::FnDecl<'hir> {
|
||||||
@ -1579,7 +1566,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
Some((def_id, _)) if impl_trait_return_allow => {
|
Some((def_id, _)) if impl_trait_return_allow => {
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
fn_def_id: def_id,
|
fn_def_id: def_id,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::FnReturn(def_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => ImplTraitContext::disallowed(),
|
_ => ImplTraitContext::disallowed(),
|
||||||
@ -1634,7 +1621,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_async_fn_ret_ty(
|
fn lower_async_fn_ret_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
) -> hir::FnRetTy<'hir> {
|
) -> hir::FnRetTy<'hir> {
|
||||||
debug!(
|
debug!(
|
||||||
@ -1688,18 +1675,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
// this is because the elided lifetimes from the return type
|
// this is because the elided lifetimes from the return type
|
||||||
// should be figured out using the ordinary elision rules, and
|
// should be figured out using the ordinary elision rules, and
|
||||||
// this desugaring achieves that.
|
// 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| {
|
self.with_hir_id_owner(opaque_ty_node_id, |this| {
|
||||||
// We have to be careful to get elision right here. The
|
// We have to be careful to get elision right here. The
|
||||||
// idea is that we create a lifetime parameter for each
|
// 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
|
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
|
||||||
// hence the elision takes place at the fn site.
|
// hence the elision takes place at the fn site.
|
||||||
let future_bound = this
|
let (lifetimes_to_define, future_bound) =
|
||||||
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
|
this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
|
||||||
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
|
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: future_bound={:#?}", future_bound);
|
||||||
|
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define);
|
||||||
|
|
||||||
// Calculate all the lifetimes that should be captured
|
lifetime_params.extend(
|
||||||
// by the opaque type. This should include all in-scope
|
// Output lifetime like `'_`:
|
||||||
// lifetime parameters, including those defined in-band.
|
lifetimes_to_define
|
||||||
//
|
.into_iter()
|
||||||
// Note: this must be done after lowering the output type,
|
.map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))),
|
||||||
// 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);
|
|
||||||
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
|
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
|
||||||
|
|
||||||
let generic_params =
|
let generic_params =
|
||||||
this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
|
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.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let opaque_ty_item = hir::OpaqueTy {
|
let opaque_ty_item = hir::OpaqueTy {
|
||||||
@ -1746,8 +1736,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
span: this.lower_span(span),
|
span: this.lower_span(span),
|
||||||
},
|
},
|
||||||
bounds: arena_vec![this; future_bound],
|
bounds: arena_vec![this; future_bound],
|
||||||
impl_trait_fn: Some(fn_def_id),
|
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("exist ty from async fn def id: {:#?}", opaque_ty_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
|
// For the "output" lifetime parameters, we just want to
|
||||||
// generate `'_`.
|
// generate `'_`.
|
||||||
let mut generic_args = Vec::with_capacity(lifetime_params.len());
|
let generic_args =
|
||||||
generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
|
self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| {
|
||||||
|&(span, hir_name)| {
|
|
||||||
// Input lifetime like `'a` or `'1`:
|
|
||||||
GenericArg::Lifetime(hir::Lifetime {
|
GenericArg::Lifetime(hir::Lifetime {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
span: self.lower_span(span),
|
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
|
// Create the `Foo<...>` reference itself. Note that the `type
|
||||||
// Foo = impl Trait` is, internally, created as a child of the
|
// 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(
|
fn lower_async_fn_output_type_to_future_bound(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> hir::GenericBound<'hir> {
|
) -> hir::GenericBound<'hir> {
|
||||||
// Compute the `T` in `Future<Output = T>` from the return type.
|
// Compute the `T` in `Future<Output = T>` from the return type.
|
||||||
@ -1815,7 +1793,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
// generates.
|
// generates.
|
||||||
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
fn_def_id,
|
fn_def_id,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
};
|
};
|
||||||
self.lower_ty(ty, context)
|
self.lower_ty(ty, context)
|
||||||
}
|
}
|
||||||
@ -1927,7 +1905,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
});
|
});
|
||||||
let param_name = match lt.name {
|
let param_name = match lt.name {
|
||||||
hir::LifetimeName::Param(param_name) => param_name,
|
hir::LifetimeName::Param(param_name) => param_name,
|
||||||
hir::LifetimeName::Implicit
|
hir::LifetimeName::Implicit(_)
|
||||||
| hir::LifetimeName::Underscore
|
| hir::LifetimeName::Underscore
|
||||||
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
|
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
|
||||||
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
|
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||||
@ -2062,6 +2040,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
self.expr_block(block, AttrVec::new())
|
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 {
|
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
|
||||||
self.with_new_scopes(|this| hir::AnonConst {
|
self.with_new_scopes(|this| hir::AnonConst {
|
||||||
hir_id: this.lower_node_id(c.id),
|
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> {
|
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);
|
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> {
|
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);
|
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> {
|
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||||
let field = self.single_pat_field(span, pat);
|
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> {
|
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(
|
fn single_pat_field(
|
||||||
@ -2176,8 +2174,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
fields: &'hir [hir::PatField<'hir>],
|
fields: &'hir [hir::PatField<'hir>],
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> &'hir hir::Pat<'hir> {
|
) -> &'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))
|
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::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,
|
&'s mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
count: usize,
|
count: usize,
|
||||||
|
param_mode: ParamMode,
|
||||||
) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
|
) -> 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 {
|
match self.anonymous_lifetime_mode {
|
||||||
AnonymousLifetimeMode::CreateParameter => {
|
AnonymousLifetimeMode::CreateParameter => {
|
||||||
// We should have emitted E0726 when processing this path above
|
// 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
|
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
|
||||||
// later, at which point a suitable error will be emitted.
|
// later, at which point a suitable error will be emitted.
|
||||||
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
|
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
|
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::Lifetime {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
span: self.lower_span(span),
|
span: self.lower_span(span),
|
||||||
name: hir::LifetimeName::Implicit,
|
name: hir::LifetimeName::Implicit(missing),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2451,17 +2418,12 @@ impl<'hir> GenericArgsCtor<'hir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug")]
|
||||||
fn lifetimes_from_impl_trait_bounds(
|
fn lifetimes_from_impl_trait_bounds(
|
||||||
opaque_ty_id: NodeId,
|
opaque_ty_id: NodeId,
|
||||||
bounds: hir::GenericBounds<'_>,
|
bounds: hir::GenericBounds<'_>,
|
||||||
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
||||||
) -> Vec<(hir::LifetimeName, Span)> {
|
) -> 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
|
// 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.
|
// 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>`.
|
// 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) {
|
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
|
||||||
let name = match lifetime.name {
|
let name = match lifetime.name {
|
||||||
hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
|
hir::LifetimeName::Implicit(_) | hir::LifetimeName::Underscore => {
|
||||||
if self.collect_elided_lifetimes {
|
if self.collect_elided_lifetimes {
|
||||||
// Use `'_` for both implicit and underscore lifetimes in
|
// Use `'_` for both implicit and underscore lifetimes in
|
||||||
// `type Foo<'_> = impl SomeTrait<'_>;`.
|
// `type Foo<'_> = impl SomeTrait<'_>;`.
|
||||||
|
@ -24,7 +24,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
|
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);
|
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) => {
|
PatKind::TupleStruct(ref qself, ref path, ref pats) => {
|
||||||
let qpath = self.lower_qpath(
|
let qpath = self.lower_qpath(
|
||||||
pattern.id,
|
pattern.id,
|
||||||
@ -81,8 +83,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
|
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
|
||||||
break hir::PatKind::Range(
|
break hir::PatKind::Range(
|
||||||
e1.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(e)),
|
e2.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
|
||||||
self.lower_range_end(end, e2.is_some()),
|
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,
|
RangeEnd::Excluded | RangeEnd::Included(_) => hir::RangeEnd::Included,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Matches `'-' lit | lit (cf. parser::Parser::parse_literal_maybe_minus)`,
|
||||||
|
/// or paths for ranges.
|
||||||
|
//
|
||||||
|
// FIXME: do we want to allow `expr -> pattern` conversion to create path expressions?
|
||||||
|
// That means making this work:
|
||||||
|
//
|
||||||
|
// ```rust,ignore (FIXME)
|
||||||
|
// struct S;
|
||||||
|
// macro_rules! m {
|
||||||
|
// ($a:expr) => {
|
||||||
|
// let $a = S;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// m!(S);
|
||||||
|
// ```
|
||||||
|
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> {
|
||||||
|
match expr.kind {
|
||||||
|
ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {}
|
||||||
|
ExprKind::Path(..) if allow_paths => {}
|
||||||
|
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||||
|
_ => {
|
||||||
|
self.diagnostic()
|
||||||
|
.span_err(expr.span, "arbitrary expressions aren't allowed in patterns");
|
||||||
|
return self.arena.alloc(self.expr_err(expr.span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.lower_expr(expr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::GenericArg;
|
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::symbol::Ident;
|
||||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
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) {
|
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
|
||||||
// Do not suggest going from `Trait()` to `Trait<>`
|
// Do not suggest going from `Trait()` to `Trait<>`
|
||||||
if !data.inputs.is_empty() {
|
if !data.inputs.is_empty() {
|
||||||
if let Some(split) = snippet.find('(') {
|
// Suggest replacing `(` and `)` with `<` and `>`
|
||||||
let trait_name = &snippet[0..split];
|
// The snippet may be missing the closing `)`, skip that case
|
||||||
let args = &snippet[split + 1..snippet.len() - 1];
|
if snippet.ends_with(')') {
|
||||||
err.span_suggestion(
|
if let Some(split) = snippet.find('(') {
|
||||||
data.span,
|
let trait_name = &snippet[0..split];
|
||||||
"use angle brackets instead",
|
let args = &snippet[split + 1..snippet.len() - 1];
|
||||||
format!("{}<{}>", trait_name, args),
|
err.span_suggestion(
|
||||||
Applicability::MaybeIncorrect,
|
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 =
|
let has_lifetimes =
|
||||||
generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
|
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.
|
// Note: these spans are used for diagnostics when they can't be inferred.
|
||||||
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
|
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
|
||||||
let elided_lifetime_span = if generic_args.span.is_empty() {
|
let elided_lifetime_span = if generic_args.span.is_empty() {
|
||||||
// If there are no brackets, use the identifier span.
|
// 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() {
|
} else if generic_args.is_empty() {
|
||||||
// If there are brackets, but not generic arguments, then use the opening bracket
|
// If there are brackets, but not generic arguments, then use the opening bracket
|
||||||
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
|
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.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
|
||||||
};
|
};
|
||||||
generic_args.args = self
|
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)
|
.map(GenericArg::Lifetime)
|
||||||
.chain(generic_args.args.into_iter())
|
.chain(generic_args.args.into_iter())
|
||||||
.collect();
|
.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 anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", ");
|
||||||
let no_non_lt_args = generic_args.args.len() == expected_lifetimes;
|
let no_non_lt_args = generic_args.args.len() == expected_lifetimes;
|
||||||
let no_bindings = generic_args.bindings.is_empty();
|
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.
|
// 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 {
|
} else {
|
||||||
// Otherwise we'll insert a `'_, ` right after the opening bracket.
|
// Otherwise we'll insert a `'_, ` right after the opening bracket.
|
||||||
let span = generic_args
|
(false, format!("{}, ", anon_lt_suggestion))
|
||||||
.span
|
|
||||||
.with_lo(generic_args.span.lo() + BytePos(1))
|
|
||||||
.shrink_to_lo();
|
|
||||||
(false, span, format!("{}, ", anon_lt_suggestion))
|
|
||||||
};
|
};
|
||||||
match self.anonymous_lifetime_mode {
|
let insertion_sp = elided_lifetime_span.shrink_to_hi();
|
||||||
// In create-parameter mode we error here because we don't want to support
|
let mut err = struct_span_err!(
|
||||||
// deprecated impl elision in new features like impl elision and `async fn`,
|
self.sess,
|
||||||
// both of which work using the `CreateParameter` mode:
|
path_span,
|
||||||
//
|
E0726,
|
||||||
// impl Foo for std::cell::Ref<u32> // note lack of '_
|
"implicit elided lifetime not allowed here"
|
||||||
// async fn foo(_: std::cell::Ref<u32>) { ... }
|
);
|
||||||
AnonymousLifetimeMode::CreateParameter => {
|
rustc_errors::add_elided_lifetime_in_path_suggestion(
|
||||||
let mut err = struct_span_err!(
|
&self.sess.source_map(),
|
||||||
self.sess,
|
&mut err,
|
||||||
path_span,
|
expected_lifetimes,
|
||||||
E0726,
|
path_span,
|
||||||
"implicit elided lifetime not allowed here"
|
incl_angl_brckt,
|
||||||
);
|
insertion_sp,
|
||||||
rustc_errors::add_elided_lifetime_in_path_suggestion(
|
suggestion,
|
||||||
&self.sess.source_map(),
|
);
|
||||||
&mut err,
|
err.note("assuming a `'static` lifetime...");
|
||||||
expected_lifetimes,
|
err.emit();
|
||||||
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,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ use rustc_span::symbol::{kw, sym, Ident};
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::DerefMut;
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
const MORE_EXTERN: &str =
|
const MORE_EXTERN: &str =
|
||||||
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
|
"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]) {
|
fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
|
||||||
// Check only lifetime parameters are present and that the lifetime
|
// Check only lifetime parameters are present and that the lifetime
|
||||||
// parameters that are present have no bounds.
|
// parameters that are present have no bounds.
|
||||||
@ -580,8 +552,7 @@ impl<'a> AstValidator<'a> {
|
|||||||
|
|
||||||
/// An item in `extern { ... }` cannot use non-ascii identifier.
|
/// An item in `extern { ... }` cannot use non-ascii identifier.
|
||||||
fn check_foreign_item_ascii_only(&self, ident: Ident) {
|
fn check_foreign_item_ascii_only(&self, ident: Ident) {
|
||||||
let symbol_str = ident.as_str();
|
if !ident.as_str().is_ascii() {
|
||||||
if !symbol_str.is_ascii() {
|
|
||||||
let n = 83942;
|
let n = 83942;
|
||||||
self.err_handler()
|
self.err_handler()
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
@ -894,7 +865,6 @@ impl<'a> AstValidator<'a> {
|
|||||||
/// Checks that generic parameters are in the correct order,
|
/// Checks that generic parameters are in the correct order,
|
||||||
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
|
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
|
||||||
fn validate_generic_param_order(
|
fn validate_generic_param_order(
|
||||||
sess: &Session,
|
|
||||||
handler: &rustc_errors::Handler,
|
handler: &rustc_errors::Handler,
|
||||||
generics: &[GenericParam],
|
generics: &[GenericParam],
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -911,8 +881,7 @@ fn validate_generic_param_order(
|
|||||||
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
|
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
|
||||||
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
|
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
|
||||||
let ty = pprust::ty_to_string(ty);
|
let ty = pprust::ty_to_string(ty);
|
||||||
let unordered = sess.features_untracked().unordered_const_ty_params();
|
(ParamKindOrd::Const, format!("const {}: {}", ident, ty))
|
||||||
(ParamKindOrd::Const { unordered }, format!("const {}: {}", ident, ty))
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
param_idents.push((kind, ord_kind, bounds, idx, ident));
|
param_idents.push((kind, ord_kind, bounds, idx, ident));
|
||||||
@ -968,14 +937,7 @@ fn validate_generic_param_order(
|
|||||||
);
|
);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
&format!(
|
"reorder the parameters: lifetimes, then consts and types",
|
||||||
"reorder the parameters: lifetimes, {}",
|
|
||||||
if sess.features_untracked().unordered_const_ty_params() {
|
|
||||||
"then consts and types"
|
|
||||||
} else {
|
|
||||||
"then types, then consts"
|
|
||||||
}
|
|
||||||
),
|
|
||||||
ordered_params.clone(),
|
ordered_params.clone(),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
@ -1342,8 +1304,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'a Generics) {
|
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;
|
let mut prev_param_default = None;
|
||||||
for param in &generics.params {
|
for param in &generics.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
@ -1358,12 +1318,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
span,
|
span,
|
||||||
"generic parameters with a default must be trailing",
|
"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();
|
err.emit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1371,12 +1325,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_generic_param_order(
|
validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
|
||||||
self.session,
|
|
||||||
self.err_handler(),
|
|
||||||
&generics.params,
|
|
||||||
generics.span,
|
|
||||||
);
|
|
||||||
|
|
||||||
for predicate in &generics.where_clause.predicates {
|
for predicate in &generics.where_clause.predicates {
|
||||||
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
||||||
@ -1449,25 +1398,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
visit::walk_param_bound(self, bound)
|
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) {
|
fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifier) {
|
||||||
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
|
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
|
||||||
visit::walk_poly_trait_ref(self, t, m);
|
visit::walk_poly_trait_ref(self, t, m);
|
||||||
@ -1714,6 +1644,53 @@ fn deny_equality_constraints(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||||
|
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
|
||||||
|
if let [potential_param, potential_assoc] = &full_path.segments[..] {
|
||||||
|
for param in &generics.params {
|
||||||
|
if param.ident == potential_param.ident {
|
||||||
|
for bound in ¶m.bounds {
|
||||||
|
if let ast::GenericBound::Trait(trait_ref, TraitBoundModifier::None) = bound
|
||||||
|
{
|
||||||
|
if let [trait_segment] = &trait_ref.trait_ref.path.segments[..] {
|
||||||
|
let assoc = pprust::path_to_string(&ast::Path::from_ident(
|
||||||
|
potential_assoc.ident,
|
||||||
|
));
|
||||||
|
let ty = pprust::ty_to_string(&predicate.rhs_ty);
|
||||||
|
let (args, span) = match &trait_segment.args {
|
||||||
|
Some(args) => match args.deref() {
|
||||||
|
ast::GenericArgs::AngleBracketed(args) => {
|
||||||
|
let Some(arg) = args.args.last() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
(
|
||||||
|
format!(", {} = {}", assoc, ty),
|
||||||
|
arg.span().shrink_to_hi(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
},
|
||||||
|
None => (
|
||||||
|
format!("<{} = {}>", assoc, ty),
|
||||||
|
trait_segment.span().shrink_to_hi(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
err.multipart_suggestion(
|
||||||
|
&format!(
|
||||||
|
"if `{}::{}` is an associated type you're trying to set, \
|
||||||
|
use the associated type binding syntax",
|
||||||
|
trait_segment.ident, potential_assoc.ident,
|
||||||
|
),
|
||||||
|
vec![(span, args), (predicate.span, String::new())],
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
err.note(
|
err.note(
|
||||||
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
|
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
|
||||||
);
|
);
|
||||||
|
@ -61,7 +61,7 @@ impl<'a> PostExpansionVisitor<'a> {
|
|||||||
fn check_abi(&self, abi: ast::StrLit) {
|
fn check_abi(&self, abi: ast::StrLit) {
|
||||||
let ast::StrLit { symbol_unescaped, span, .. } = abi;
|
let ast::StrLit { symbol_unescaped, span, .. } = abi;
|
||||||
|
|
||||||
match &*symbol_unescaped.as_str() {
|
match symbol_unescaped.as_str() {
|
||||||
// Stable
|
// Stable
|
||||||
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
||||||
| "system" => {}
|
| "system" => {}
|
||||||
@ -347,7 +347,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||||||
|
|
||||||
if let Some(modifiers) = nested_meta.value_str() {
|
if let Some(modifiers) = nested_meta.value_str() {
|
||||||
for modifier in modifiers.as_str().split(',') {
|
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)*) => {
|
macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => {
|
||||||
$(if modifier == $name {
|
$(if modifier == $name {
|
||||||
let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable");
|
let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable");
|
||||||
@ -383,7 +383,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast::ItemKind::Fn(..) => {
|
ast::ItemKind::Fn(..) => {
|
||||||
if self.sess.contains_name(&i.attrs[..], sym::start) {
|
if self.sess.contains_name(&i.attrs, sym::start) {
|
||||||
gate_feature_post!(
|
gate_feature_post!(
|
||||||
&self,
|
&self,
|
||||||
start,
|
start,
|
||||||
@ -396,7 +396,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast::ItemKind::Struct(..) => {
|
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) {
|
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
|
||||||
if item.has_name(sym::simd) {
|
if item.has_name(sym::simd) {
|
||||||
gate_feature_post!(
|
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!(half_open_range_patterns, "half-open range patterns are unstable");
|
||||||
gate_all!(inline_const, "inline-const is experimental");
|
gate_all!(inline_const, "inline-const is experimental");
|
||||||
gate_all!(inline_const_pat, "inline-const in pattern position 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,
|
// All uses of `gate_all!` below this point were added in #65742,
|
||||||
// and subsequently disabled (with the non-early gating readded).
|
// and subsequently disabled (with the non-early gating readded).
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#![feature(iter_is_partitioned)]
|
#![feature(iter_is_partitioned)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
|
#![feature(let_else)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
pub mod ast_validation;
|
pub mod ast_validation;
|
||||||
|
@ -35,4 +35,14 @@ impl Printer {
|
|||||||
self.word(w);
|
self.word(w);
|
||||||
self.nbsp()
|
self.nbsp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Synthesizes a comment that was not textually present in the original
|
||||||
|
// source file.
|
||||||
|
pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) {
|
||||||
|
self.word("/*");
|
||||||
|
self.space();
|
||||||
|
self.word(text);
|
||||||
|
self.space();
|
||||||
|
self.word("*/")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,5 +73,14 @@ pub fn attribute_to_string(attr: &ast::Attribute) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
|
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
|
||||||
State::new().to_string(f)
|
State::to_string(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn crate_to_string_for_macros(krate: &ast::Crate) -> String {
|
||||||
|
State::to_string(|s| {
|
||||||
|
s.print_inner_attributes(&krate.attrs);
|
||||||
|
for item in &krate.items {
|
||||||
|
s.print_item(item);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -236,7 +236,7 @@ where
|
|||||||
|
|
||||||
// These unwraps are safe because `get` ensures the meta item
|
// These unwraps are safe because `get` ensures the meta item
|
||||||
// is a name/value pair string literal.
|
// is a name/value pair string literal.
|
||||||
issue_num = match &*issue.unwrap().as_str() {
|
issue_num = match issue.unwrap().as_str() {
|
||||||
"none" => None,
|
"none" => None,
|
||||||
issue => {
|
issue => {
|
||||||
let emit_diag = |msg: &str| {
|
let emit_diag = |msg: &str| {
|
||||||
@ -301,7 +301,7 @@ where
|
|||||||
|
|
||||||
match (feature, reason, issue) {
|
match (feature, reason, issue) {
|
||||||
(Some(feature), reason, Some(_)) => {
|
(Some(feature), reason, Some(_)) => {
|
||||||
if !rustc_lexer::is_ident(&feature.as_str()) {
|
if !rustc_lexer::is_ident(feature.as_str()) {
|
||||||
handle_errors(
|
handle_errors(
|
||||||
&sess.parse_sess,
|
&sess.parse_sess,
|
||||||
attr.span,
|
attr.span,
|
||||||
@ -519,8 +519,10 @@ pub fn eval_condition(
|
|||||||
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||||
(sym, span)
|
(sym, span)
|
||||||
}
|
}
|
||||||
[NestedMetaItem::Literal(Lit { span, .. })
|
[
|
||||||
| NestedMetaItem::MetaItem(MetaItem { span, .. })] => {
|
NestedMetaItem::Literal(Lit { span, .. })
|
||||||
|
| NestedMetaItem::MetaItem(MetaItem { span, .. }),
|
||||||
|
] => {
|
||||||
sess.span_diagnostic
|
sess.span_diagnostic
|
||||||
.struct_span_err(*span, "expected a version literal")
|
.struct_span_err(*span, "expected a version literal")
|
||||||
.emit();
|
.emit();
|
||||||
@ -533,7 +535,7 @@ pub fn eval_condition(
|
|||||||
return false;
|
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,
|
Some(ver) => ver,
|
||||||
None => {
|
None => {
|
||||||
sess.span_diagnostic
|
sess.span_diagnostic
|
||||||
|
@ -84,7 +84,7 @@ pub enum LocalsStateAtExit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalsStateAtExit {
|
impl LocalsStateAtExit {
|
||||||
fn build(
|
fn build<'tcx>(
|
||||||
locals_are_invalidated_at_exit: bool,
|
locals_are_invalidated_at_exit: bool,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
|
@ -5,7 +5,7 @@ use rustc_middle::ty::RegionVid;
|
|||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
|
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
|
||||||
use rustc_mir_dataflow::ResultsVisitable;
|
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 rustc_mir_dataflow::{Analysis, Direction, Results};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
@ -434,9 +434,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
_trans: &mut impl GenKill<Self::Idx>,
|
_trans: &mut impl GenKill<Self::Idx>,
|
||||||
_block: mir::BasicBlock,
|
_block: mir::BasicBlock,
|
||||||
_func: &mir::Operand<'tcx>,
|
_return_places: CallReturnPlaces<'_, 'tcx>,
|
||||||
_args: &[mir::Operand<'tcx>],
|
|
||||||
_dest_place: mir::Place<'tcx>,
|
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
|||||||
PlaceContext::MutatingUse(MutatingUseContext::Store) |
|
PlaceContext::MutatingUse(MutatingUseContext::Store) |
|
||||||
|
|
||||||
// This is potentially both a def and a use...
|
// 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
|
// We let Call define the result in both the success and
|
||||||
// unwind cases. This is not really correct, however it
|
// 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
|
// the def in call only to the input from the success
|
||||||
// path and not the unwind path. -nmatsakis
|
// path and not the unwind path. -nmatsakis
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Call) |
|
PlaceContext::MutatingUse(MutatingUseContext::Call) |
|
||||||
|
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Yield) |
|
PlaceContext::MutatingUse(MutatingUseContext::Yield) |
|
||||||
|
|
||||||
// Storage live and storage dead aren't proper defines, but we can ignore
|
// Storage live and storage dead aren't proper defines, but we can ignore
|
||||||
|
@ -31,7 +31,7 @@ enum UniverseInfoInner<'tcx> {
|
|||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UniverseInfo<'tcx> {
|
impl<'tcx> UniverseInfo<'tcx> {
|
||||||
crate fn other() -> UniverseInfo<'tcx> {
|
crate fn other() -> UniverseInfo<'tcx> {
|
||||||
UniverseInfo(UniverseInfoInner::Other)
|
UniverseInfo(UniverseInfoInner::Other)
|
||||||
}
|
}
|
||||||
@ -191,7 +191,7 @@ struct PredicateQuery<'tcx> {
|
|||||||
base_universe: ty::UniverseIndex,
|
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> {
|
fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||||
let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error");
|
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));
|
err.note(&format!("could not prove {}", self.canonical_query.value.value.predicate));
|
||||||
@ -231,7 +231,7 @@ struct NormalizeQuery<'tcx, T> {
|
|||||||
base_universe: ty::UniverseIndex,
|
base_universe: ty::UniverseIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
|
impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
|
||||||
where
|
where
|
||||||
T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx,
|
T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx,
|
||||||
{
|
{
|
||||||
@ -291,7 +291,7 @@ struct AscribeUserTypeQuery<'tcx> {
|
|||||||
base_universe: ty::UniverseIndex,
|
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> {
|
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,
|
// 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.
|
// 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,
|
error_region,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
placeholder_region,
|
placeholder_region,
|
||||||
|
vec![],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(Some(error_region), _) => NiceRegionError::new(
|
(Some(error_region), _) => NiceRegionError::new(
|
||||||
|
@ -15,16 +15,18 @@ use rustc_span::symbol::sym;
|
|||||||
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
|
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
|
|
||||||
|
use crate::borrow_set::TwoPhaseActivation;
|
||||||
use crate::borrowck_errors;
|
use crate::borrowck_errors;
|
||||||
|
|
||||||
|
use crate::diagnostics::find_all_local_uses;
|
||||||
use crate::{
|
use crate::{
|
||||||
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
||||||
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
|
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
explain_borrow::BorrowExplanation, FnSelfUseKind, IncludingDowncast, RegionName,
|
explain_borrow::{BorrowExplanation, LaterUseKind},
|
||||||
RegionNameSource, UseSpans,
|
FnSelfUseKind, IncludingDowncast, RegionName, RegionNameSource, UseSpans,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -414,7 +416,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
tcx,
|
tcx,
|
||||||
generics,
|
generics,
|
||||||
&mut err,
|
&mut err,
|
||||||
¶m.name.as_str(),
|
param.name.as_str(),
|
||||||
"Copy",
|
"Copy",
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
@ -768,9 +770,92 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
Some((issued_span, span)),
|
Some((issued_span, span)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.suggest_using_local_if_applicable(
|
||||||
|
&mut err,
|
||||||
|
location,
|
||||||
|
(place, span),
|
||||||
|
gen_borrow_kind,
|
||||||
|
issued_borrow,
|
||||||
|
explanation,
|
||||||
|
);
|
||||||
|
|
||||||
err
|
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(
|
fn suggest_split_at_mut_if_applicable(
|
||||||
&self,
|
&self,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
@ -977,9 +1062,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
Some(ref name),
|
Some(ref name),
|
||||||
BorrowExplanation::MustBeValidFor {
|
BorrowExplanation::MustBeValidFor {
|
||||||
category:
|
category:
|
||||||
category
|
category @ (ConstraintCategory::Return(_)
|
||||||
@
|
|
||||||
(ConstraintCategory::Return(_)
|
|
||||||
| ConstraintCategory::CallArgument
|
| ConstraintCategory::CallArgument
|
||||||
| ConstraintCategory::OpaqueType),
|
| ConstraintCategory::OpaqueType),
|
||||||
from_closure: false,
|
from_closure: false,
|
||||||
@ -1515,8 +1598,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
location: Location,
|
location: Location,
|
||||||
mpi: MovePathIndex,
|
mpi: MovePathIndex,
|
||||||
) -> (Vec<MoveSite>, Vec<Location>) {
|
) -> (Vec<MoveSite>, Vec<Location>) {
|
||||||
fn predecessor_locations(
|
fn predecessor_locations<'a>(
|
||||||
body: &'a mir::Body<'tcx>,
|
body: &'a mir::Body<'_>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> impl Iterator<Item = Location> + 'a {
|
) -> impl Iterator<Item = Location> + 'a {
|
||||||
if location.statement_index == 0 {
|
if location.statement_index == 0 {
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||||
|
use rustc_middle::mir::{Body, Local, Location};
|
||||||
|
|
||||||
|
/// Find all uses of (including assignments to) a [`Local`].
|
||||||
|
///
|
||||||
|
/// Uses `BTreeSet` so output is deterministic.
|
||||||
|
pub(super) fn find<'tcx>(body: &Body<'tcx>, local: Local) -> BTreeSet<Location> {
|
||||||
|
let mut visitor = AllLocalUsesVisitor { for_local: local, uses: BTreeSet::default() };
|
||||||
|
visitor.visit_body(body);
|
||||||
|
visitor.uses
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AllLocalUsesVisitor {
|
||||||
|
for_local: Local,
|
||||||
|
uses: BTreeSet<Location>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Visitor<'tcx> for AllLocalUsesVisitor {
|
||||||
|
fn visit_local(&mut self, local: &Local, _context: PlaceContext, location: Location) {
|
||||||
|
if *local == self.for_local {
|
||||||
|
self.uses.insert(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ use rustc_target::abi::VariantIdx;
|
|||||||
use super::borrow_set::BorrowData;
|
use super::borrow_set::BorrowData;
|
||||||
use super::MirBorrowckCtxt;
|
use super::MirBorrowckCtxt;
|
||||||
|
|
||||||
|
mod find_all_local_uses;
|
||||||
mod find_use;
|
mod find_use;
|
||||||
mod outlives_suggestion;
|
mod outlives_suggestion;
|
||||||
mod region_name;
|
mod region_name;
|
||||||
@ -205,7 +206,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
{
|
{
|
||||||
let local_info = &self.body.local_decls[local].local_info;
|
let local_info = &self.body.local_decls[local].local_info;
|
||||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *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 {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
@ -317,7 +318,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
let decl = &self.body.local_decls[local];
|
let decl = &self.body.local_decls[local];
|
||||||
match self.local_names[local] {
|
match self.local_names[local] {
|
||||||
Some(name) if !decl.from_compiler_desugaring() => {
|
Some(name) if !decl.from_compiler_desugaring() => {
|
||||||
buf.push_str(&name.as_str());
|
buf.push_str(name.as_str());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
@ -408,7 +409,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
/// Add a note that a type does not implement `Copy`
|
/// Add a note that a type does not implement `Copy`
|
||||||
pub(super) fn note_type_does_not_implement_copy(
|
pub(super) fn note_type_does_not_implement_copy(
|
||||||
&self,
|
&self,
|
||||||
err: &mut DiagnosticBuilder<'a>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
place_desc: &str,
|
place_desc: &str,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
@ -732,21 +733,19 @@ pub(super) enum BorrowedContentSource<'tcx> {
|
|||||||
OverloadedIndex(Ty<'tcx>),
|
OverloadedIndex(Ty<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BorrowedContentSource<'tcx> {
|
impl<'tcx> BorrowedContentSource<'tcx> {
|
||||||
pub(super) fn describe_for_unnamed_place(&self, tcx: TyCtxt<'_>) -> String {
|
pub(super) fn describe_for_unnamed_place(&self, tcx: TyCtxt<'_>) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
BorrowedContentSource::DerefRawPointer => "a raw pointer".to_string(),
|
BorrowedContentSource::DerefRawPointer => "a raw pointer".to_string(),
|
||||||
BorrowedContentSource::DerefSharedRef => "a shared reference".to_string(),
|
BorrowedContentSource::DerefSharedRef => "a shared reference".to_string(),
|
||||||
BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
|
BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
|
||||||
BorrowedContentSource::OverloadedDeref(ty) => match ty.kind() {
|
BorrowedContentSource::OverloadedDeref(ty) => ty
|
||||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
|
.ty_adt_def()
|
||||||
"an `Rc`".to_string()
|
.and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
|
||||||
}
|
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
|
||||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
|
_ => None,
|
||||||
"an `Arc`".to_string()
|
})
|
||||||
}
|
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
|
||||||
_ => format!("dereference of `{}`", ty),
|
|
||||||
},
|
|
||||||
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
|
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -770,15 +769,13 @@ impl BorrowedContentSource<'tcx> {
|
|||||||
BorrowedContentSource::DerefMutableRef => {
|
BorrowedContentSource::DerefMutableRef => {
|
||||||
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
|
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
|
||||||
}
|
}
|
||||||
BorrowedContentSource::OverloadedDeref(ty) => match ty.kind() {
|
BorrowedContentSource::OverloadedDeref(ty) => ty
|
||||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
|
.ty_adt_def()
|
||||||
"an `Rc`".to_string()
|
.and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
|
||||||
}
|
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
|
||||||
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
|
_ => None,
|
||||||
"an `Arc`".to_string()
|
})
|
||||||
}
|
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
|
||||||
_ => format!("a dereference of `{}`", ty),
|
|
||||||
},
|
|
||||||
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty),
|
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -960,8 +957,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
|
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
|
||||||
tcx.is_diagnostic_item(sym::Option, def_id)
|
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
|
||||||
|| tcx.is_diagnostic_item(sym::Result, def_id)
|
|
||||||
});
|
});
|
||||||
FnSelfUseKind::Normal { self_arg, implicit_into_iter, is_option_or_result }
|
FnSelfUseKind::Normal { self_arg, implicit_into_iter, is_option_or_result }
|
||||||
});
|
});
|
||||||
|
@ -165,10 +165,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
PlaceRef {
|
PlaceRef {
|
||||||
local: _,
|
local: _,
|
||||||
projection:
|
projection:
|
||||||
[.., ProjectionElem::Index(_)
|
[
|
||||||
| ProjectionElem::ConstantIndex { .. }
|
..,
|
||||||
| ProjectionElem::Subslice { .. }
|
ProjectionElem::Index(_)
|
||||||
| ProjectionElem::Downcast(..)],
|
| ProjectionElem::ConstantIndex { .. }
|
||||||
|
| ProjectionElem::Subslice { .. }
|
||||||
|
| ProjectionElem::Downcast(..),
|
||||||
|
],
|
||||||
} => bug!("Unexpected immutable place."),
|
} => bug!("Unexpected immutable place."),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,19 +220,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
PlaceRef {
|
PlaceRef {
|
||||||
local,
|
local,
|
||||||
projection:
|
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));
|
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,
|
self.infcx.tcx,
|
||||||
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
|
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
|
||||||
field,
|
field,
|
||||||
) {
|
) {
|
||||||
err.span_suggestion(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
"consider changing this to be mutable",
|
"consider changing this to be mutable",
|
||||||
message,
|
" mut ".into(),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -739,7 +747,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
HirId, ImplItem, ImplItemKind, Item, ItemKind,
|
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) {
|
match hir_map.find(id) {
|
||||||
Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. }))
|
Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. }))
|
||||||
| Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => {
|
| Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => {
|
||||||
@ -763,11 +771,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
kind:
|
kind:
|
||||||
Call(
|
Call(
|
||||||
_,
|
_,
|
||||||
[Expr {
|
[
|
||||||
kind: MethodCall(path_segment, ..),
|
Expr {
|
||||||
hir_id,
|
kind: MethodCall(path_segment, ..),
|
||||||
..
|
hir_id,
|
||||||
}, ..],
|
..
|
||||||
|
},
|
||||||
|
..,
|
||||||
|
],
|
||||||
),
|
),
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
@ -1048,18 +1059,18 @@ fn is_closure_or_generator(ty: Ty<'_>) -> bool {
|
|||||||
ty.is_closure() || ty.is_generator()
|
ty.is_closure() || ty.is_generator()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a suggestion to a struct definition given a field access to a local.
|
/// 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 suggestion.
|
/// This function expects the local to be a reference to a struct in order to produce a span.
|
||||||
///
|
///
|
||||||
/// ```text
|
/// ```text
|
||||||
/// LL | s: &'a String
|
/// LL | s: &'a String
|
||||||
/// | ---------- use `&'a mut String` here to make mutable
|
/// | ^^^ returns a span taking up the space here
|
||||||
/// ```
|
/// ```
|
||||||
fn annotate_struct_field(
|
fn get_mut_span_in_struct_field<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
field: &mir::Field,
|
field: &mir::Field,
|
||||||
) -> Option<(Span, String)> {
|
) -> Option<Span> {
|
||||||
// Expect our local to be a reference to a struct of some kind.
|
// Expect our local to be a reference to a struct of some kind.
|
||||||
if let ty::Ref(_, ty, _) = ty.kind() {
|
if let ty::Ref(_, ty, _) = ty.kind() {
|
||||||
if let ty::Adt(def, _) = 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,
|
// 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.
|
// we can expect a field that is an immutable reference to a type.
|
||||||
if let hir::Node::Field(field) = node {
|
if let hir::Node::Field(field) = node {
|
||||||
if let hir::TyKind::Rptr(
|
if let hir::TyKind::Rptr(lifetime, hir::MutTy { mutbl: hir::Mutability::Not, ty }) =
|
||||||
lifetime,
|
field.ty.kind
|
||||||
hir::MutTy { mutbl: hir::Mutability::Not, ref ty },
|
|
||||||
) = field.ty.kind
|
|
||||||
{
|
{
|
||||||
// Get the snippets in two parts - the named lifetime (if there is one) and
|
return Some(lifetime.span.between(ty.span));
|
||||||
// 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,),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use rustc_infer::infer::{
|
|||||||
error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin,
|
error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin,
|
||||||
};
|
};
|
||||||
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
|
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_middle::ty::{self, RegionVid, Ty};
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
use rustc_span::{BytePos, Span};
|
use rustc_span::{BytePos, Span};
|
||||||
@ -334,13 +334,43 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
match variance_info {
|
match variance_info {
|
||||||
ty::VarianceDiagInfo::None => {}
|
ty::VarianceDiagInfo::None => {}
|
||||||
ty::VarianceDiagInfo::Mut { kind, ty } => {
|
ty::VarianceDiagInfo::Invariant { ty, param_index } => {
|
||||||
let kind_name = match kind {
|
let (desc, note) = match ty.kind() {
|
||||||
ty::VarianceDiagMutKind::Ref => "reference",
|
ty::RawPtr(ty_mut) => {
|
||||||
ty::VarianceDiagMutKind::RawPtr => "pointer",
|
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!("requirement occurs because of {desc}",));
|
||||||
diag.note(&format!("mutable {kind_name}s are invariant over their type parameter"));
|
diag.note(¬e);
|
||||||
diag.help("see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance");
|
diag.help("see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
|
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
|
// In this case, the user left off the lifetime; so
|
||||||
// they wrote something like:
|
// they wrote something like:
|
||||||
//
|
//
|
||||||
@ -769,20 +769,24 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
let opaque_ty = hir.item(id);
|
let opaque_ty = hir.item(id);
|
||||||
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
bounds:
|
bounds:
|
||||||
[hir::GenericBound::LangItemTrait(
|
[
|
||||||
hir::LangItem::Future,
|
hir::GenericBound::LangItemTrait(
|
||||||
_,
|
hir::LangItem::Future,
|
||||||
_,
|
_,
|
||||||
hir::GenericArgs {
|
_,
|
||||||
bindings:
|
hir::GenericArgs {
|
||||||
[hir::TypeBinding {
|
bindings:
|
||||||
ident: Ident { name: sym::Output, .. },
|
[
|
||||||
kind: hir::TypeBindingKind::Equality { ty },
|
hir::TypeBinding {
|
||||||
..
|
ident: Ident { name: sym::Output, .. },
|
||||||
}],
|
kind: hir::TypeBindingKind::Equality { ty },
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
)],
|
],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
..
|
..
|
||||||
}) = opaque_ty.kind
|
}) = opaque_ty.kind
|
||||||
{
|
{
|
||||||
|
@ -199,6 +199,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
|||||||
options: _,
|
options: _,
|
||||||
line_spans: _,
|
line_spans: _,
|
||||||
destination: _,
|
destination: _,
|
||||||
|
cleanup: _,
|
||||||
} => {
|
} => {
|
||||||
for op in operands {
|
for op in operands {
|
||||||
match *op {
|
match *op {
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![cfg_attr(bootstrap, feature(format_args_capture))]
|
|
||||||
#![feature(in_band_lifetimes)]
|
|
||||||
#![feature(iter_zip)]
|
|
||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
@ -792,6 +789,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
|||||||
options: _,
|
options: _,
|
||||||
line_spans: _,
|
line_spans: _,
|
||||||
destination: _,
|
destination: _,
|
||||||
|
cleanup: _,
|
||||||
} => {
|
} => {
|
||||||
for op in operands {
|
for op in operands {
|
||||||
match *op {
|
match *op {
|
||||||
@ -1396,10 +1394,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
|
|
||||||
Rvalue::NullaryOp(_op, _ty) => {
|
Rvalue::NullaryOp(_op, _ty) => {
|
||||||
// nullary ops take no dynamic input; no borrowck effect.
|
// 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) => {
|
Rvalue::Aggregate(ref aggregate_kind, ref operands) => {
|
||||||
|
@ -53,7 +53,7 @@ rustc_index::newtype_index! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MemberConstraintSet<'tcx, ty::RegionVid> {
|
impl Default for MemberConstraintSet<'_, ty::RegionVid> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
first_constraints: Default::default(),
|
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
|
where
|
||||||
R1: Copy + Hash + Eq,
|
R1: Copy + Hash + Eq,
|
||||||
{
|
{
|
||||||
@ -140,7 +140,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> MemberConstraintSet<'tcx, R>
|
impl<R> MemberConstraintSet<'_, R>
|
||||||
where
|
where
|
||||||
R: Copy + Hash + Eq,
|
R: Copy + Hash + Eq,
|
||||||
{
|
{
|
||||||
|
@ -141,7 +141,7 @@ pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool {
|
|||||||
/// then returns the index of the field being projected. Note that this closure will always
|
/// 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
|
/// be `self` in the current MIR, because that is the only time we directly access the fields
|
||||||
/// of a closure type.
|
/// of a closure type.
|
||||||
pub(crate) fn is_upvar_field_projection(
|
pub(crate) fn is_upvar_field_projection<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
upvars: &[Upvar<'tcx>],
|
upvars: &[Upvar<'tcx>],
|
||||||
place_ref: PlaceRef<'tcx>,
|
place_ref: PlaceRef<'tcx>,
|
||||||
|
@ -173,7 +173,7 @@ fn check_opaque_type_parameter_valid(
|
|||||||
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
||||||
//
|
//
|
||||||
// which would error here on all of the `'static` args.
|
// which would error here on all of the `'static` args.
|
||||||
OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true,
|
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
|
||||||
// Check these
|
// Check these
|
||||||
OpaqueTyOrigin::TyAlias => {}
|
OpaqueTyOrigin::TyAlias => {}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use rustc_data_structures::fx::FxIndexSet;
|
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::Idx;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::mir::{BasicBlock, Body, Location};
|
use rustc_middle::mir::{BasicBlock, Body, Location};
|
||||||
@ -110,11 +112,11 @@ crate enum RegionElement {
|
|||||||
PlaceholderRegion(ty::PlaceholderRegion),
|
PlaceholderRegion(ty::PlaceholderRegion),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When we initially compute liveness, we use a bit matrix storing
|
/// When we initially compute liveness, we use an interval matrix storing
|
||||||
/// points for each region-vid.
|
/// liveness ranges for each region-vid.
|
||||||
crate struct LivenessValues<N: Idx> {
|
crate struct LivenessValues<N: Idx> {
|
||||||
elements: Rc<RegionValueElements>,
|
elements: Rc<RegionValueElements>,
|
||||||
points: SparseBitMatrix<N, PointIndex>,
|
points: SparseIntervalMatrix<N, PointIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Idx> LivenessValues<N> {
|
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
|
/// Each of the regions in num_region_variables will be initialized with an
|
||||||
/// empty set of points and no causal information.
|
/// empty set of points and no causal information.
|
||||||
crate fn new(elements: Rc<RegionValueElements>) -> Self {
|
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.
|
/// 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
|
/// Adds all the elements in the given bit array into the given
|
||||||
/// region. Returns whether any of them are newly added.
|
/// 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);
|
debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations);
|
||||||
self.points.union_row(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.
|
/// Returns `true` if the region `r` contains the given element.
|
||||||
crate fn contains(&self, row: N, location: Location) -> bool {
|
crate fn contains(&self, row: N, location: Location) -> bool {
|
||||||
let index = self.elements.point_from_location(location);
|
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`
|
/// Returns an iterator of all the elements contained by the region `r`
|
||||||
@ -221,7 +223,7 @@ impl PlaceholderIndices {
|
|||||||
crate struct RegionValues<N: Idx> {
|
crate struct RegionValues<N: Idx> {
|
||||||
elements: Rc<RegionValueElements>,
|
elements: Rc<RegionValueElements>,
|
||||||
placeholder_indices: Rc<PlaceholderIndices>,
|
placeholder_indices: Rc<PlaceholderIndices>,
|
||||||
points: SparseBitMatrix<N, PointIndex>,
|
points: SparseIntervalMatrix<N, PointIndex>,
|
||||||
free_regions: SparseBitMatrix<N, RegionVid>,
|
free_regions: SparseBitMatrix<N, RegionVid>,
|
||||||
|
|
||||||
/// Placeholders represent bound regions -- so something like `'a`
|
/// Placeholders represent bound regions -- so something like `'a`
|
||||||
@ -241,7 +243,7 @@ impl<N: Idx> RegionValues<N> {
|
|||||||
let num_placeholders = placeholder_indices.len();
|
let num_placeholders = placeholder_indices.len();
|
||||||
Self {
|
Self {
|
||||||
elements: elements.clone(),
|
elements: elements.clone(),
|
||||||
points: SparseBitMatrix::new(elements.num_points),
|
points: SparseIntervalMatrix::new(elements.num_points),
|
||||||
placeholder_indices: placeholder_indices.clone(),
|
placeholder_indices: placeholder_indices.clone(),
|
||||||
free_regions: SparseBitMatrix::new(num_universal_regions),
|
free_regions: SparseBitMatrix::new(num_universal_regions),
|
||||||
placeholders: SparseBitMatrix::new(num_placeholders),
|
placeholders: SparseBitMatrix::new(num_placeholders),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
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::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
|
|
||||||
@ -62,22 +62,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
|
|||||||
debug!(?ty);
|
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")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
||||||
*substs = self.renumber_regions(*substs);
|
*substs = self.renumber_regions(*substs);
|
||||||
|
@ -6,6 +6,7 @@ use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
|||||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
use rustc_middle::ty::subst::GenericArgKind;
|
||||||
|
use rustc_middle::ty::TypeFoldable;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
|
||||||
@ -95,11 +96,23 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||||||
self.add_outlives(r1_vid, r2_vid);
|
self.add_outlives(r1_vid, r2_vid);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericArgKind::Type(t1) => {
|
GenericArgKind::Type(mut t1) => {
|
||||||
// we don't actually use this for anything, but
|
// we don't actually use this for anything, but
|
||||||
// the `TypeOutlives` code needs an origin.
|
// the `TypeOutlives` code needs an origin.
|
||||||
let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
|
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(
|
TypeOutlives::new(
|
||||||
&mut *self,
|
&mut *self,
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -58,7 +58,7 @@ crate struct CreateResult<'tcx> {
|
|||||||
crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
|
crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn create(
|
crate fn create<'tcx>(
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
implicit_region_bound: Option<ty::Region<'tcx>>,
|
implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||||
@ -81,7 +81,7 @@ crate fn create(
|
|||||||
.create()
|
.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UniversalRegionRelations<'tcx> {
|
impl UniversalRegionRelations<'_> {
|
||||||
/// Records in the `outlives_relation` (and
|
/// Records in the `outlives_relation` (and
|
||||||
/// `inverse_outlives_relation`) that `fr_a: fr_b`. Invoked by the
|
/// `inverse_outlives_relation`) that `fr_a: fr_b`. Invoked by the
|
||||||
/// builder below.
|
/// builder below.
|
||||||
@ -110,7 +110,7 @@ impl UniversalRegionRelations<'tcx> {
|
|||||||
/// outlives `fr` and (b) is not local.
|
/// outlives `fr` and (b) is not local.
|
||||||
///
|
///
|
||||||
/// (*) If there are multiple competing choices, we return all of them.
|
/// (*) 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);
|
debug!("non_local_upper_bound(fr={:?})", fr);
|
||||||
let res = self.non_local_bounds(&self.inverse_outlives, fr);
|
let res = self.non_local_bounds(&self.inverse_outlives, fr);
|
||||||
assert!(!res.is_empty(), "can't find an upper bound!?");
|
assert!(!res.is_empty(), "can't find an upper bound!?");
|
||||||
@ -232,7 +232,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> {
|
|||||||
region_bound_pairs: RegionBoundPairs<'tcx>,
|
region_bound_pairs: RegionBoundPairs<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||||
crate fn create(mut self) -> CreateResult<'tcx> {
|
crate fn create(mut self) -> CreateResult<'tcx> {
|
||||||
let unnormalized_input_output_tys = self
|
let unnormalized_input_output_tys = self
|
||||||
.universal_regions
|
.universal_regions
|
||||||
|
@ -117,9 +117,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(body.yield_ty().is_some() == universal_regions.yield_ty.is_some());
|
debug!(
|
||||||
if let Some(mir_yield_ty) = body.yield_ty() {
|
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}",
|
||||||
let ur_yield_ty = universal_regions.yield_ty.unwrap();
|
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;
|
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);
|
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ impl LocalUseMapBuild<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor<'tcx> for LocalUseMapBuild<'_> {
|
impl Visitor<'_> for LocalUseMapBuild<'_> {
|
||||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
||||||
if self.locals_with_use_data[local] {
|
if self.locals_with_use_data[local] {
|
||||||
match def_use::categorize(context) {
|
match def_use::categorize(context) {
|
||||||
|
@ -74,7 +74,7 @@ pub(super) fn generate<'mir, 'tcx>(
|
|||||||
// to compute whether a variable `X` is live if that variable contains
|
// 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
|
// 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).
|
// 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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
free_regions: &FxHashSet<RegionVid>,
|
free_regions: &FxHashSet<RegionVid>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
@ -104,7 +104,7 @@ fn compute_live_locals(
|
|||||||
/// regions. For these regions, we do not need to compute
|
/// regions. For these regions, we do not need to compute
|
||||||
/// liveness, since the outlives constraints will ensure that they
|
/// liveness, since the outlives constraints will ensure that they
|
||||||
/// are live over the whole fn body anyhow.
|
/// 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,
|
num_region_vars: usize,
|
||||||
universal_regions: &UniversalRegions<'tcx>,
|
universal_regions: &UniversalRegions<'tcx>,
|
||||||
constraint_set: &OutlivesConstraintSet<'tcx>,
|
constraint_set: &OutlivesConstraintSet<'tcx>,
|
||||||
|
@ -53,7 +53,7 @@ impl UseFactsExtractor<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor<'tcx> for UseFactsExtractor<'_> {
|
impl Visitor<'_> for UseFactsExtractor<'_> {
|
||||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
||||||
match def_use::categorize(context) {
|
match def_use::categorize(context) {
|
||||||
Some(DefUse::Def) => self.insert_def(local, location),
|
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);
|
self.super_place(place, context, location);
|
||||||
match context {
|
match context {
|
||||||
PlaceContext::NonMutatingUse(_) => {
|
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>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
location_table: &LocationTable,
|
location_table: &LocationTable,
|
||||||
@ -123,7 +123,7 @@ pub(super) fn populate_access_facts(
|
|||||||
|
|
||||||
// For every potentially drop()-touched region `region` in `local`'s type
|
// For every potentially drop()-touched region `region` in `local`'s type
|
||||||
// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
|
// (`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>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
local: Local,
|
local: Local,
|
||||||
kind: &GenericArg<'tcx>,
|
kind: &GenericArg<'tcx>,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_index::bit_set::HybridBitSet;
|
use rustc_index::bit_set::HybridBitSet;
|
||||||
|
use rustc_index::interval::IntervalSet;
|
||||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||||
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
|
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
|
||||||
use rustc_middle::ty::{Ty, TypeFoldable};
|
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
|
/// DROP-LIVE set are to the liveness sets for regions found in the
|
||||||
/// `dropck_outlives` result of the variable's type (in particular,
|
/// `dropck_outlives` result of the variable's type (in particular,
|
||||||
/// this respects `#[may_dangle]` annotations).
|
/// this respects `#[may_dangle]` annotations).
|
||||||
pub(super) fn trace(
|
pub(super) fn trace<'mir, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<RegionValueElements>,
|
||||||
@ -105,12 +106,12 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||||||
|
|
||||||
/// Points where the current variable is "use live" -- meaning
|
/// Points where the current variable is "use live" -- meaning
|
||||||
/// that there is a future "full use" that may use its value.
|
/// 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
|
/// Points where the current variable is "drop live" -- meaning
|
||||||
/// that there is no future "full use" that may use its value, but
|
/// that there is no future "full use" that may use its value, but
|
||||||
/// there is a future drop.
|
/// there is a future drop.
|
||||||
drop_live_at: HybridBitSet<PointIndex>,
|
drop_live_at: IntervalSet<PointIndex>,
|
||||||
|
|
||||||
/// Locations where drops may occur.
|
/// Locations where drops may occur.
|
||||||
drop_locations: Vec<Location>,
|
drop_locations: Vec<Location>,
|
||||||
@ -119,14 +120,14 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||||||
stack: Vec<PointIndex>,
|
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 {
|
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self {
|
||||||
let num_points = cx.elements.num_points();
|
let num_points = cx.elements.num_points();
|
||||||
LivenessResults {
|
LivenessResults {
|
||||||
cx,
|
cx,
|
||||||
defs: HybridBitSet::new_empty(num_points),
|
defs: HybridBitSet::new_empty(num_points),
|
||||||
use_live_at: HybridBitSet::new_empty(num_points),
|
use_live_at: IntervalSet::new(num_points),
|
||||||
drop_live_at: HybridBitSet::new_empty(num_points),
|
drop_live_at: IntervalSet::new(num_points),
|
||||||
drop_locations: vec![],
|
drop_locations: vec![],
|
||||||
stack: vec![],
|
stack: vec![],
|
||||||
}
|
}
|
||||||
@ -165,7 +166,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||||||
drop_used: Vec<(Local, Location)>,
|
drop_used: Vec<(Local, Location)>,
|
||||||
live_locals: FxHashSet<Local>,
|
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 {
|
for (local, location) in drop_used {
|
||||||
if !live_locals.contains(&local) {
|
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
|
/// 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
|
/// cursor position. Callers should call one of the `seek` methods immediately before to point
|
||||||
/// the cursor to the desired location.
|
/// the cursor to the desired location.
|
||||||
@ -456,7 +457,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||||||
fn add_use_live_facts_for(
|
fn add_use_live_facts_for(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: impl TypeFoldable<'tcx>,
|
value: impl TypeFoldable<'tcx>,
|
||||||
live_at: &HybridBitSet<PointIndex>,
|
live_at: &IntervalSet<PointIndex>,
|
||||||
) {
|
) {
|
||||||
debug!("add_use_live_facts_for(value={:?})", value);
|
debug!("add_use_live_facts_for(value={:?})", value);
|
||||||
|
|
||||||
@ -473,7 +474,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||||||
dropped_local: Local,
|
dropped_local: Local,
|
||||||
dropped_ty: Ty<'tcx>,
|
dropped_ty: Ty<'tcx>,
|
||||||
drop_locations: &[Location],
|
drop_locations: &[Location],
|
||||||
live_at: &HybridBitSet<PointIndex>,
|
live_at: &IntervalSet<PointIndex>,
|
||||||
) {
|
) {
|
||||||
debug!(
|
debug!(
|
||||||
"add_drop_live_constraint(\
|
"add_drop_live_constraint(\
|
||||||
@ -521,7 +522,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||||||
elements: &RegionValueElements,
|
elements: &RegionValueElements,
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
value: impl TypeFoldable<'tcx>,
|
value: impl TypeFoldable<'tcx>,
|
||||||
live_at: &HybridBitSet<PointIndex>,
|
live_at: &IntervalSet<PointIndex>,
|
||||||
) {
|
) {
|
||||||
debug!("make_all_regions_live(value={:?})", value);
|
debug!("make_all_regions_live(value={:?})", value);
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -31,7 +31,7 @@ use rustc_middle::ty::fold::TypeFoldable;
|
|||||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
|
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
|
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::def_id::CRATE_DEF_ID;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
@ -945,7 +945,7 @@ crate struct MirTypeckRegionConstraints<'tcx> {
|
|||||||
crate type_tests: Vec<TypeTest<'tcx>>,
|
crate type_tests: Vec<TypeTest<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MirTypeckRegionConstraints<'tcx> {
|
impl<'tcx> MirTypeckRegionConstraints<'tcx> {
|
||||||
fn placeholder_region(
|
fn placeholder_region(
|
||||||
&mut self,
|
&mut self,
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
@ -1828,10 +1828,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
self.assert_iscleanup(body, block_data, unwind, true);
|
self.assert_iscleanup(body, block_data, unwind, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminatorKind::InlineAsm { destination, .. } => {
|
TerminatorKind::InlineAsm { destination, cleanup, .. } => {
|
||||||
if let Some(target) = destination {
|
if let Some(target) = destination {
|
||||||
self.assert_iscleanup(body, block_data, target, is_cleanup);
|
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();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
match *ak {
|
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 variant = &def.variants[variant_index];
|
||||||
let adj_field_index = active_field_index.unwrap_or(field_index);
|
let adj_field_index = active_field_index.unwrap_or(field_index);
|
||||||
if let Some(field) = variant.fields.get(adj_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 {
|
let (def_id, instantiated_predicates) = match aggregate_kind {
|
||||||
AggregateKind::Adt(def, _, substs, _, _) => {
|
AggregateKind::Adt(adt_did, _, substs, _, _) => {
|
||||||
(def.did, tcx.predicates_of(def.did).instantiate(tcx, substs))
|
(*adt_did, tcx.predicates_of(*adt_did).instantiate(tcx, substs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// For closures, we have some **extra requirements** we
|
// For closures, we have some **extra requirements** we
|
||||||
|
@ -51,7 +51,7 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
|||||||
universe_info: UniverseInfo<'tcx>,
|
universe_info: UniverseInfo<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
||||||
locations: Locations,
|
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> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.type_checker.param_env
|
self.type_checker.param_env
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
|
|||||||
rustc_errors = { path = "../rustc_errors" }
|
rustc_errors = { path = "../rustc_errors" }
|
||||||
rustc_feature = { path = "../rustc_feature" }
|
rustc_feature = { path = "../rustc_feature" }
|
||||||
rustc_lexer = { path = "../rustc_lexer" }
|
rustc_lexer = { path = "../rustc_lexer" }
|
||||||
|
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||||
rustc_parse = { path = "../rustc_parse" }
|
rustc_parse = { path = "../rustc_parse" }
|
||||||
rustc_target = { path = "../rustc_target" }
|
rustc_target = { path = "../rustc_target" }
|
||||||
rustc_session = { path = "../rustc_session" }
|
rustc_session = { path = "../rustc_session" }
|
||||||
|
@ -8,13 +8,14 @@ use rustc_expand::base::{self, *};
|
|||||||
use rustc_parse::parser::Parser;
|
use rustc_parse::parser::Parser;
|
||||||
use rustc_parse_format as parse;
|
use rustc_parse_format as parse;
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
use rustc_span::{InnerSpan, Span};
|
use rustc_span::{InnerSpan, Span};
|
||||||
use rustc_target::asm::InlineAsmArch;
|
use rustc_target::asm::InlineAsmArch;
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
struct AsmArgs {
|
pub struct AsmArgs {
|
||||||
templates: Vec<P<ast::Expr>>,
|
templates: Vec<P<ast::Expr>>,
|
||||||
operands: Vec<(ast::InlineAsmOperand, Span)>,
|
operands: Vec<(ast::InlineAsmOperand, Span)>,
|
||||||
named_args: FxHashMap<Symbol, usize>,
|
named_args: FxHashMap<Symbol, usize>,
|
||||||
@ -31,30 +32,30 @@ fn parse_args<'a>(
|
|||||||
is_global_asm: bool,
|
is_global_asm: bool,
|
||||||
) -> Result<AsmArgs, DiagnosticBuilder<'a>> {
|
) -> Result<AsmArgs, DiagnosticBuilder<'a>> {
|
||||||
let mut p = ecx.new_parser_from_tts(tts);
|
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 {
|
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!)
|
// 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) {
|
if !is_global_asm && p.look_ahead(1, |t| *t == token::Colon || *t == token::ModSep) {
|
||||||
let mut err =
|
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("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");
|
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);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ fn parse_args<'a>(
|
|||||||
if !p.eat(&token::Comma) {
|
if !p.eat(&token::Comma) {
|
||||||
if allow_templates {
|
if allow_templates {
|
||||||
// After a template string, we always expect *only* a comma...
|
// 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 `,`");
|
err.span_label(p.token.span, "expected `,`");
|
||||||
p.maybe_annotate_with_ascription(&mut err, false);
|
p.maybe_annotate_with_ascription(&mut err, false);
|
||||||
return Err(err);
|
return Err(err);
|
||||||
@ -89,14 +90,14 @@ fn parse_args<'a>(
|
|||||||
|
|
||||||
// Parse clobber_abi
|
// Parse clobber_abi
|
||||||
if p.eat_keyword(sym::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;
|
allow_templates = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse options
|
// Parse options
|
||||||
if p.eat_keyword(sym::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;
|
allow_templates = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -116,25 +117,25 @@ fn parse_args<'a>(
|
|||||||
|
|
||||||
let mut explicit_reg = false;
|
let mut explicit_reg = false;
|
||||||
let op = if !is_global_asm && p.eat_keyword(kw::In) {
|
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) {
|
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);
|
return Err(err);
|
||||||
}
|
}
|
||||||
let expr = p.parse_expr()?;
|
let expr = p.parse_expr()?;
|
||||||
ast::InlineAsmOperand::In { reg, expr }
|
ast::InlineAsmOperand::In { reg, expr }
|
||||||
} else if !is_global_asm && p.eat_keyword(sym::out) {
|
} 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()?) };
|
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
|
||||||
ast::InlineAsmOperand::Out { reg, expr, late: false }
|
ast::InlineAsmOperand::Out { reg, expr, late: false }
|
||||||
} else if !is_global_asm && p.eat_keyword(sym::lateout) {
|
} 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()?) };
|
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
|
||||||
ast::InlineAsmOperand::Out { reg, expr, late: true }
|
ast::InlineAsmOperand::Out { reg, expr, late: true }
|
||||||
} else if !is_global_asm && p.eat_keyword(sym::inout) {
|
} 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) {
|
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);
|
return Err(err);
|
||||||
}
|
}
|
||||||
let expr = p.parse_expr()?;
|
let expr = p.parse_expr()?;
|
||||||
@ -146,9 +147,9 @@ fn parse_args<'a>(
|
|||||||
ast::InlineAsmOperand::InOut { reg, expr, late: false }
|
ast::InlineAsmOperand::InOut { reg, expr, late: false }
|
||||||
}
|
}
|
||||||
} else if !is_global_asm && p.eat_keyword(sym::inlateout) {
|
} 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) {
|
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);
|
return Err(err);
|
||||||
}
|
}
|
||||||
let expr = p.parse_expr()?;
|
let expr = p.parse_expr()?;
|
||||||
@ -167,7 +168,7 @@ fn parse_args<'a>(
|
|||||||
match expr.kind {
|
match expr.kind {
|
||||||
ast::ExprKind::Path(..) => {}
|
ast::ExprKind::Path(..) => {}
|
||||||
_ => {
|
_ => {
|
||||||
let err = ecx
|
let err = diag
|
||||||
.struct_span_err(expr.span, "argument to `sym` must be a path expression");
|
.struct_span_err(expr.span, "argument to `sym` must be a path expression");
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
@ -186,7 +187,7 @@ fn parse_args<'a>(
|
|||||||
} else {
|
} else {
|
||||||
"expected operand, clobber_abi, options, or additional template string"
|
"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);
|
err.span_label(template.span, errstr);
|
||||||
return Err(err);
|
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
|
// clobber_abi/options. We do this at the end once we have the full span
|
||||||
// of the argument available.
|
// of the argument available.
|
||||||
if !args.options_spans.is_empty() {
|
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_labels(args.options_spans.clone(), "previous options")
|
||||||
.span_label(span, "argument")
|
.span_label(span, "argument")
|
||||||
.emit();
|
.emit();
|
||||||
} else if let Some((_, abi_span)) = args.clobber_abis.last() {
|
} 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(*abi_span, "clobber_abi")
|
||||||
.span_label(span, "argument")
|
.span_label(span, "argument")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
if explicit_reg {
|
if explicit_reg {
|
||||||
if name.is_some() {
|
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);
|
args.reg_args.insert(slot);
|
||||||
} else if let Some(name) = name {
|
} else if let Some(name) = name {
|
||||||
if let Some(&prev) = args.named_args.get(&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(args.operands[prev].1, "previously here")
|
||||||
.span_label(span, "duplicate argument")
|
.span_label(span, "duplicate argument")
|
||||||
.emit();
|
.emit();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !args.reg_args.is_empty() {
|
if !args.reg_args.is_empty() {
|
||||||
let mut err = ecx.struct_span_err(
|
let mut err = diag.struct_span_err(
|
||||||
span,
|
span,
|
||||||
"named arguments cannot follow explicit register arguments",
|
"named arguments cannot follow explicit register arguments",
|
||||||
);
|
);
|
||||||
@ -243,7 +244,7 @@ fn parse_args<'a>(
|
|||||||
args.named_args.insert(name, slot);
|
args.named_args.insert(name, slot);
|
||||||
} else {
|
} else {
|
||||||
if !args.named_args.is_empty() || !args.reg_args.is_empty() {
|
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,
|
span,
|
||||||
"positional arguments cannot follow named arguments \
|
"positional arguments cannot follow named arguments \
|
||||||
or explicit register arguments",
|
or explicit register arguments",
|
||||||
@ -264,21 +265,21 @@ fn parse_args<'a>(
|
|||||||
&& args.options.contains(ast::InlineAsmOptions::READONLY)
|
&& args.options.contains(ast::InlineAsmOptions::READONLY)
|
||||||
{
|
{
|
||||||
let spans = args.options_spans.clone();
|
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();
|
.emit();
|
||||||
}
|
}
|
||||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||||
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
|
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
|
||||||
{
|
{
|
||||||
let spans = args.options_spans.clone();
|
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();
|
.emit();
|
||||||
}
|
}
|
||||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||||
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
|
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
|
||||||
{
|
{
|
||||||
let spans = args.options_spans.clone();
|
let spans = args.options_spans.clone();
|
||||||
ecx.struct_span_err(
|
diag.struct_span_err(
|
||||||
spans,
|
spans,
|
||||||
"the `pure` option must be combined with either `nomem` or `readonly`",
|
"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 {
|
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
|
||||||
ecx.struct_span_err(
|
diag.struct_span_err(
|
||||||
args.options_spans.clone(),
|
args.options_spans.clone(),
|
||||||
"asm with the `pure` option must have at least one output",
|
"asm with the `pure` option must have at least one output",
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
|
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");
|
.struct_span_err(outputs_sp, "asm outputs are not allowed with the `noreturn` option");
|
||||||
|
|
||||||
// Bail out now since this is likely to confuse MIR
|
// 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 args.clobber_abis.len() > 0 {
|
||||||
if is_global_asm {
|
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>>(),
|
args.clobber_abis.iter().map(|(_, span)| *span).collect::<Vec<Span>>(),
|
||||||
"`clobber_abi` cannot be used with `global_asm!`",
|
"`clobber_abi` cannot be used with `global_asm!`",
|
||||||
);
|
);
|
||||||
@ -334,7 +335,7 @@ fn parse_args<'a>(
|
|||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
if !regclass_outputs.is_empty() {
|
if !regclass_outputs.is_empty() {
|
||||||
ecx.struct_span_err(
|
diag.struct_span_err(
|
||||||
regclass_outputs.clone(),
|
regclass_outputs.clone(),
|
||||||
"asm with `clobber_abi` must specify explicit registers for outputs",
|
"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);
|
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
|
||||||
} else if p.eat_keyword(kw::Raw) {
|
} else if p.eat_keyword(kw::Raw) {
|
||||||
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::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 {
|
} else {
|
||||||
return p.unexpected();
|
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_snippet.as_ref().map(|s| Symbol::intern(s)),
|
||||||
template_sp,
|
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 {
|
if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
|
||||||
let find_span = |needle: &str| -> Span {
|
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),
|
Some(&idx) => Some(idx),
|
||||||
None => {
|
None => {
|
||||||
let msg = format!("there is no argument named `{}`", name);
|
let msg = format!("there is no argument named `{}`", name);
|
||||||
ecx.struct_span_err(span, &msg[..]).emit();
|
ecx.struct_span_err(span, &msg).emit();
|
||||||
None
|
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<'_>,
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: TokenStream,
|
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<'_>,
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::panic::use_panic_2021;
|
use crate::edition_panic::use_panic_2021;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::util::check_builtin_macro_attribute;
|
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::mut_visit::MutVisitor;
|
use rustc_ast::mut_visit::MutVisitor;
|
||||||
@ -11,7 +11,7 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
|
|||||||
use rustc_expand::config::StripUnconfigured;
|
use rustc_expand::config::StripUnconfigured;
|
||||||
use rustc_expand::configure;
|
use rustc_expand::configure;
|
||||||
use rustc_feature::Features;
|
use rustc_feature::Features;
|
||||||
use rustc_parse::parser::ForceCollect;
|
use rustc_parse::parser::{ForceCollect, Parser};
|
||||||
use rustc_session::utils::FlattenNonterminals;
|
use rustc_session::utils::FlattenNonterminals;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
@ -25,6 +25,7 @@ crate fn expand(
|
|||||||
annotatable: Annotatable,
|
annotatable: Annotatable,
|
||||||
) -> Vec<Annotatable> {
|
) -> Vec<Annotatable> {
|
||||||
check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval);
|
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)]
|
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::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::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::Variant(v) => vis.flat_map_variant(v).pop().map(Annotatable::Variant),
|
||||||
|
Annotatable::Crate(mut krate) => {
|
||||||
|
vis.visit_crate(&mut krate);
|
||||||
|
Some(Annotatable::Crate(krate))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +106,7 @@ impl CfgFinder {
|
|||||||
Annotatable::Param(param) => finder.visit_param(¶m),
|
Annotatable::Param(param) => finder.visit_param(¶m),
|
||||||
Annotatable::FieldDef(field) => finder.visit_field_def(&field),
|
Annotatable::FieldDef(field) => finder.visit_field_def(&field),
|
||||||
Annotatable::Variant(variant) => finder.visit_variant(&variant),
|
Annotatable::Variant(variant) => finder.visit_variant(&variant),
|
||||||
|
Annotatable::Crate(krate) => finder.visit_crate(krate),
|
||||||
};
|
};
|
||||||
finder.has_cfg_or_cfg_attr
|
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
|
// the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization
|
||||||
// process is lossless, so this process is invisible to proc-macros.
|
// process is lossless, so this process is invisible to proc-macros.
|
||||||
|
|
||||||
// FIXME - get rid of this clone
|
let parse_annotatable_with: fn(&mut Parser<'_>) -> _ = match annotatable {
|
||||||
let nt = annotatable.clone().into_nonterminal();
|
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(
|
let mut orig_tokens = rustc_parse::nt_to_tokenstream(
|
||||||
&nt,
|
&nt,
|
||||||
@ -173,25 +205,7 @@ impl CfgEval<'_, '_> {
|
|||||||
let mut parser =
|
let mut parser =
|
||||||
rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None);
|
rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None);
|
||||||
parser.capture_cfg = true;
|
parser.capture_cfg = true;
|
||||||
annotatable = match annotatable {
|
annotatable = parse_annotatable_with(&mut parser);
|
||||||
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!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring
|
// Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring
|
||||||
// our attribute target will correctly the tokens as well.
|
// our attribute target will correctly the tokens as well.
|
||||||
|
@ -21,7 +21,7 @@ pub fn expand_concat(
|
|||||||
match e.kind {
|
match e.kind {
|
||||||
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
ast::LitKind::Str(ref s, _) | ast::LitKind::Float(ref s, _) => {
|
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) => {
|
ast::LitKind::Char(c) => {
|
||||||
accumulator.push(c);
|
accumulator.push(c);
|
||||||
|
192
compiler/rustc_builtin_macros/src/concat_bytes.rs
Normal file
192
compiler/rustc_builtin_macros/src/concat_bytes.rs
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
use rustc_ast as ast;
|
||||||
|
use rustc_ast::{ptr::P, tokenstream::TokenStream};
|
||||||
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_expand::base::{self, DummyResult};
|
||||||
|
|
||||||
|
/// Emits errors for literal expressions that are invalid inside and outside of an array.
|
||||||
|
fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_nested: bool) {
|
||||||
|
let lit = if let ast::ExprKind::Lit(lit) = &expr.kind {
|
||||||
|
lit
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
match lit.kind {
|
||||||
|
ast::LitKind::Char(_) => {
|
||||||
|
let mut err = cx.struct_span_err(expr.span, "cannot concatenate character literals");
|
||||||
|
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"try using a byte character",
|
||||||
|
format!("b{}", snippet),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::LitKind::Str(_, _) => {
|
||||||
|
let mut err = cx.struct_span_err(expr.span, "cannot concatenate string literals");
|
||||||
|
// suggestion would be invalid if we are nested
|
||||||
|
if !is_nested {
|
||||||
|
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"try using a byte string",
|
||||||
|
format!("b{}", snippet),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
ast::LitKind::Float(_, _) => {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate float literals");
|
||||||
|
}
|
||||||
|
ast::LitKind::Bool(_) => {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate boolean literals");
|
||||||
|
}
|
||||||
|
ast::LitKind::Err(_) => {}
|
||||||
|
ast::LitKind::Int(_, _) if !is_nested => {
|
||||||
|
let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
|
||||||
|
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"try wrapping the number in an array",
|
||||||
|
format!("[{}]", snippet),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
ast::LitKind::Int(
|
||||||
|
val,
|
||||||
|
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||||
|
) => {
|
||||||
|
assert!(val > u8::MAX.into()); // must be an error
|
||||||
|
cx.span_err(expr.span, "numeric literal is out of bounds");
|
||||||
|
}
|
||||||
|
ast::LitKind::Int(_, _) => {
|
||||||
|
cx.span_err(expr.span, "numeric literal is not a `u8`");
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_array_element(
|
||||||
|
cx: &mut base::ExtCtxt<'_>,
|
||||||
|
has_errors: &mut bool,
|
||||||
|
missing_literals: &mut Vec<rustc_span::Span>,
|
||||||
|
expr: &P<rustc_ast::Expr>,
|
||||||
|
) -> Option<u8> {
|
||||||
|
match expr.kind {
|
||||||
|
ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
|
||||||
|
if !*has_errors {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate doubly nested array");
|
||||||
|
}
|
||||||
|
*has_errors = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
|
ast::LitKind::Int(
|
||||||
|
val,
|
||||||
|
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||||
|
) if val <= u8::MAX.into() => Some(val as u8),
|
||||||
|
|
||||||
|
ast::LitKind::Byte(val) => Some(val),
|
||||||
|
ast::LitKind::ByteStr(_) => {
|
||||||
|
if !*has_errors {
|
||||||
|
cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
|
||||||
|
.note("byte strings are treated as arrays of bytes")
|
||||||
|
.help("try flattening the array")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
*has_errors = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !*has_errors {
|
||||||
|
invalid_type_err(cx, expr, true);
|
||||||
|
}
|
||||||
|
*has_errors = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
missing_literals.push(expr.span);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expand_concat_bytes(
|
||||||
|
cx: &mut base::ExtCtxt<'_>,
|
||||||
|
sp: rustc_span::Span,
|
||||||
|
tts: TokenStream,
|
||||||
|
) -> Box<dyn base::MacResult + 'static> {
|
||||||
|
let es = match base::get_exprs_from_tts(cx, sp, tts) {
|
||||||
|
Some(e) => e,
|
||||||
|
None => return DummyResult::any(sp),
|
||||||
|
};
|
||||||
|
let mut accumulator = Vec::new();
|
||||||
|
let mut missing_literals = vec![];
|
||||||
|
let mut has_errors = false;
|
||||||
|
for e in es {
|
||||||
|
match e.kind {
|
||||||
|
ast::ExprKind::Array(ref exprs) => {
|
||||||
|
for expr in exprs {
|
||||||
|
if let Some(elem) =
|
||||||
|
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||||
|
{
|
||||||
|
accumulator.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::ExprKind::Repeat(ref expr, ref count) => {
|
||||||
|
if let ast::ExprKind::Lit(ast::Lit {
|
||||||
|
kind: ast::LitKind::Int(count_val, _), ..
|
||||||
|
}) = count.value.kind
|
||||||
|
{
|
||||||
|
if let Some(elem) =
|
||||||
|
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||||
|
{
|
||||||
|
for _ in 0..count_val {
|
||||||
|
accumulator.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cx.span_err(count.value.span, "repeat count is not a positive number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
|
ast::LitKind::Byte(val) => {
|
||||||
|
accumulator.push(val);
|
||||||
|
}
|
||||||
|
ast::LitKind::ByteStr(ref bytes) => {
|
||||||
|
accumulator.extend_from_slice(&bytes);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !has_errors {
|
||||||
|
invalid_type_err(cx, &e, false);
|
||||||
|
}
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ast::ExprKind::Err => {
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
missing_literals.push(e.span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !missing_literals.is_empty() {
|
||||||
|
let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
|
||||||
|
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
|
||||||
|
err.emit();
|
||||||
|
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||||
|
} else if has_errors {
|
||||||
|
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||||
|
}
|
||||||
|
let sp = cx.with_def_site_ctxt(sp);
|
||||||
|
base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator))))
|
||||||
|
}
|
@ -29,7 +29,7 @@ pub fn expand_concat_idents<'cx>(
|
|||||||
} else {
|
} else {
|
||||||
if let TokenTree::Token(token) = e {
|
if let TokenTree::Token(token) = e {
|
||||||
if let Some((ident, _)) = token.ident() {
|
if let Some((ident, _)) = token.ident() {
|
||||||
res_str.push_str(&ident.name.as_str());
|
res_str.push_str(ident.name.as_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
|
|||||||
|
|
||||||
fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
|
fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
|
||||||
let help_msg = match lit.token.kind {
|
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)
|
format!("try using `#[derive({})]`", lit.token.symbol)
|
||||||
}
|
}
|
||||||
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
|
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
|
||||||
|
@ -567,8 +567,11 @@ impl<'a> TraitDef<'a> {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let Generics { mut params, mut where_clause, span } =
|
let Generics { mut params, mut where_clause, .. } =
|
||||||
self.generics.to_generics(cx, self.span, type_ident, generics);
|
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
|
// Create the generic parameters
|
||||||
params.extend(generics.params.iter().map(|param| match ¶m.kind {
|
params.extend(generics.params.iter().map(|param| match ¶m.kind {
|
||||||
@ -589,12 +592,12 @@ impl<'a> TraitDef<'a> {
|
|||||||
param.bounds.iter().cloned()
|
param.bounds.iter().cloned()
|
||||||
).collect();
|
).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, .. } => {
|
GenericParamKind::Const { ty, kw_span, .. } => {
|
||||||
let const_nodefault_kind = GenericParamKind::Const {
|
let const_nodefault_kind = GenericParamKind::Const {
|
||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
kw_span: *kw_span,
|
kw_span: kw_span.with_ctxt(ctxt),
|
||||||
|
|
||||||
// We can't have default values inside impl block
|
// We can't have default values inside impl block
|
||||||
default: None,
|
default: None,
|
||||||
@ -607,28 +610,27 @@ impl<'a> TraitDef<'a> {
|
|||||||
|
|
||||||
// and similarly for where clauses
|
// and similarly for where clauses
|
||||||
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
|
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
|
||||||
match *clause {
|
match clause {
|
||||||
ast::WherePredicate::BoundPredicate(ref wb) => {
|
ast::WherePredicate::BoundPredicate(wb) => {
|
||||||
|
let span = wb.span.with_ctxt(ctxt);
|
||||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||||
span: self.span,
|
span,
|
||||||
bound_generic_params: wb.bound_generic_params.clone(),
|
..wb.clone()
|
||||||
bounded_ty: wb.bounded_ty.clone(),
|
|
||||||
bounds: wb.bounds.to_vec(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ast::WherePredicate::RegionPredicate(ref rb) => {
|
ast::WherePredicate::RegionPredicate(wr) => {
|
||||||
|
let span = wr.span.with_ctxt(ctxt);
|
||||||
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
||||||
span: self.span,
|
span,
|
||||||
lifetime: rb.lifetime,
|
..wr.clone()
|
||||||
bounds: rb.bounds.to_vec(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ast::WherePredicate::EqPredicate(ref we) => {
|
ast::WherePredicate::EqPredicate(we) => {
|
||||||
|
let span = we.span.with_ctxt(ctxt);
|
||||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: self.span,
|
span,
|
||||||
lhs_ty: we.lhs_ty.clone(),
|
..we.clone()
|
||||||
rhs_ty: we.rhs_ty.clone(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -691,13 +693,13 @@ impl<'a> TraitDef<'a> {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|param| match param.kind {
|
.map(|param| match param.kind {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericArg::Lifetime(cx.lifetime(self.span, param.ident))
|
GenericArg::Lifetime(cx.lifetime(param.ident.span.with_ctxt(ctxt), param.ident))
|
||||||
}
|
}
|
||||||
GenericParamKind::Type { .. } => {
|
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 { .. } => {
|
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();
|
.collect();
|
||||||
@ -764,8 +766,8 @@ impl<'a> TraitDef<'a> {
|
|||||||
self,
|
self,
|
||||||
struct_def,
|
struct_def,
|
||||||
type_ident,
|
type_ident,
|
||||||
&self_args[..],
|
&self_args,
|
||||||
&nonself_args[..],
|
&nonself_args,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
method_def.expand_struct_method_body(
|
method_def.expand_struct_method_body(
|
||||||
@ -773,8 +775,8 @@ impl<'a> TraitDef<'a> {
|
|||||||
self,
|
self,
|
||||||
struct_def,
|
struct_def,
|
||||||
type_ident,
|
type_ident,
|
||||||
&self_args[..],
|
&self_args,
|
||||||
&nonself_args[..],
|
&nonself_args,
|
||||||
use_temporaries,
|
use_temporaries,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -813,8 +815,8 @@ impl<'a> TraitDef<'a> {
|
|||||||
self,
|
self,
|
||||||
enum_def,
|
enum_def,
|
||||||
type_ident,
|
type_ident,
|
||||||
&self_args[..],
|
&self_args,
|
||||||
&nonself_args[..],
|
&nonself_args,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
method_def.expand_enum_method_body(
|
method_def.expand_enum_method_body(
|
||||||
@ -823,7 +825,7 @@ impl<'a> TraitDef<'a> {
|
|||||||
enum_def,
|
enum_def,
|
||||||
type_ident,
|
type_ident,
|
||||||
self_args,
|
self_args,
|
||||||
&nonself_args[..],
|
&nonself_args,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -845,16 +847,17 @@ impl<'a> MethodDef<'a> {
|
|||||||
nonself_args: &[P<Expr>],
|
nonself_args: &[P<Expr>],
|
||||||
fields: &SubstructureFields<'_>,
|
fields: &SubstructureFields<'_>,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
|
let span = trait_.span;
|
||||||
let substructure = Substructure {
|
let substructure = Substructure {
|
||||||
type_ident,
|
type_ident,
|
||||||
method_ident: Ident::new(self.name, trait_.span),
|
method_ident: Ident::new(self.name, span),
|
||||||
self_args,
|
self_args,
|
||||||
nonself_args,
|
nonself_args,
|
||||||
fields,
|
fields,
|
||||||
};
|
};
|
||||||
let mut f = self.combine_substructure.borrow_mut();
|
let mut f = self.combine_substructure.borrow_mut();
|
||||||
let f: &mut CombineSubstructureFunc<'_> = &mut *f;
|
let f: &mut CombineSubstructureFunc<'_> = &mut *f;
|
||||||
f(cx, trait_.span, &substructure)
|
f(cx, span, &substructure)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ret_ty(
|
fn get_ret_ty(
|
||||||
@ -882,9 +885,10 @@ impl<'a> MethodDef<'a> {
|
|||||||
let mut nonself_args = Vec::new();
|
let mut nonself_args = Vec::new();
|
||||||
let mut arg_tys = Vec::new();
|
let mut arg_tys = Vec::new();
|
||||||
let mut nonstatic = false;
|
let mut nonstatic = false;
|
||||||
|
let span = trait_.span;
|
||||||
|
|
||||||
let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| {
|
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);
|
self_args.push(self_expr);
|
||||||
nonstatic = true;
|
nonstatic = true;
|
||||||
@ -893,11 +897,11 @@ impl<'a> MethodDef<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (ty, name) in self.args.iter() {
|
for (ty, name) in self.args.iter() {
|
||||||
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
|
let ast_ty = ty.to_ty(cx, span, type_ident, generics);
|
||||||
let ident = Ident::new(*name, trait_.span);
|
let ident = Ident::new(*name, span);
|
||||||
arg_tys.push((ident, ast_ty));
|
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 {
|
match *ty {
|
||||||
// for static methods, just treat any Self
|
// for static methods, just treat any Self
|
||||||
@ -906,7 +910,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
self_args.push(arg_expr);
|
self_args.push(arg_expr);
|
||||||
}
|
}
|
||||||
Ptr(ref ty, _) if matches!(**ty, Self_) && nonstatic => {
|
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);
|
nonself_args.push(arg_expr);
|
||||||
@ -927,33 +931,33 @@ impl<'a> MethodDef<'a> {
|
|||||||
arg_types: Vec<(Ident, P<ast::Ty>)>,
|
arg_types: Vec<(Ident, P<ast::Ty>)>,
|
||||||
body: P<Expr>,
|
body: P<Expr>,
|
||||||
) -> P<ast::AssocItem> {
|
) -> P<ast::AssocItem> {
|
||||||
|
let span = trait_.span;
|
||||||
// Create the generics that aren't for `Self`.
|
// 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 args = {
|
||||||
let self_args = explicit_self.map(|explicit_self| {
|
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)
|
ast::Param::from_self(ast::AttrVec::default(), explicit_self, ident)
|
||||||
});
|
});
|
||||||
let nonself_args =
|
let nonself_args = arg_types.into_iter().map(|(name, ty)| cx.param(span, name, ty));
|
||||||
arg_types.into_iter().map(|(name, ty)| cx.param(trait_.span, name, ty));
|
|
||||||
self_args.into_iter().chain(nonself_args).collect()
|
self_args.into_iter().chain(nonself_args).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
|
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 fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type));
|
||||||
let body_block = cx.block_expr(body);
|
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 {
|
let sig = ast::FnSig {
|
||||||
header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() },
|
header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() },
|
||||||
decl: fn_decl,
|
decl: fn_decl,
|
||||||
span: trait_.span,
|
span,
|
||||||
};
|
};
|
||||||
let defaultness = ast::Defaultness::Final;
|
let defaultness = ast::Defaultness::Final;
|
||||||
|
|
||||||
@ -961,7 +965,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
P(ast::AssocItem {
|
P(ast::AssocItem {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
attrs: self.attributes.clone(),
|
attrs: self.attributes.clone(),
|
||||||
span: trait_.span,
|
span,
|
||||||
vis: ast::Visibility {
|
vis: ast::Visibility {
|
||||||
span: trait_lo_sp,
|
span: trait_lo_sp,
|
||||||
kind: ast::VisibilityKind::Inherited,
|
kind: ast::VisibilityKind::Inherited,
|
||||||
@ -1024,11 +1028,11 @@ impl<'a> MethodDef<'a> {
|
|||||||
nonself_args: &[P<Expr>],
|
nonself_args: &[P<Expr>],
|
||||||
use_temporaries: bool,
|
use_temporaries: bool,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
let mut raw_fields = Vec::new(); // Vec<[fields of self],
|
let mut raw_fields = Vec::new(); // Vec<[fields of self], [fields of next Self arg], [etc]>
|
||||||
// [fields of next Self arg], [etc]>
|
let span = trait_.span;
|
||||||
let mut patterns = Vec::new();
|
let mut patterns = Vec::new();
|
||||||
for i in 0..self_args.len() {
|
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(
|
let (pat, ident_expr) = trait_.create_struct_pattern(
|
||||||
cx,
|
cx,
|
||||||
struct_path,
|
struct_path,
|
||||||
@ -1048,7 +1052,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
let mut other_fields: Vec<vec::IntoIter<_>> = raw_fields.collect();
|
let mut other_fields: Vec<vec::IntoIter<_>> = raw_fields.collect();
|
||||||
first_field
|
first_field
|
||||||
.map(|(span, opt_id, field, attrs)| FieldInfo {
|
.map(|(span, opt_id, field, attrs)| FieldInfo {
|
||||||
span,
|
span: span.with_ctxt(trait_.span.ctxt()),
|
||||||
name: opt_id,
|
name: opt_id,
|
||||||
self_: field,
|
self_: field,
|
||||||
other: other_fields
|
other: other_fields
|
||||||
@ -1062,7 +1066,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} 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
|
// 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
|
// structs. This is actually right-to-left, but it shouldn't
|
||||||
// matter.
|
// matter.
|
||||||
for (arg_expr, pat) in iter::zip(self_args, patterns) {
|
for (arg_expr, pat) in iter::zip(self_args, patterns) {
|
||||||
body = cx.expr_match(
|
body = cx.expr_match(span, arg_expr.clone(), vec![cx.arm(span, pat.clone(), body)])
|
||||||
trait_.span,
|
|
||||||
arg_expr.clone(),
|
|
||||||
vec![cx.arm(trait_.span, pat.clone(), body)],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body
|
body
|
||||||
@ -1193,7 +1193,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
mut self_args: Vec<P<Expr>>,
|
mut self_args: Vec<P<Expr>>,
|
||||||
nonself_args: &[P<Expr>],
|
nonself_args: &[P<Expr>],
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
let sp = trait_.span;
|
let span = trait_.span;
|
||||||
let variants = &enum_def.variants;
|
let variants = &enum_def.variants;
|
||||||
|
|
||||||
let self_arg_names = iter::once("__self".to_string())
|
let self_arg_names = iter::once("__self".to_string())
|
||||||
@ -1208,7 +1208,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
|
|
||||||
let self_arg_idents = self_arg_names
|
let self_arg_idents = self_arg_names
|
||||||
.iter()
|
.iter()
|
||||||
.map(|name| Ident::from_str_and_span(name, sp))
|
.map(|name| Ident::from_str_and_span(name, span))
|
||||||
.collect::<Vec<Ident>>();
|
.collect::<Vec<Ident>>();
|
||||||
|
|
||||||
// The `vi_idents` will be bound, solely in the catch-all, to
|
// 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
|
let vi_idents = self_arg_names
|
||||||
.iter()
|
.iter()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
let vi_suffix = format!("{}_vi", &name[..]);
|
let vi_suffix = format!("{}_vi", name);
|
||||||
Ident::from_str_and_span(&vi_suffix, trait_.span)
|
Ident::from_str_and_span(&vi_suffix, span)
|
||||||
})
|
})
|
||||||
.collect::<Vec<Ident>>();
|
.collect::<Vec<Ident>>();
|
||||||
|
|
||||||
@ -1226,7 +1226,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
// delegated expression that handles the catch-all case,
|
// delegated expression that handles the catch-all case,
|
||||||
// using `__variants_tuple` to drive logic if necessary.
|
// using `__variants_tuple` to drive logic if necessary.
|
||||||
let catch_all_substructure =
|
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());
|
let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty());
|
||||||
|
|
||||||
@ -1248,7 +1248,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
self_arg_name,
|
self_arg_name,
|
||||||
ast::Mutability::Not,
|
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
|
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
|
||||||
@ -1261,13 +1261,13 @@ impl<'a> MethodDef<'a> {
|
|||||||
idents
|
idents
|
||||||
};
|
};
|
||||||
for self_arg_name in &self_arg_names[1..] {
|
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);
|
subpats.push(p);
|
||||||
self_pats_idents.push(idents);
|
self_pats_idents.push(idents);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here is the pat = `(&VariantK, &VariantK, ...)`
|
// 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,
|
// For the BodyK, we need to delegate to our caller,
|
||||||
// passing it an EnumMatching to indicate which case
|
// passing it an EnumMatching to indicate which case
|
||||||
@ -1284,7 +1284,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
// For each arg field of self, pull out its getter expr ...
|
// 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
|
// ... but FieldInfo also wants getter expr
|
||||||
// for matching other arguments of Self type;
|
// for matching other arguments of Self type;
|
||||||
// so walk across the *other* self_pats_idents
|
// so walk across the *other* self_pats_idents
|
||||||
@ -1307,7 +1307,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
.collect::<Vec<P<Expr>>>();
|
.collect::<Vec<P<Expr>>>();
|
||||||
|
|
||||||
FieldInfo {
|
FieldInfo {
|
||||||
span: sp,
|
span,
|
||||||
name: opt_ident,
|
name: opt_ident,
|
||||||
self_: self_getter_expr,
|
self_: self_getter_expr,
|
||||||
other: others,
|
other: others,
|
||||||
@ -1330,7 +1330,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
&substructure,
|
&substructure,
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.arm(sp, single_pat, arm_expr)
|
cx.arm(span, single_pat, arm_expr)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -1353,12 +1353,12 @@ impl<'a> MethodDef<'a> {
|
|||||||
// Since we know that all the arguments will match if we reach
|
// Since we know that all the arguments will match if we reach
|
||||||
// the match expression we add the unreachable intrinsics as the
|
// the match expression we add the unreachable intrinsics as the
|
||||||
// result of the catch all which should help llvm in optimizing it
|
// 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,
|
_ => None,
|
||||||
};
|
};
|
||||||
if let Some(arm) = default {
|
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
|
// 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
|
// We also build an expression which checks whether all discriminants are equal
|
||||||
// discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
|
// 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;
|
let mut first_ident = None;
|
||||||
for (&ident, self_arg) in iter::zip(&vi_idents, &self_args) {
|
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 =
|
let variant_value =
|
||||||
deriving::call_intrinsic(cx, sp, sym::discriminant_value, vec![self_addr]);
|
deriving::call_intrinsic(cx, span, sym::discriminant_value, vec![self_addr]);
|
||||||
let let_stmt = cx.stmt_let(sp, false, ident, variant_value);
|
let let_stmt = cx.stmt_let(span, false, ident, variant_value);
|
||||||
index_let_stmts.push(let_stmt);
|
index_let_stmts.push(let_stmt);
|
||||||
|
|
||||||
match first_ident {
|
match first_ident {
|
||||||
Some(first) => {
|
Some(first) => {
|
||||||
let first_expr = cx.expr_ident(sp, first);
|
let first_expr = cx.expr_ident(span, first);
|
||||||
let id = cx.expr_ident(sp, ident);
|
let id = cx.expr_ident(span, ident);
|
||||||
let test = cx.expr_binary(sp, BinOpKind::Eq, first_expr, id);
|
let test = cx.expr_binary(span, BinOpKind::Eq, first_expr, id);
|
||||||
discriminant_test =
|
discriminant_test =
|
||||||
cx.expr_binary(sp, BinOpKind::And, discriminant_test, test)
|
cx.expr_binary(span, BinOpKind::And, discriminant_test, test)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
first_ident = Some(ident);
|
first_ident = Some(ident);
|
||||||
@ -1430,8 +1430,8 @@ impl<'a> MethodDef<'a> {
|
|||||||
// them when they are fed as r-values into a tuple
|
// them when they are fed as r-values into a tuple
|
||||||
// expression; here add a layer of borrowing, turning
|
// expression; here add a layer of borrowing, turning
|
||||||
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
|
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
|
||||||
self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg));
|
self_args.map_in_place(|self_arg| cx.expr_addr_of(span, self_arg));
|
||||||
let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args));
|
let match_arg = cx.expr(span, ast::ExprKind::Tup(self_args));
|
||||||
|
|
||||||
// Lastly we create an expression which branches on all discriminants being equal
|
// Lastly we create an expression which branches on all discriminants being equal
|
||||||
// if discriminant_test {
|
// if discriminant_test {
|
||||||
@ -1445,10 +1445,10 @@ impl<'a> MethodDef<'a> {
|
|||||||
// else {
|
// else {
|
||||||
// <delegated expression referring to __self0_vi, et al.>
|
// <delegated expression referring to __self0_vi, et al.>
|
||||||
// }
|
// }
|
||||||
let all_match = cx.expr_match(sp, match_arg, match_arms);
|
let all_match = cx.expr_match(span, match_arg, match_arms);
|
||||||
let arm_expr = cx.expr_if(sp, discriminant_test, all_match, Some(arm_expr));
|
let arm_expr = cx.expr_if(span, discriminant_test, all_match, Some(arm_expr));
|
||||||
index_let_stmts.push(cx.stmt_expr(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() {
|
} else if variants.is_empty() {
|
||||||
// As an additional wrinkle, For a zero-variant enum A,
|
// As an additional wrinkle, For a zero-variant enum A,
|
||||||
// currently the compiler
|
// currently the compiler
|
||||||
@ -1499,16 +1499,16 @@ impl<'a> MethodDef<'a> {
|
|||||||
// derive Debug on such a type could here generate code
|
// derive Debug on such a type could here generate code
|
||||||
// that needs the feature gate enabled.)
|
// that needs the feature gate enabled.)
|
||||||
|
|
||||||
deriving::call_unreachable(cx, sp)
|
deriving::call_unreachable(cx, span)
|
||||||
} else {
|
} else {
|
||||||
// Final wrinkle: the self_args are expressions that deref
|
// Final wrinkle: the self_args are expressions that deref
|
||||||
// down to desired places, but we cannot actually deref
|
// down to desired places, but we cannot actually deref
|
||||||
// them when they are fed as r-values into a tuple
|
// them when they are fed as r-values into a tuple
|
||||||
// expression; here add a layer of borrowing, turning
|
// expression; here add a layer of borrowing, turning
|
||||||
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
|
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
|
||||||
self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg));
|
self_args.map_in_place(|self_arg| cx.expr_addr_of(span, self_arg));
|
||||||
let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args));
|
let match_arg = cx.expr(span, ast::ExprKind::Tup(self_args));
|
||||||
cx.expr_match(sp, match_arg, match_arms)
|
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(..));
|
let is_tuple = matches!(struct_def, ast::VariantData::Tuple(..));
|
||||||
match (just_spans.is_empty(), named_idents.is_empty()) {
|
match (just_spans.is_empty(), named_idents.is_empty()) {
|
||||||
(false, false) => cx.span_bug(
|
(false, false) => {
|
||||||
self.span,
|
cx.span_bug(self.span, "a struct with named and unnamed fields in generic `derive`")
|
||||||
"a struct with named and unnamed \
|
}
|
||||||
fields in generic `derive`",
|
|
||||||
),
|
|
||||||
// named fields
|
// named fields
|
||||||
(_, false) => Named(named_idents),
|
(_, false) => Named(named_idents),
|
||||||
// unnamed fields
|
// unnamed fields
|
||||||
|
@ -211,14 +211,6 @@ fn mk_ty_param(
|
|||||||
cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
|
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.
|
/// Bounds on type parameters.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Bounds {
|
pub struct Bounds {
|
||||||
@ -236,7 +228,7 @@ impl Bounds {
|
|||||||
self_ty: Ident,
|
self_ty: Ident,
|
||||||
self_generics: &Generics,
|
self_generics: &Generics,
|
||||||
) -> Generics {
|
) -> Generics {
|
||||||
let generic_params = self
|
let params = self
|
||||||
.bounds
|
.bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
@ -245,7 +237,11 @@ impl Bounds {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
mk_generics(generic_params, span)
|
Generics {
|
||||||
|
params,
|
||||||
|
where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
|
||||||
|
span,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,29 @@ pub fn expand_panic<'cx>(
|
|||||||
sp: Span,
|
sp: Span,
|
||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
) -> Box<dyn MacResult + 'cx> {
|
) -> 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);
|
let sp = cx.with_call_site_ctxt(sp);
|
||||||
|
|
||||||
MacEager::expr(
|
MacEager::expr(
|
||||||
@ -31,7 +52,7 @@ pub fn expand_panic<'cx>(
|
|||||||
path: Path {
|
path: Path {
|
||||||
span: sp,
|
span: sp,
|
||||||
segments: cx
|
segments: cx
|
||||||
.std_path(&[sym::panic, panic])
|
.std_path(&[sym::panic, mac])
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ident| PathSegment::from_ident(ident))
|
.map(|ident| PathSegment::from_ident(ident))
|
||||||
.collect(),
|
.collect(),
|
@ -80,11 +80,11 @@ pub fn expand_env<'cx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sp = cx.with_def_site_ctxt(sp);
|
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));
|
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
|
||||||
let e = match value {
|
let e = match value {
|
||||||
None => {
|
None => {
|
||||||
cx.span_err(sp, &msg.as_str());
|
cx.span_err(sp, msg.as_str());
|
||||||
return DummyResult::any(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
Some(value) => cx.expr_str(sp, value),
|
Some(value) => cx.expr_str(sp, value),
|
||||||
|
@ -23,6 +23,7 @@ enum ArgumentType {
|
|||||||
|
|
||||||
enum Position {
|
enum Position {
|
||||||
Exact(usize),
|
Exact(usize),
|
||||||
|
Capture(usize),
|
||||||
Named(Symbol),
|
Named(Symbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +48,8 @@ struct Context<'a, 'b> {
|
|||||||
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
|
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
|
||||||
/// * `names` (in JSON): `{"foo": 2}`
|
/// * `names` (in JSON): `{"foo": 2}`
|
||||||
args: Vec<P<ast::Expr>>,
|
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.
|
/// Placeholder slot numbers indexed by argument.
|
||||||
arg_types: Vec<Vec<usize>>,
|
arg_types: Vec<Vec<usize>>,
|
||||||
/// Unique format specs seen for each argument.
|
/// 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$}"`
|
/// * Implicit argument resolution: `"{1:.0$} {2:.foo$} {1:.3$} {4:.0$}"`
|
||||||
/// * Name resolution: `"{1:.0$} {2:.5$} {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_positions` (in JSON): `{0: 0, 5: 1, 3: 2}`
|
||||||
/// * `count_args`: `vec![Exact(0), Exact(5), Exact(3)]`
|
/// * `count_args`: `vec![0, 5, 3]`
|
||||||
count_args: Vec<Position>,
|
count_args: Vec<usize>,
|
||||||
/// Relative slot numbers for count arguments.
|
/// Relative slot numbers for count arguments.
|
||||||
count_positions: FxHashMap<usize, usize>,
|
count_positions: FxHashMap<usize, usize>,
|
||||||
/// Number of count slots assigned.
|
/// Number of count slots assigned.
|
||||||
@ -229,6 +232,11 @@ fn parse_args<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Context<'a, 'b> {
|
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<'_>) {
|
fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
|
||||||
// NOTE: the `unwrap_or` branch is needed in case of invalid format
|
// NOTE: the `unwrap_or` branch is needed in case of invalid format
|
||||||
// arguments, e.g., `format_args!("{foo}")`.
|
// arguments, e.g., `format_args!("{foo}")`.
|
||||||
@ -343,7 +351,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn describe_num_args(&self) -> Cow<'_, str> {
|
fn describe_num_args(&self) -> Cow<'_, str> {
|
||||||
match self.args.len() {
|
match self.num_args() {
|
||||||
0 => "no arguments were given".into(),
|
0 => "no arguments were given".into(),
|
||||||
1 => "there is 1 argument".into(),
|
1 => "there is 1 argument".into(),
|
||||||
x => format!("there are {} arguments", x).into(),
|
x => format!("there are {} arguments", x).into(),
|
||||||
@ -369,7 +377,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
|
|
||||||
let count = self.pieces.len()
|
let count = self.pieces.len()
|
||||||
+ self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
|
+ 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(
|
e = self.ecx.struct_span_err(
|
||||||
sp,
|
sp,
|
||||||
&format!(
|
&format!(
|
||||||
@ -417,7 +425,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
if let Some(span) = fmt.precision_span {
|
if let Some(span) = fmt.precision_span {
|
||||||
let span = self.fmtsp.from_inner(span);
|
let span = self.fmtsp.from_inner(span);
|
||||||
match fmt.precision {
|
match fmt.precision {
|
||||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||||
e.span_label(
|
e.span_label(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
@ -460,7 +468,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
if let Some(span) = fmt.width_span {
|
if let Some(span) = fmt.width_span {
|
||||||
let span = self.fmtsp.from_inner(span);
|
let span = self.fmtsp.from_inner(span);
|
||||||
match fmt.width {
|
match fmt.width {
|
||||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||||
e.span_label(
|
e.span_label(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
@ -492,12 +500,15 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
/// Actually verifies and tracks a given format placeholder
|
/// Actually verifies and tracks a given format placeholder
|
||||||
/// (a.k.a. argument).
|
/// (a.k.a. argument).
|
||||||
fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
|
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 {
|
match arg {
|
||||||
Exact(arg) => {
|
Exact(arg) | Capture(arg) => {
|
||||||
if self.args.len() <= arg {
|
|
||||||
self.invalid_refs.push((arg, self.curpiece));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
match ty {
|
match ty {
|
||||||
Placeholder(_) => {
|
Placeholder(_) => {
|
||||||
// record every (position, type) combination only once
|
// 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) {
|
if let Entry::Vacant(e) = self.count_positions.entry(arg) {
|
||||||
let i = self.count_positions_count;
|
let i = self.count_positions_count;
|
||||||
e.insert(i);
|
e.insert(i);
|
||||||
self.count_args.push(Exact(arg));
|
self.count_args.push(arg);
|
||||||
self.count_positions_count += 1;
|
self.count_positions_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -524,7 +535,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
match self.names.get(&name) {
|
match self.names.get(&name) {
|
||||||
Some(&idx) => {
|
Some(&idx) => {
|
||||||
// Treat as positional arg.
|
// Treat as positional arg.
|
||||||
self.verify_arg_type(Exact(idx), ty)
|
self.verify_arg_type(Capture(idx), ty)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// For the moment capturing variables from format strings expanded from macros is
|
// For the moment capturing variables from format strings expanded from macros is
|
||||||
@ -539,9 +550,10 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
} else {
|
} else {
|
||||||
self.fmtsp
|
self.fmtsp
|
||||||
};
|
};
|
||||||
|
self.num_captured_args += 1;
|
||||||
self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
|
self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
|
||||||
self.names.insert(name, idx);
|
self.names.insert(name, idx);
|
||||||
self.verify_arg_type(Exact(idx), ty)
|
self.verify_arg_type(Capture(idx), ty)
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("there is no argument named `{}`", name);
|
let msg = format!("there is no argument named `{}`", name);
|
||||||
let sp = if self.is_literal {
|
let sp = if self.is_literal {
|
||||||
@ -549,7 +561,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
} else {
|
} else {
|
||||||
self.fmtsp
|
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!(
|
err.note(&format!(
|
||||||
"did you intend to capture a variable `{}` from \
|
"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() {
|
for arg_ty in self.arg_unique_types[i].iter() {
|
||||||
args.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, i));
|
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 {
|
for index in self.count_args {
|
||||||
let index = match pos {
|
|
||||||
Exact(i) => i,
|
|
||||||
_ => panic!("should never happen"),
|
|
||||||
};
|
|
||||||
let span = spans_pos[index];
|
let span = spans_pos[index];
|
||||||
args.push(Context::format_arg(self.ecx, self.macsp, span, &Count, 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),
|
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 fmt_snippet = ecx.source_map().span_to_snippet(fmt_sp).ok();
|
||||||
let mut parser = parse::Parser::new(
|
let mut parser = parse::Parser::new(
|
||||||
fmt_str,
|
fmt_str,
|
||||||
@ -996,8 +1007,9 @@ pub fn expand_preparsed_format_args(
|
|||||||
e.note(¬e);
|
e.note(¬e);
|
||||||
}
|
}
|
||||||
if let Some((label, span)) = err.secondary_label {
|
if let Some((label, span)) = err.secondary_label {
|
||||||
let sp = fmt_span.from_inner(span);
|
if efmt_kind_is_lit {
|
||||||
e.span_label(sp, label);
|
e.span_label(fmt_span.from_inner(span), label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
e.emit();
|
e.emit();
|
||||||
return DummyResult::raw_expr(sp, true);
|
return DummyResult::raw_expr(sp, true);
|
||||||
@ -1010,6 +1022,7 @@ pub fn expand_preparsed_format_args(
|
|||||||
let mut cx = Context {
|
let mut cx = Context {
|
||||||
ecx,
|
ecx,
|
||||||
args,
|
args,
|
||||||
|
num_captured_args: 0,
|
||||||
arg_types,
|
arg_types,
|
||||||
arg_unique_types,
|
arg_unique_types,
|
||||||
names,
|
names,
|
||||||
|
@ -7,28 +7,29 @@ pub(crate) mod printf {
|
|||||||
pub enum Substitution<'a> {
|
pub enum Substitution<'a> {
|
||||||
/// A formatted output substitution with its internal byte offset.
|
/// A formatted output substitution with its internal byte offset.
|
||||||
Format(Format<'a>),
|
Format(Format<'a>),
|
||||||
/// A literal `%%` escape.
|
/// A literal `%%` escape, with its start and end indices.
|
||||||
Escape,
|
Escape((usize, usize)),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Substitution<'a> {
|
impl<'a> Substitution<'a> {
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Substitution::Format(ref fmt) => fmt.span,
|
Substitution::Format(ref fmt) => fmt.span,
|
||||||
Substitution::Escape => "%%",
|
Substitution::Escape(_) => "%%",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> Option<InnerSpan> {
|
pub fn position(&self) -> Option<InnerSpan> {
|
||||||
match *self {
|
match *self {
|
||||||
Substitution::Format(ref fmt) => Some(fmt.position),
|
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) {
|
pub fn set_position(&mut self, start: usize, end: usize) {
|
||||||
if let Substitution::Format(ref mut fmt) = self {
|
match self {
|
||||||
fmt.position = InnerSpan::new(start, end);
|
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>> {
|
pub fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match *self {
|
match *self {
|
||||||
Substitution::Format(ref fmt) => fmt.translate(),
|
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> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let (mut sub, tail) = parse_next_substitution(self.s)?;
|
let (mut sub, tail) = parse_next_substitution(self.s)?;
|
||||||
self.s = tail;
|
self.s = tail;
|
||||||
match sub {
|
if let Some(InnerSpan { start, end }) = sub.position() {
|
||||||
Substitution::Format(_) => {
|
sub.set_position(start + self.pos, end + self.pos);
|
||||||
if let Some(inner_span) = sub.position() {
|
self.pos += end;
|
||||||
sub.set_position(inner_span.start + self.pos, inner_span.end + self.pos);
|
|
||||||
self.pos += inner_span.end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Substitution::Escape => self.pos += 2,
|
|
||||||
}
|
}
|
||||||
Some(sub)
|
Some(sub)
|
||||||
}
|
}
|
||||||
@ -340,7 +336,7 @@ pub(crate) mod printf {
|
|||||||
let at = {
|
let at = {
|
||||||
let start = s.find('%')?;
|
let start = s.find('%')?;
|
||||||
if let '%' = s[start + 1..].chars().next()? {
|
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)
|
Cur::new_at(s, start)
|
||||||
|
@ -13,9 +13,9 @@ macro_rules! assert_eq_pnsat {
|
|||||||
fn test_escape() {
|
fn test_escape() {
|
||||||
assert_eq!(pns("has no escapes"), None);
|
assert_eq!(pns("has no escapes"), None);
|
||||||
assert_eq!(pns("has no escapes, either %"), None);
|
assert_eq!(pns("has no escapes, either %"), None);
|
||||||
assert_eq!(pns("*so* has a %% escape"), Some((S::Escape, " escape")));
|
assert_eq!(pns("*so* has a %% escape"), Some((S::Escape((11, 13)), " escape")));
|
||||||
assert_eq!(pns("%% leading escape"), Some((S::Escape, " leading escape")));
|
assert_eq!(pns("%% leading escape"), Some((S::Escape((0, 2)), " leading escape")));
|
||||||
assert_eq!(pns("trailing escape %%"), Some((S::Escape, "")));
|
assert_eq!(pns("trailing escape %%"), Some((S::Escape((16, 18)), "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(iter_zip)]
|
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
#![feature(proc_macro_quote)]
|
#![feature(proc_macro_quote)]
|
||||||
@ -20,28 +19,29 @@ use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
|
|||||||
use rustc_expand::proc_macro::BangProcMacro;
|
use rustc_expand::proc_macro::BangProcMacro;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
mod asm;
|
|
||||||
mod assert;
|
mod assert;
|
||||||
mod cfg;
|
mod cfg;
|
||||||
mod cfg_accessible;
|
mod cfg_accessible;
|
||||||
mod cfg_eval;
|
mod cfg_eval;
|
||||||
mod compile_error;
|
mod compile_error;
|
||||||
mod concat;
|
mod concat;
|
||||||
|
mod concat_bytes;
|
||||||
mod concat_idents;
|
mod concat_idents;
|
||||||
mod derive;
|
mod derive;
|
||||||
mod deriving;
|
mod deriving;
|
||||||
|
mod edition_panic;
|
||||||
mod env;
|
mod env;
|
||||||
mod format;
|
mod format;
|
||||||
mod format_foreign;
|
mod format_foreign;
|
||||||
mod global_allocator;
|
mod global_allocator;
|
||||||
mod llvm_asm;
|
mod llvm_asm;
|
||||||
mod log_syntax;
|
mod log_syntax;
|
||||||
mod panic;
|
|
||||||
mod source_util;
|
mod source_util;
|
||||||
mod test;
|
mod test;
|
||||||
mod trace_macros;
|
mod trace_macros;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
pub mod asm;
|
||||||
pub mod cmdline_attrs;
|
pub mod cmdline_attrs;
|
||||||
pub mod proc_macro_harness;
|
pub mod proc_macro_harness;
|
||||||
pub mod standard_library_imports;
|
pub mod standard_library_imports;
|
||||||
@ -65,6 +65,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
|||||||
cfg: cfg::expand_cfg,
|
cfg: cfg::expand_cfg,
|
||||||
column: source_util::expand_column,
|
column: source_util::expand_column,
|
||||||
compile_error: compile_error::expand_compile_error,
|
compile_error: compile_error::expand_compile_error,
|
||||||
|
concat_bytes: concat_bytes::expand_concat_bytes,
|
||||||
concat_idents: concat_idents::expand_concat_idents,
|
concat_idents: concat_idents::expand_concat_idents,
|
||||||
concat: concat::expand_concat,
|
concat: concat::expand_concat,
|
||||||
env: env::expand_env,
|
env: env::expand_env,
|
||||||
@ -81,8 +82,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
|||||||
log_syntax: log_syntax::expand_log_syntax,
|
log_syntax: log_syntax::expand_log_syntax,
|
||||||
module_path: source_util::expand_mod,
|
module_path: source_util::expand_mod,
|
||||||
option_env: env::expand_option_env,
|
option_env: env::expand_option_env,
|
||||||
core_panic: panic::expand_panic,
|
core_panic: edition_panic::expand_panic,
|
||||||
std_panic: panic::expand_panic,
|
std_panic: edition_panic::expand_panic,
|
||||||
|
unreachable: edition_panic::expand_unreachable,
|
||||||
stringify: source_util::expand_stringify,
|
stringify: source_util::expand_stringify,
|
||||||
trace_macros: trace_macros::expand_trace_macros,
|
trace_macros: trace_macros::expand_trace_macros,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/// The expansion from a test function to the appropriate test struct for libtest
|
/// 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.
|
/// 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 as ast;
|
||||||
use rustc_ast::attr;
|
use rustc_ast::attr;
|
||||||
@ -27,6 +27,7 @@ pub fn expand_test_case(
|
|||||||
anno_item: Annotatable,
|
anno_item: Annotatable,
|
||||||
) -> Vec<Annotatable> {
|
) -> Vec<Annotatable> {
|
||||||
check_builtin_macro_attribute(ecx, meta_item, sym::test_case);
|
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 {
|
if !ecx.ecfg.should_test {
|
||||||
return vec![];
|
return vec![];
|
||||||
@ -55,6 +56,7 @@ pub fn expand_test(
|
|||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
) -> Vec<Annotatable> {
|
) -> Vec<Annotatable> {
|
||||||
check_builtin_macro_attribute(cx, meta_item, sym::test);
|
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)
|
expand_test_or_bench(cx, attr_sp, item, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +67,7 @@ pub fn expand_bench(
|
|||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
) -> Vec<Annotatable> {
|
) -> Vec<Annotatable> {
|
||||||
check_builtin_macro_attribute(cx, meta_item, sym::bench);
|
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)
|
expand_test_or_bench(cx, attr_sp, item, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +84,35 @@ struct TestHarnessGenerator<'a> {
|
|||||||
tests: Vec<Test>,
|
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> {
|
impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
||||||
fn visit_crate(&mut self, c: &mut ast::Crate) {
|
fn visit_crate(&mut self, c: &mut ast::Crate) {
|
||||||
|
let prev_tests = mem::take(&mut self.tests);
|
||||||
noop_visit_crate(c, self);
|
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
|
// Create a main function to run our tests
|
||||||
c.items.push(mk_main(&mut self.cx));
|
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
|
// We don't want to recurse into anything other than mods, since
|
||||||
// mods or tests inside of functions will break things
|
// mods or tests inside of functions will break things
|
||||||
if let ast::ItemKind::Mod(..) = item.kind {
|
if let ast::ItemKind::Mod(_, ModKind::Loaded(.., span)) = item.kind {
|
||||||
let tests = mem::take(&mut self.tests);
|
let prev_tests = mem::take(&mut self.tests);
|
||||||
noop_visit_item_kind(&mut item.kind, self);
|
noop_visit_item_kind(&mut item.kind, self);
|
||||||
let mut tests = mem::replace(&mut self.tests, tests);
|
self.add_test_cases(item.id, span, prev_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
smallvec![P(item)]
|
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) {
|
} else if sess.contains_name(&item.attrs, sym::rustc_main) {
|
||||||
EntryPointType::MainAttr
|
EntryPointType::MainAttr
|
||||||
} else if item.ident.name == sym::main {
|
} else if item.ident.name == sym::main {
|
||||||
if depth == 1 {
|
if depth == 0 {
|
||||||
// This is a top-level function so can be 'main'
|
// This is a top-level function so can be 'main'
|
||||||
EntryPointType::MainNamed
|
EntryPointType::MainNamed
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use rustc_ast::MetaItem;
|
use rustc_ast::{Attribute, MetaItem};
|
||||||
use rustc_expand::base::ExtCtxt;
|
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||||
use rustc_feature::AttributeTemplate;
|
use rustc_feature::AttributeTemplate;
|
||||||
|
use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
|
||||||
use rustc_parse::validate_attr;
|
use rustc_parse::validate_attr;
|
||||||
use rustc_span::Symbol;
|
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());
|
let attr = ecx.attribute(meta_item.clone());
|
||||||
validate_attr::check_builtin_attribute(&ecx.sess.parse_sess, &attr, name, template);
|
validate_attr::check_builtin_attribute(&ecx.sess.parse_sess, &attr, name, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when
|
||||||
|
/// an attribute may have been mistakenly duplicated.
|
||||||
|
pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
|
||||||
|
let attrs: Option<&[Attribute]> = match item {
|
||||||
|
Annotatable::Item(item) => Some(&item.attrs),
|
||||||
|
Annotatable::TraitItem(item) => Some(&item.attrs),
|
||||||
|
Annotatable::ImplItem(item) => Some(&item.attrs),
|
||||||
|
Annotatable::ForeignItem(item) => Some(&item.attrs),
|
||||||
|
Annotatable::Expr(expr) => Some(&expr.attrs),
|
||||||
|
Annotatable::Arm(arm) => Some(&arm.attrs),
|
||||||
|
Annotatable::ExprField(field) => Some(&field.attrs),
|
||||||
|
Annotatable::PatField(field) => Some(&field.attrs),
|
||||||
|
Annotatable::GenericParam(param) => Some(¶m.attrs),
|
||||||
|
Annotatable::Param(param) => Some(¶m.attrs),
|
||||||
|
Annotatable::FieldDef(def) => Some(&def.attrs),
|
||||||
|
Annotatable::Variant(variant) => Some(&variant.attrs),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(attrs) = attrs {
|
||||||
|
if let Some(attr) = ecx.sess.find_by_name(attrs, name) {
|
||||||
|
ecx.parse_sess().buffer_lint(
|
||||||
|
DUPLICATE_MACRO_ATTRIBUTES,
|
||||||
|
attr.span,
|
||||||
|
ecx.current_expansion.lint_node_id,
|
||||||
|
"duplicated attribute",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,21 @@ on:
|
|||||||
- pull_request
|
- pull_request
|
||||||
|
|
||||||
jobs:
|
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:
|
build:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
@ -65,6 +80,12 @@ jobs:
|
|||||||
git config --global user.name "User"
|
git config --global user.name "User"
|
||||||
./y.rs prepare
|
./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
|
- name: Build
|
||||||
run: ./y.rs build --sysroot none
|
run: ./y.rs build --sysroot none
|
||||||
|
|
||||||
@ -152,11 +173,12 @@ jobs:
|
|||||||
|
|
||||||
./y.exe build
|
./y.exe build
|
||||||
|
|
||||||
#- name: Package prebuilt cg_clif
|
- name: Package prebuilt cg_clif
|
||||||
# run: tar cvfJ cg_clif.tar.xz build
|
# 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
|
- name: Upload prebuilt cg_clif
|
||||||
# uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
# with:
|
with:
|
||||||
# name: cg_clif-${{ runner.os }}
|
name: cg_clif-${{ runner.os }}
|
||||||
# path: cg_clif.tar.xz
|
path: cg_clif.tar
|
||||||
|
59
compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
vendored
Normal file
59
compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
name: Test nightly Cranelift
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
schedule:
|
||||||
|
- cron: '17 1 * * *' # At 01:17 UTC every day.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 60
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Cache cargo installed crates
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.cargo/bin
|
||||||
|
key: ubuntu-latest-cargo-installed-crates
|
||||||
|
|
||||||
|
- name: Prepare dependencies
|
||||||
|
run: |
|
||||||
|
git config --global user.email "user@example.com"
|
||||||
|
git config --global user.name "User"
|
||||||
|
./y.rs prepare
|
||||||
|
|
||||||
|
- name: Patch Cranelift
|
||||||
|
run: |
|
||||||
|
sed -i 's/cranelift-codegen = { version = "\w*.\w*.\w*", features = \["unwind", "all-arch"\] }/cranelift-codegen = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", features = ["unwind", "all-arch"] }/' Cargo.toml
|
||||||
|
sed -i 's/cranelift-frontend = "\w*.\w*.\w*"/cranelift-frontend = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||||
|
sed -i 's/cranelift-module = "\w*.\w*.\w*"/cranelift-module = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||||
|
sed -i 's/cranelift-native = "\w*.\w*.\w*"/cranelift-native = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||||
|
sed -i 's/cranelift-jit = { version = "\w*.\w*.\w*", optional = true }/cranelift-jit = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", optional = true }/' Cargo.toml
|
||||||
|
sed -i 's/cranelift-object = "\w*.\w*.\w*"/cranelift-object = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
|
||||||
|
|
||||||
|
sed -i 's/gimli = { version = "0.25.0", default-features = false, features = \["write"\]}/gimli = { version = "0.26.1", default-features = false, features = ["write"] }/' Cargo.toml
|
||||||
|
|
||||||
|
cat Cargo.toml
|
||||||
|
|
||||||
|
- name: Build without unstable features
|
||||||
|
# This is the config rust-lang/rust uses for builds
|
||||||
|
run: ./y.rs build --no-unstable-features
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: ./y.rs build --sysroot none
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
# Enable backtraces for easier debugging
|
||||||
|
export RUST_BACKTRACE=1
|
||||||
|
|
||||||
|
# Reduce amount of benchmark runs as they are slow
|
||||||
|
export COMPILE_RUNS=2
|
||||||
|
export RUN_RUNS=2
|
||||||
|
|
||||||
|
# Enable extra checks
|
||||||
|
export CG_CLIF_ENABLE_VERIFIER=1
|
||||||
|
|
||||||
|
./test.sh
|
@ -5,6 +5,7 @@
|
|||||||
"rust-analyzer.assist.importEnforceGranularity": true,
|
"rust-analyzer.assist.importEnforceGranularity": true,
|
||||||
"rust-analyzer.assist.importPrefix": "crate",
|
"rust-analyzer.assist.importPrefix": "crate",
|
||||||
"rust-analyzer.cargo.runBuildScripts": true,
|
"rust-analyzer.cargo.runBuildScripts": true,
|
||||||
|
"rust-analyzer.cargo.features": ["unstable-features"]
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"./Cargo.toml",
|
"./Cargo.toml",
|
||||||
//"./build_sysroot/sysroot_src/src/libstd/Cargo.toml",
|
//"./build_sysroot/sysroot_src/src/libstd/Cargo.toml",
|
||||||
|
86
compiler/rustc_codegen_cranelift/Cargo.lock
generated
86
compiler/rustc_codegen_cranelift/Cargo.lock
generated
@ -4,9 +4,9 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.42"
|
version = "1.0.51"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
|
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ar"
|
name = "ar"
|
||||||
@ -21,9 +21,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -33,16 +33,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-bforest"
|
name = "cranelift-bforest"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc0cb7df82c8cf8f2e6a8dd394a0932a71369c160cc9b027dca414fced242513"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen"
|
name = "cranelift-codegen"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe4463c15fa42eee909e61e5eac4866b7c6d22d0d8c621e57a0c5380753bfa8c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-bforest",
|
"cranelift-bforest",
|
||||||
"cranelift-codegen-meta",
|
"cranelift-codegen-meta",
|
||||||
@ -57,8 +59,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-meta"
|
name = "cranelift-codegen-meta"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "793f6a94a053a55404ea16e1700202a88101672b8cd6b4df63e13cde950852bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
@ -66,18 +69,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-shared"
|
name = "cranelift-codegen-shared"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44aa1846df275bce5eb30379d65964c7afc63c05a117076e62a119c25fe174be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-entity"
|
name = "cranelift-entity"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3a45d8d6318bf8fc518154d9298eab2a8154ec068a8885ff113f6db8d69bb3a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-frontend"
|
name = "cranelift-frontend"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e07339bd461766deb7605169de039e01954768ff730fa1254e149001884a8525"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"log",
|
"log",
|
||||||
@ -87,8 +93,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-jit"
|
name = "cranelift-jit"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e8f0d60fb5d67f7a1e5c49db38ba96d1c846921faef02085fc5590b74781747"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
@ -104,8 +111,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-module"
|
name = "cranelift-module"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "825ac7e0959cbe7ddc9cc21209f0319e611a57f9fcb2b723861fe7ef2017e651"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
@ -115,8 +123,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-native"
|
name = "cranelift-native"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03e2fca76ff57e0532936a71e3fc267eae6a19a86656716479c66e7f912e3d7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"libc",
|
"libc",
|
||||||
@ -125,8 +134,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-object"
|
name = "cranelift-object"
|
||||||
version = "0.76.0"
|
version = "0.78.0"
|
||||||
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55500d0fc9bb05c0944fc4506649249d28f55bd4fe95b87f0e55bf41058f0e6d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
@ -138,9 +148,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
@ -172,9 +182,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.98"
|
version = "0.2.112"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@ -206,15 +216,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.0"
|
version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.26.0"
|
version = "0.27.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
|
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
@ -223,9 +233,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regalloc"
|
name = "regalloc"
|
||||||
version = "0.0.31"
|
version = "0.0.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
|
checksum = "a6304468554ed921da3d32c355ea107b8d13d7b8996c3adfb7aab48d3bc321f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
@ -271,15 +281,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.6.1"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.1"
|
version = "0.12.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0652da4c4121005e9ed22b79f6c5f2d9e2752906b53a33e9490489ba421a6fb"
|
checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
|
@ -8,23 +8,23 @@ crate-type = ["dylib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# These have to be in sync with each other
|
# These have to be in sync with each other
|
||||||
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", features = ["unwind", "all-arch"] }
|
cranelift-codegen = { version = "0.78.0", features = ["unwind", "all-arch"] }
|
||||||
cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
cranelift-frontend = "0.78.0"
|
||||||
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
cranelift-module = "0.78.0"
|
||||||
cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
cranelift-native = "0.78.0"
|
||||||
cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", optional = true }
|
cranelift-jit = { version = "0.78.0", optional = true }
|
||||||
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git" }
|
cranelift-object = "0.78.0"
|
||||||
target-lexicon = "0.12.0"
|
target-lexicon = "0.12.0"
|
||||||
gimli = { version = "0.25.0", default-features = false, features = ["write"]}
|
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" }
|
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
libloading = { version = "0.6.0", optional = true }
|
libloading = { version = "0.6.0", optional = true }
|
||||||
smallvec = "1.6.1"
|
smallvec = "1.6.1"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
# Uncomment to use local checkout of cranelift
|
# Uncomment to use local checkout of cranelift
|
||||||
#[patch."https://github.com/bytecodealliance/wasmtime.git"]
|
|
||||||
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
|
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
|
||||||
#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
|
#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
|
||||||
#cranelift-module = { path = "../wasmtime/cranelift/module" }
|
#cranelift-module = { path = "../wasmtime/cranelift/module" }
|
||||||
@ -32,7 +32,6 @@ smallvec = "1.6.1"
|
|||||||
#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
|
#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
|
||||||
#cranelift-object = { path = "../wasmtime/cranelift/object" }
|
#cranelift-object = { path = "../wasmtime/cranelift/object" }
|
||||||
|
|
||||||
#[patch.crates-io]
|
|
||||||
#gimli = { path = "../" }
|
#gimli = { path = "../" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@ -41,31 +40,12 @@ unstable-features = ["jit", "inline_asm"]
|
|||||||
jit = ["cranelift-jit", "libloading"]
|
jit = ["cranelift-jit", "libloading"]
|
||||||
inline_asm = []
|
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
|
# 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.
|
# 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]
|
[profile.release.build-override]
|
||||||
opt-level = 0
|
opt-level = 0
|
||||||
debug = false
|
debug = false
|
||||||
|
|
||||||
[profile.dev.package.cranelift-codegen-meta]
|
|
||||||
opt-level = 0
|
|
||||||
debug = false
|
|
||||||
|
|
||||||
[profile.release.package.cranelift-codegen-meta]
|
[profile.release.package.cranelift-codegen-meta]
|
||||||
opt-level = 0
|
opt-level = 0
|
||||||
debug = false
|
debug = false
|
||||||
|
@ -37,7 +37,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
|
|||||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||||
|
|
||||||
```bash
|
```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.
|
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||||
|
@ -40,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.70"
|
version = "1.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -56,7 +56,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.50"
|
version = "0.1.66"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
@ -67,9 +67,9 @@ version = "0.0.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dlmalloc"
|
name = "dlmalloc"
|
||||||
version = "0.2.1"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
|
checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"libc",
|
"libc",
|
||||||
@ -132,9 +132,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.102"
|
version = "0.2.112"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
|
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
@ -2,9 +2,29 @@ use std::env;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
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");
|
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 {
|
match channel {
|
||||||
"debug" => {}
|
"debug" => {}
|
||||||
@ -14,25 +34,20 @@ pub(crate) fn build_backend(channel: &str, host_triple: &str) -> PathBuf {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the rpath to make the cg_clif executable find librustc_codegen_cranelift without changing
|
||||||
|
// LD_LIBRARY_PATH
|
||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
if cfg!(target_os = "macos") {
|
if cfg!(target_os = "macos") {
|
||||||
cmd.env(
|
rustflags += " -Csplit-debuginfo=unpacked \
|
||||||
"RUSTFLAGS",
|
|
||||||
"-Csplit-debuginfo=unpacked \
|
|
||||||
-Clink-arg=-Wl,-rpath,@loader_path/../lib \
|
-Clink-arg=-Wl,-rpath,@loader_path/../lib \
|
||||||
-Zosx-rpath-install-name"
|
-Zosx-rpath-install-name";
|
||||||
.to_string()
|
|
||||||
+ env::var("RUSTFLAGS").as_deref().unwrap_or(""),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
cmd.env(
|
rustflags += " -Clink-arg=-Wl,-rpath=$ORIGIN/../lib ";
|
||||||
"RUSTFLAGS",
|
|
||||||
"-Clink-arg=-Wl,-rpath=$ORIGIN/../lib ".to_string()
|
|
||||||
+ env::var("RUSTFLAGS").as_deref().unwrap_or(""),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.env("RUSTFLAGS", rustflags);
|
||||||
|
|
||||||
eprintln!("[BUILD] rustc_codegen_cranelift");
|
eprintln!("[BUILD] rustc_codegen_cranelift");
|
||||||
crate::utils::spawn_and_wait(cmd);
|
crate::utils::spawn_and_wait(cmd);
|
||||||
|
|
||||||
|
@ -46,9 +46,9 @@ pub(crate) fn build_sysroot(
|
|||||||
// Build and copy cargo wrapper
|
// Build and copy cargo wrapper
|
||||||
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
||||||
build_cargo_wrapper_cmd
|
build_cargo_wrapper_cmd
|
||||||
.arg("scripts/cargo.rs")
|
.arg("scripts/cargo-clif.rs")
|
||||||
.arg("-o")
|
.arg("-o")
|
||||||
.arg(target_dir.join("cargo"))
|
.arg(target_dir.join("cargo-clif"))
|
||||||
.arg("-g");
|
.arg("-g");
|
||||||
spawn_and_wait(build_cargo_wrapper_cmd);
|
spawn_and_wait(build_cargo_wrapper_cmd);
|
||||||
|
|
||||||
@ -193,8 +193,7 @@ fn build_clif_sysroot_for_triple(
|
|||||||
"RUSTC",
|
"RUSTC",
|
||||||
env::current_dir().unwrap().join(target_dir).join("bin").join("cg_clif_build_sysroot"),
|
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_DEFAULT_LIB_METADATA", "cg_clif");
|
||||||
build_cmd.env("CARGO_INCREMENTAL", "0").env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
|
|
||||||
spawn_and_wait(build_cmd);
|
spawn_and_wait(build_cmd);
|
||||||
|
|
||||||
// Copy all relevant files to the sysroot
|
// Copy all relevant files to the sysroot
|
||||||
|
@ -30,7 +30,7 @@ pub(crate) fn prepare() {
|
|||||||
clone_repo(
|
clone_repo(
|
||||||
"portable-simd",
|
"portable-simd",
|
||||||
"https://github.com/rust-lang/portable-simd",
|
"https://github.com/rust-lang/portable-simd",
|
||||||
"8cf7a62e5d2552961df51e5200aaa5b7c890a4bf",
|
"b8d6b6844602f80af79cd96401339ec594d472d8",
|
||||||
);
|
);
|
||||||
apply_patches("portable-simd", Path::new("portable-simd"));
|
apply_patches("portable-simd", Path::new("portable-simd"));
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ fn prepare_sysroot() {
|
|||||||
clone_repo(
|
clone_repo(
|
||||||
"build_sysroot/compiler-builtins",
|
"build_sysroot/compiler-builtins",
|
||||||
"https://github.com/rust-lang/compiler-builtins.git",
|
"https://github.com/rust-lang/compiler-builtins.git",
|
||||||
"0.1.50",
|
"0.1.66",
|
||||||
);
|
);
|
||||||
apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
|
apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
|
|||||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||||
|
|
||||||
```bash
|
```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.
|
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.
|
> The jit mode will probably need cargo integration to make this possible.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/cargo jit
|
$ $cg_clif_dir/build/cargo-clif jit
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
@ -45,7 +45,7 @@ There is also an experimental lazy jit mode. In this mode functions are only com
|
|||||||
first called.
|
first called.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/cargo lazy-jit
|
$ $cg_clif_dir/build/cargo-clif lazy-jit
|
||||||
```
|
```
|
||||||
|
|
||||||
## Shell
|
## Shell
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
// Copied from rustc ui test suite
|
||||||
|
|
||||||
|
// run-pass
|
||||||
|
//
|
||||||
|
// Test that we can handle unsized types with an extern type tail part.
|
||||||
|
// Regression test for issue #91827.
|
||||||
|
|
||||||
|
#![feature(const_ptr_offset_from)]
|
||||||
|
#![feature(const_slice_from_raw_parts)]
|
||||||
|
#![feature(extern_types)]
|
||||||
|
|
||||||
|
use std::ptr::addr_of;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
type Opaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for Opaque {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct List<T> {
|
||||||
|
len: usize,
|
||||||
|
data: [T; 0],
|
||||||
|
tail: Opaque,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ListImpl<T, const N: usize> {
|
||||||
|
len: usize,
|
||||||
|
data: [T; N],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> List<T> {
|
||||||
|
const fn as_slice(&self) -> &[T] {
|
||||||
|
unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, const N: usize> ListImpl<T, N> {
|
||||||
|
const fn as_list(&self) -> &List<T> {
|
||||||
|
unsafe { std::mem::transmute(self) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static A: ListImpl<u128, 3> = ListImpl {
|
||||||
|
len: 3,
|
||||||
|
data: [5, 6, 7],
|
||||||
|
};
|
||||||
|
pub static A_REF: &'static List<u128> = A.as_list();
|
||||||
|
pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
|
||||||
|
|
||||||
|
const fn tail_offset<T>(list: &List<T>) -> isize {
|
||||||
|
unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
|
||||||
|
// Check that interpreter and code generation agree about the position of the tail field.
|
||||||
|
assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
|
||||||
|
}
|
@ -129,6 +129,7 @@ fn call_return_u128_pair() {
|
|||||||
return_u128_pair();
|
return_u128_pair();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unreachable_code)] // FIXME false positive
|
||||||
fn main() {
|
fn main() {
|
||||||
take_unique(Unique {
|
take_unique(Unique {
|
||||||
pointer: 0 as *const (),
|
pointer: 0 as *const (),
|
||||||
|
@ -1,41 +1,20 @@
|
|||||||
From 6bfce5dc2cbf834c74dbccb7538adc08c6eb57e7 Mon Sep 17 00:00:00 2001
|
From 97c473937382a5b5858d9cce3c947855d23b2dc5 Mon Sep 17 00:00:00 2001
|
||||||
From: bjorn3 <bjorn3@users.noreply.github.com>
|
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
|
Subject: [PATCH] Disable unsupported tests
|
||||||
|
|
||||||
---
|
---
|
||||||
crates/core_simd/src/vector.rs | 2 ++
|
crates/core_simd/src/math.rs | 6 ++++++
|
||||||
crates/core_simd/src/math.rs | 4 ++++
|
crates/core_simd/src/vector.rs | 2 ++
|
||||||
crates/core_simd/tests/masks.rs | 12 ------------
|
crates/core_simd/tests/masks.rs | 2 ++
|
||||||
crates/core_simd/tests/ops_macros.rs | 6 ++++++
|
crates/core_simd/tests/ops_macros.rs | 4 ++++
|
||||||
crates/core_simd/tests/round.rs | 2 ++
|
4 files changed, 14 insertions(+)
|
||||||
6 files changed, 15 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
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
|
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
|
--- a/crates/core_simd/src/math.rs
|
||||||
+++ b/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),+) => {
|
($($ty:ty),+) => {
|
||||||
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
|
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
|
||||||
|
|
||||||
@ -43,15 +22,15 @@ index 7290a28..e394730 100644
|
|||||||
/// Lanewise saturating add.
|
/// Lanewise saturating add.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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 {
|
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),+) => {
|
($($ty:ty),+) => {
|
||||||
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
|
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
|
||||||
|
|
||||||
@ -59,7 +38,23 @@ index 7290a28..e394730 100644
|
|||||||
/// Lanewise saturating add.
|
/// Lanewise saturating add.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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 {
|
pub fn saturating_neg(self) -> Self {
|
||||||
Self::splat(0).saturating_sub(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
|
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
|
--- a/crates/core_simd/tests/masks.rs
|
||||||
+++ b/crates/core_simd/tests/masks.rs
|
+++ b/crates/core_simd/tests/masks.rs
|
||||||
@@ -67,19 +67,6 @@ macro_rules! test_mask_api {
|
@@ -68,6 +68,7 @@ macro_rules! test_mask_api {
|
||||||
assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]);
|
|
||||||
assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
|
assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
|
||||||
}
|
}
|
||||||
-
|
|
||||||
- #[cfg(feature = "generic_const_exprs")]
|
+ /*
|
||||||
- #[test]
|
#[cfg(feature = "generic_const_exprs")]
|
||||||
- fn roundtrip_bitmask_conversion() {
|
#[test]
|
||||||
- let values = [
|
fn roundtrip_bitmask_conversion() {
|
||||||
- true, false, false, true, false, false, true, false,
|
@@ -80,6 +81,7 @@ macro_rules! test_mask_api {
|
||||||
- true, true, false, false, false, false, false, true,
|
assert_eq!(bitmask, [0b01001001, 0b10000011]);
|
||||||
- ];
|
assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
|
||||||
- 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);
|
|
||||||
- }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
|
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
|
--- a/crates/core_simd/tests/ops_macros.rs
|
||||||
+++ b/crates/core_simd/tests/ops_macros.rs
|
+++ b/crates/core_simd/tests/ops_macros.rs
|
||||||
@@ -435,6 +435,7 @@ macro_rules! impl_float_tests {
|
@@ -567,6 +567,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 {
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +114,7 @@ index cb39e73..fc0ebe1 100644
|
|||||||
fn horizontal_max<const LANES: usize>() {
|
fn horizontal_max<const LANES: usize>() {
|
||||||
test_helpers::test_1(&|x| {
|
test_helpers::test_1(&|x| {
|
||||||
let vmax = Vector::<LANES>::from_array(x).horizontal_max();
|
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(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -127,26 +122,22 @@ index cb39e73..fc0ebe1 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
|
@@ -604,6 +606,7 @@ macro_rules! impl_float_tests {
|
||||||
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 {
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
+ /*
|
||||||
fn round<const LANES: usize>() {
|
fn mul_add<const LANES: usize>() {
|
||||||
test_helpers::test_unary_elementwise(
|
test_helpers::test_ternary_elementwise(
|
||||||
&Vector::<LANES>::round,
|
&Vector::<LANES>::mul_add,
|
||||||
@@ -32,6 +33,7 @@ macro_rules! float_rounding_test {
|
@@ -611,6 +614,7 @@ macro_rules! impl_float_tests {
|
||||||
&|_| true,
|
&|_, _, _| true,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
+ */
|
||||||
}
|
}
|
||||||
+ */
|
}
|
||||||
|
}
|
||||||
fn trunc<const LANES: usize>() {
|
|
||||||
test_helpers::test_unary_elementwise(
|
|
||||||
--
|
--
|
||||||
2.26.2.7.g19db9cfb68
|
2.26.2.7.g19db9cfb68
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ index fa96b7a..2854f9c 100644
|
|||||||
inner::monotonize(raw)
|
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")]
|
+#[cfg(target_has_atomic = "64")]
|
||||||
pub mod inner {
|
pub mod inner {
|
||||||
use crate::sync::atomic::AtomicU64;
|
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 {
|
pub mod inner {
|
||||||
use crate::sync::atomic::AtomicU128;
|
use crate::sync::atomic::AtomicU128;
|
||||||
@@ -94,8 +95,9 @@ pub mod inner {
|
@@ -94,8 +95,9 @@ pub mod inner {
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
From 0ffdd8eda8df364391c8ac6e1ce92c73ba9254d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: bjorn3 <bjorn3@users.noreply.github.com>
|
||||||
|
Date: Fri, 3 Dec 2021 12:16:30 +0100
|
||||||
|
Subject: [PATCH] Disable long running tests
|
||||||
|
|
||||||
|
---
|
||||||
|
library/core/tests/slice.rs | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
|
||||||
|
index 2c8f00a..44847ee 100644
|
||||||
|
--- a/library/core/tests/slice.rs
|
||||||
|
+++ b/library/core/tests/slice.rs
|
||||||
|
@@ -2332,7 +2332,8 @@ macro_rules! empty_max_mut {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
|
||||||
|
take_tests! {
|
||||||
|
slice: &[(); usize::MAX], method: take,
|
||||||
|
(take_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]),
|
||||||
|
@@ -2345,3 +2347,4 @@ take_tests! {
|
||||||
|
(take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
|
||||||
|
(take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
|
||||||
|
}
|
||||||
|
+*/
|
||||||
|
--
|
||||||
|
2.26.2.7.g19db9cfb68
|
||||||
|
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2021-09-19"
|
channel = "nightly-2021-12-30"
|
||||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||||
|
@ -42,7 +42,7 @@ fn main() {
|
|||||||
"RUSTFLAGS",
|
"RUSTFLAGS",
|
||||||
env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
|
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(env::args().skip(2))
|
||||||
.chain([
|
.chain([
|
||||||
"--".to_string(),
|
"--".to_string(),
|
||||||
@ -56,7 +56,7 @@ fn main() {
|
|||||||
"RUSTFLAGS",
|
"RUSTFLAGS",
|
||||||
env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
|
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(env::args().skip(2))
|
||||||
.chain([
|
.chain([
|
||||||
"--".to_string(),
|
"--".to_string(),
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
./y.rs build
|
./y.rs build --no-unstable-features
|
||||||
source scripts/config.sh
|
source scripts/config.sh
|
||||||
|
|
||||||
echo "[SETUP] Rust fork"
|
echo "[SETUP] Rust fork"
|
||||||
@ -33,7 +33,7 @@ index d95b5b7f17f..00b6f0e3635 100644
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
core = { path = "../core" }
|
core = { path = "../core" }
|
||||||
-compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
|
-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]
|
[dev-dependencies]
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
@ -53,5 +53,6 @@ local-rebuild = true
|
|||||||
[rust]
|
[rust]
|
||||||
codegen-backends = ["cranelift"]
|
codegen-backends = ["cranelift"]
|
||||||
deny-warnings = false
|
deny-warnings = false
|
||||||
|
verbose-tests = false
|
||||||
EOF
|
EOF
|
||||||
popd
|
popd
|
||||||
|
@ -10,7 +10,7 @@ pushd rust
|
|||||||
|
|
||||||
cargo install ripgrep
|
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
|
for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto|// needs-asm-support" src/test/ui); do
|
||||||
rm $test
|
rm $test
|
||||||
done
|
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-26655.rs
|
||||||
rm src/test/ui/issues/issue-29485.rs
|
rm src/test/ui/issues/issue-29485.rs
|
||||||
rm src/test/ui/issues/issue-30018-panic.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/sepcomp/sepcomp-unwind.rs
|
||||||
rm src/test/ui/structs-enums/unit-like-struct-drop-run.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/threads-sendsync/task-stderr.rs
|
||||||
rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
|
rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
|
||||||
rm src/test/ui/drop/drop-trait-enum.rs
|
rm src/test/ui/drop/drop-trait-enum.rs
|
||||||
rm src/test/ui/numbers-arithmetic/issue-8460.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/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/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/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-33992.rs # unsupported linkages
|
||||||
rm src/test/ui/issues/issue-51947.rs # same
|
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/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_misc_casts.rs # depends on deduplication of constants
|
||||||
rm src/test/ui/mir/mir_raw_fat_ptr.rs # same
|
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/hashes/inline_asm.rs # inline asm
|
||||||
rm src/test/incremental/issue-72386.rs # same
|
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/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/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/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 -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 -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-multifile.rs # differing warning
|
||||||
rm src/test/ui/json-bom-plus-crlf.rs # same
|
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/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/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
|
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/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/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"
|
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
|
popd
|
||||||
|
@ -35,6 +35,10 @@ function base_sysroot_tests() {
|
|||||||
$MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
|
$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
|
$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"
|
echo "[AOT] alloc_system"
|
||||||
$MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"
|
$MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"
|
||||||
|
|
||||||
@ -76,73 +80,73 @@ function base_sysroot_tests() {
|
|||||||
|
|
||||||
function extended_sysroot_tests() {
|
function extended_sysroot_tests() {
|
||||||
pushd rand
|
pushd rand
|
||||||
../build/cargo clean
|
../build/cargo-clif clean
|
||||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||||
echo "[TEST] rust-random/rand"
|
echo "[TEST] rust-random/rand"
|
||||||
../build/cargo test --workspace
|
../build/cargo-clif test --workspace
|
||||||
else
|
else
|
||||||
echo "[AOT] rust-random/rand"
|
echo "[AOT] rust-random/rand"
|
||||||
../build/cargo build --workspace --target $TARGET_TRIPLE --tests
|
../build/cargo-clif build --workspace --target $TARGET_TRIPLE --tests
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd simple-raytracer
|
pushd simple-raytracer
|
||||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||||
echo "[BENCH COMPILE] ebobby/simple-raytracer"
|
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" \
|
"RUSTC=rustc RUSTFLAGS='' cargo build" \
|
||||||
"../build/cargo build"
|
"../build/cargo-clif build"
|
||||||
|
|
||||||
echo "[BENCH RUN] ebobby/simple-raytracer"
|
echo "[BENCH RUN] ebobby/simple-raytracer"
|
||||||
cp ./target/debug/main ./raytracer_cg_clif
|
cp ./target/debug/main ./raytracer_cg_clif
|
||||||
hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
|
hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
|
||||||
else
|
else
|
||||||
../build/cargo clean
|
../build/cargo-clif clean
|
||||||
echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
|
echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
|
||||||
echo "[COMPILE] ebobby/simple-raytracer"
|
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)"
|
echo "[BENCH RUN] ebobby/simple-raytracer (skipped)"
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd build_sysroot/sysroot_src/library/core/tests
|
pushd build_sysroot/sysroot_src/library/core/tests
|
||||||
echo "[TEST] libcore"
|
echo "[TEST] libcore"
|
||||||
../../../../../build/cargo clean
|
../../../../../build/cargo-clif clean
|
||||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||||
../../../../../build/cargo test
|
../../../../../build/cargo-clif test
|
||||||
else
|
else
|
||||||
../../../../../build/cargo build --target $TARGET_TRIPLE --tests
|
../../../../../build/cargo-clif build --target $TARGET_TRIPLE --tests
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd regex
|
pushd regex
|
||||||
echo "[TEST] rust-lang/regex example shootout-regex-dna"
|
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
|
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
|
# 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
|
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||||
cat examples/regexdna-input.txt \
|
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
|
| grep -v "Spawned thread" > res.txt
|
||||||
diff -u res.txt examples/regexdna-output.txt
|
diff -u res.txt examples/regexdna-output.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||||
echo "[TEST] rust-lang/regex tests"
|
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
|
else
|
||||||
echo "[AOT] rust-lang/regex tests"
|
echo "[AOT] rust-lang/regex tests"
|
||||||
../build/cargo build --tests --target $TARGET_TRIPLE
|
../build/cargo-clif build --tests --target $TARGET_TRIPLE
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd portable-simd
|
pushd portable-simd
|
||||||
echo "[TEST] rust-lang/portable-simd"
|
echo "[TEST] rust-lang/portable-simd"
|
||||||
../build/cargo clean
|
../build/cargo-clif clean
|
||||||
../build/cargo build --all-targets --target $TARGET_TRIPLE
|
../build/cargo-clif build --all-targets --target $TARGET_TRIPLE
|
||||||
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
|
||||||
../build/cargo test -q
|
../build/cargo-clif test -q
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,11 @@ pub(crate) use self::returning::codegen_return;
|
|||||||
|
|
||||||
fn clif_sig_from_fn_abi<'tcx>(
|
fn clif_sig_from_fn_abi<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
triple: &target_lexicon::Triple,
|
default_call_conv: CallConv,
|
||||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
let call_conv = match fn_abi.conv {
|
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_64SysV => CallConv::SystemV,
|
||||||
Conv::X86_64Win64 => CallConv::WindowsFastcall,
|
Conv::X86_64Win64 => CallConv::WindowsFastcall,
|
||||||
Conv::ArmAapcs
|
Conv::ArmAapcs
|
||||||
@ -55,7 +55,7 @@ pub(crate) fn get_function_sig<'tcx>(
|
|||||||
assert!(!inst.substs.needs_infer());
|
assert!(!inst.substs.needs_infer());
|
||||||
clif_sig_from_fn_abi(
|
clif_sig_from_fn_abi(
|
||||||
tcx,
|
tcx,
|
||||||
triple,
|
CallConv::triple_default(triple),
|
||||||
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
|
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
returns: Vec<AbiParam>,
|
returns: Vec<AbiParam>,
|
||||||
args: &[Value],
|
args: &[Value],
|
||||||
) -> &[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_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 func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
|
||||||
let call_inst = self.bcx.ins().call(func_ref, args);
|
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 (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);
|
let sig = fx.bcx.import_signature(sig);
|
||||||
|
|
||||||
(CallTarget::Indirect(sig, method), Some(ptr))
|
(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 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);
|
let sig = fx.bcx.import_signature(sig);
|
||||||
|
|
||||||
(CallTarget::Indirect(sig, func), None)
|
(CallTarget::Indirect(sig, func), None)
|
||||||
@ -531,7 +531,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
|||||||
let fn_abi =
|
let fn_abi =
|
||||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
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);
|
let sig = fx.bcx.import_signature(sig);
|
||||||
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
|
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
|
|||||||
.prefix
|
.prefix
|
||||||
.iter()
|
.iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|&kind| reg_to_abi_param(Reg { kind, size: cast.prefix_chunk_size }))
|
.map(|®| reg_to_abi_param(reg))
|
||||||
.chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))
|
.chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))
|
||||||
.collect::<SmallVec<_>>();
|
.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::Cast(cast) => cast_target_to_abi_params(cast),
|
||||||
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
|
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
|
||||||
if 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(
|
smallvec![apply_arg_attrs_to_abi_param(
|
||||||
AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructArgument(size),),
|
AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructArgument(size),),
|
||||||
attrs
|
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
|
// It may also be smaller for example when the type is a wrapper around an integer with a
|
||||||
// larger alignment than the integer.
|
// larger alignment than the integer.
|
||||||
size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16,
|
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 ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0));
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! Creation of ar archives like for the lib and staticlib crate type
|
//! Creation of ar archives like for the lib and staticlib crate type
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read, Seek};
|
use std::io::{self, Read, Seek};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@ -10,7 +9,7 @@ use rustc_codegen_ssa::back::archive::ArchiveBuilder;
|
|||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
|
||||||
use object::read::archive::ArchiveFile;
|
use object::read::archive::ArchiveFile;
|
||||||
use object::{Object, ObjectSymbol, ReadCache, SymbolKind};
|
use object::{Object, ObjectSymbol, ReadCache};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ArchiveEntry {
|
enum ArchiveEntry {
|
||||||
@ -150,12 +149,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
|||||||
object
|
object
|
||||||
.symbols()
|
.symbols()
|
||||||
.filter_map(|symbol| {
|
.filter_map(|symbol| {
|
||||||
if symbol.is_undefined()
|
if symbol.is_undefined() || symbol.is_local() {
|
||||||
|| symbol.is_local()
|
|
||||||
|| symbol.kind() != SymbolKind::Data
|
|
||||||
&& symbol.kind() != SymbolKind::Text
|
|
||||||
&& symbol.kind() != SymbolKind::Tls
|
|
||||||
{
|
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
symbol.name().map(|name| name.as_bytes().to_vec()).ok()
|
symbol.name().map(|name| name.as_bytes().to_vec()).ok()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Codegen of a single function
|
//! Codegen of a single function
|
||||||
|
|
||||||
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
|
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
|
||||||
|
use rustc_ast::InlineAsmOptions;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::ty::adjustment::PointerCast;
|
use rustc_middle::ty::adjustment::PointerCast;
|
||||||
use rustc_middle::ty::layout::FnAbiOf;
|
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();
|
(0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
|
||||||
|
|
||||||
// Make FunctionCx
|
// 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 clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
|
||||||
|
|
||||||
let mut fx = FunctionCx {
|
let mut fx = FunctionCx {
|
||||||
cx,
|
cx,
|
||||||
module,
|
module,
|
||||||
tcx,
|
tcx,
|
||||||
|
target_config,
|
||||||
pointer_type,
|
pointer_type,
|
||||||
constants_cx: ConstantCx::new(),
|
constants_cx: ConstantCx::new(),
|
||||||
|
|
||||||
@ -71,8 +74,6 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||||||
clif_comments,
|
clif_comments,
|
||||||
source_info_set: indexmap::IndexSet::new(),
|
source_info_set: indexmap::IndexSet::new(),
|
||||||
next_ssa_var: 0,
|
next_ssa_var: 0,
|
||||||
|
|
||||||
inline_asm_index: 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let arg_uninhabited = fx
|
let arg_uninhabited = fx
|
||||||
@ -203,7 +204,6 @@ pub(crate) fn verify_func(
|
|||||||
tcx.sess.err(&format!("{:?}", err));
|
tcx.sess.err(&format!("{:?}", err));
|
||||||
let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error(
|
let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error(
|
||||||
&func,
|
&func,
|
||||||
None,
|
|
||||||
Some(Box::new(writer)),
|
Some(Box::new(writer)),
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
@ -239,7 +239,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
fx.add_comment(inst, terminator_head);
|
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 {
|
match &bb_data.terminator().kind {
|
||||||
TerminatorKind::Goto { target } => {
|
TerminatorKind::Goto { target } => {
|
||||||
@ -294,20 +295,18 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
AssertKind::BoundsCheck { ref len, ref index } => {
|
AssertKind::BoundsCheck { ref len, ref index } => {
|
||||||
let len = codegen_operand(fx, len).load_scalar(fx);
|
let len = codegen_operand(fx, len).load_scalar(fx);
|
||||||
let index = codegen_operand(fx, index).load_scalar(fx);
|
let index = codegen_operand(fx, index).load_scalar(fx);
|
||||||
let location = fx
|
let location = fx.get_caller_location(source_info.span).load_scalar(fx);
|
||||||
.get_caller_location(bb_data.terminator().source_info.span)
|
|
||||||
.load_scalar(fx);
|
|
||||||
|
|
||||||
codegen_panic_inner(
|
codegen_panic_inner(
|
||||||
fx,
|
fx,
|
||||||
rustc_hir::LangItem::PanicBoundsCheck,
|
rustc_hir::LangItem::PanicBoundsCheck,
|
||||||
&[index, len, location],
|
&[index, len, location],
|
||||||
bb_data.terminator().source_info.span,
|
source_info.span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let msg_str = msg.description();
|
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,
|
options,
|
||||||
destination,
|
destination,
|
||||||
line_spans: _,
|
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(
|
crate::inline_asm::codegen_inline_asm(
|
||||||
fx,
|
fx,
|
||||||
bb_data.terminator().source_info.span,
|
source_info.span,
|
||||||
template,
|
template,
|
||||||
operands,
|
operands,
|
||||||
*options,
|
*options,
|
||||||
@ -415,7 +422,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
}
|
}
|
||||||
TerminatorKind::Drop { place, target, unwind: _ } => {
|
TerminatorKind::Drop { place, target, unwind: _ } => {
|
||||||
let drop_place = codegen_place(fx, *place);
|
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);
|
let target_block = fx.get_block(*target);
|
||||||
fx.bcx.ins().jump(target_block, &[]);
|
fx.bcx.ins().jump(target_block, &[]);
|
||||||
@ -671,7 +678,7 @@ fn codegen_stmt<'tcx>(
|
|||||||
// FIXME use emit_small_memset where possible
|
// FIXME use emit_small_memset where possible
|
||||||
let addr = lval.to_ptr().get_addr(fx);
|
let addr = lval.to_ptr().get_addr(fx);
|
||||||
let val = operand.load_scalar(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 {
|
} else {
|
||||||
let loop_block = fx.bcx.create_block();
|
let loop_block = fx.bcx.create_block();
|
||||||
let loop_block2 = 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);
|
let operand = operand.load_scalar(fx);
|
||||||
lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
|
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) => {
|
Rvalue::NullaryOp(null_op, ty) => {
|
||||||
assert!(
|
assert!(
|
||||||
lval.layout()
|
lval.layout()
|
||||||
@ -742,10 +725,8 @@ fn codegen_stmt<'tcx>(
|
|||||||
let val = match null_op {
|
let val = match null_op {
|
||||||
NullOp::SizeOf => layout.size.bytes(),
|
NullOp::SizeOf => layout.size.bytes(),
|
||||||
NullOp::AlignOf => layout.align.abi.bytes(),
|
NullOp::AlignOf => layout.align.abi.bytes(),
|
||||||
NullOp::Box => unreachable!(),
|
|
||||||
};
|
};
|
||||||
let val =
|
let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
|
||||||
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
|
|
||||||
lval.write_cvalue(fx, val);
|
lval.write_cvalue(fx, val);
|
||||||
}
|
}
|
||||||
Rvalue::Aggregate(ref kind, ref operands) => match kind.as_ref() {
|
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 elem_size: u64 = pointee.size.bytes();
|
||||||
let bytes =
|
let bytes =
|
||||||
if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
|
if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
|
||||||
fx.bcx.call_memcpy(fx.module.target_config(), dst, src, bytes);
|
fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::ty::layout::{
|
use rustc_middle::ty::layout::{
|
||||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
|
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) cx: &'clif mut crate::CodegenCx<'tcx>,
|
||||||
pub(crate) module: &'m mut dyn Module,
|
pub(crate) module: &'m mut dyn Module,
|
||||||
pub(crate) tcx: TyCtxt<'tcx>,
|
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) constants_cx: ConstantCx,
|
||||||
|
|
||||||
pub(crate) instance: Instance<'tcx>,
|
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`.
|
/// This should only be accessed by `CPlace::new_var`.
|
||||||
pub(crate) next_ssa_var: u32,
|
pub(crate) next_ssa_var: u32,
|
||||||
|
|
||||||
pub(crate) inline_asm_index: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
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())
|
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 {
|
pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value {
|
||||||
let mut data_ctx = DataContext::new();
|
let mut data_ctx = DataContext::new();
|
||||||
data_ctx.define(msg.as_bytes().to_vec().into_boxed_slice());
|
data_ctx.define(msg.as_bytes().to_vec().into_boxed_slice());
|
||||||
|
@ -369,7 +369,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||||||
TodoItem::Static(def_id) => {
|
TodoItem::Static(def_id) => {
|
||||||
//println!("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();
|
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 {
|
if let Some(section_name) = section_name {
|
||||||
let (segment_name, section_name) = if tcx.sess.target.is_like_osx {
|
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(',') {
|
if let Some(names) = section_name.split_once(',') {
|
||||||
names
|
names
|
||||||
} else {
|
} else {
|
||||||
@ -397,7 +398,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
("", &*section_name)
|
("", section_name.as_str())
|
||||||
};
|
};
|
||||||
data_ctx.set_segment_section(segment_name, section_name);
|
data_ctx.set_segment_section(segment_name, section_name);
|
||||||
}
|
}
|
||||||
|
@ -67,10 +67,8 @@ impl WriterRelocate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform the collected relocations to be usable for JIT usage.
|
/// 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> {
|
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(..) {
|
for reloc in self.relocs.drain(..) {
|
||||||
match reloc.name {
|
match reloc.name {
|
||||||
super::DebugRelocName::Section(_) => unreachable!(),
|
super::DebugRelocName::Section(_) => unreachable!(),
|
||||||
|
@ -10,7 +10,7 @@ use crate::prelude::*;
|
|||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
|
||||||
use cranelift_codegen::entity::EntityRef;
|
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::isa::TargetIsa;
|
||||||
use cranelift_codegen::ValueLocRange;
|
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 emit::{DebugReloc, DebugRelocName};
|
||||||
pub(crate) use unwind::UnwindContext;
|
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> {
|
pub(crate) struct DebugContext<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
||||||
@ -60,6 +51,11 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
address_size: isa.frontend_config().pointer_bytes(),
|
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 mut dwarf = DwarfUnit::new(encoding);
|
||||||
|
|
||||||
let producer = format!(
|
let producer = format!(
|
||||||
@ -67,7 +63,12 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
rustc_interface::util::version_str().unwrap_or("unknown version"),
|
rustc_interface::util::version_str().unwrap_or("unknown version"),
|
||||||
cranelift_codegen::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() {
|
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let name = path.to_string_lossy().into_owned();
|
let name = path.to_string_lossy().into_owned();
|
||||||
@ -103,7 +104,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
DebugContext {
|
DebugContext {
|
||||||
tcx,
|
tcx,
|
||||||
|
|
||||||
endian: target_endian(tcx),
|
endian,
|
||||||
|
|
||||||
dwarf,
|
dwarf,
|
||||||
unit_range_list: RangeList(Vec::new()),
|
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.
|
// FIXME make it more reliable and implement scopes before re-enabling this.
|
||||||
if false {
|
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() {
|
for (local, _local_decl) in mir.local_decls.iter_enumerated() {
|
||||||
let ty = self.tcx.subst_and_normalize_erasing_regions(
|
let ty = self.tcx.subst_and_normalize_erasing_regions(
|
||||||
@ -264,7 +265,6 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
self,
|
self,
|
||||||
isa,
|
isa,
|
||||||
symbol,
|
symbol,
|
||||||
context,
|
|
||||||
&local_map,
|
&local_map,
|
||||||
&value_labels_ranges,
|
&value_labels_ranges,
|
||||||
Place { local, projection: ty::List::empty() },
|
Place { local, projection: ty::List::empty() },
|
||||||
@ -283,7 +283,6 @@ fn place_location<'tcx>(
|
|||||||
debug_context: &mut DebugContext<'tcx>,
|
debug_context: &mut DebugContext<'tcx>,
|
||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
symbol: usize,
|
symbol: usize,
|
||||||
context: &Context,
|
|
||||||
local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
|
local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
|
||||||
#[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
|
#[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
|
||||||
ValueLabel,
|
ValueLabel,
|
||||||
@ -306,12 +305,7 @@ fn place_location<'tcx>(
|
|||||||
addend: i64::from(value_loc_range.start),
|
addend: i64::from(value_loc_range.start),
|
||||||
},
|
},
|
||||||
end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
|
end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
|
||||||
data: translate_loc(
|
data: translate_loc(isa, value_loc_range.loc).unwrap(),
|
||||||
isa,
|
|
||||||
value_loc_range.loc,
|
|
||||||
&context.func.stack_slots,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
@ -340,34 +334,14 @@ fn place_location<'tcx>(
|
|||||||
AttributeValue::Exprloc(Expression::new())
|
AttributeValue::Exprloc(Expression::new())
|
||||||
|
|
||||||
// For PointerBase::Stack:
|
// 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
|
// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
|
||||||
fn translate_loc(
|
fn translate_loc(isa: &dyn TargetIsa, loc: LabelValueLoc) -> Option<Expression> {
|
||||||
isa: &dyn TargetIsa,
|
|
||||||
loc: LabelValueLoc,
|
|
||||||
stack_slots: &StackSlots,
|
|
||||||
) -> Option<Expression> {
|
|
||||||
match loc {
|
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) => {
|
LabelValueLoc::Reg(reg) => {
|
||||||
let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
|
let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
|
||||||
let mut expr = Expression::new();
|
let mut expr = Expression::new();
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::convert::{TryFrom, TryInto};
|
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
|
||||||
use cranelift_module::FuncId;
|
use cranelift_module::FuncId;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user