diff --git a/Cargo.lock b/Cargo.lock index 5c767817ae563..f8fa2971b49d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,9 +24,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" dependencies = [ "memchr", ] @@ -53,7 +53,7 @@ dependencies = [ "markup5ever_rcdom", "matches", "tendril", - "url 2.1.0", + "url 2.1.1", ] [[package]] @@ -77,7 +77,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -86,39 +86,26 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "anyhow" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" +checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" [[package]] name = "arc-swap" -version = "0.3.7" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" [[package]] -name = "argon2rs" -version = "0.2.5" +name = "arrayref" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" -dependencies = [ - "blake2-rfc", - "scoped_threadpool", -] - -[[package]] -name = "arrayvec" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -dependencies = [ - "nodrop", -] +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" @@ -134,7 +121,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -155,6 +142,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + [[package]] name = "bitflags" version = "1.2.1" @@ -163,20 +156,21 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bitmaps" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e039a80914325b37fde728ef7693c212f0ac913d5599607d7b95a9484aae0b" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" dependencies = [ "typenum", ] [[package]] -name = "blake2-rfc" -version = "0.2.18" +name = "blake2b_simd" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" dependencies = [ - "arrayvec 0.4.7", + "arrayref", + "arrayvec", "constant_time_eq", ] @@ -220,14 +214,14 @@ dependencies = [ "serde_json", "time", "toml", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "bstr" -version = "0.1.3" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853b090ce0f45d0265902666bf88039ea3da825e33796716c511a1ec9c170036" +checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" dependencies = [ "memchr", ] @@ -262,15 +256,15 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.3.2" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "bytes" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" dependencies = [ "byteorder", "iovec", @@ -278,9 +272,9 @@ dependencies = [ [[package]] name = "bytesize" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" +checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da" [[package]] name = "cargo" @@ -306,9 +300,9 @@ dependencies = [ "git2", "git2-curl", "glob", - "hex 0.4.0", + "hex 0.4.2", "home", - "humantime 2.0.0", + "humantime 2.0.1", "ignore", "im-rc", "jobserver", @@ -318,7 +312,7 @@ dependencies = [ "libgit2-sys", "log", "memchr", - "miow 0.3.3", + "miow 0.3.5", "num_cpus", "opener", "openssl", @@ -339,9 +333,9 @@ dependencies = [ "toml", "unicode-width", "unicode-xid", - "url 2.1.0", + "url 2.1.1", "walkdir", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -382,16 +376,15 @@ dependencies = [ "remove_dir_all", "serde_json", "tar", - "url 2.1.0", + "url 2.1.1", ] [[package]] name = "cargo_metadata" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "929766d993a2fde7a0ae962ee82429069cd7b68839cd9375b98efd719df65d3a" +checksum = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426" dependencies = [ - "failure", "semver 0.9.0", "serde", "serde_derive", @@ -485,9 +478,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.6" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" +checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" dependencies = [ "num-integer", "num-traits", @@ -496,9 +489,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.0" +version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term 0.11.0", "atty", @@ -546,11 +539,11 @@ dependencies = [ "regex-syntax", "semver 0.9.0", "serde", - "smallvec 1.4.0", + "smallvec 1.4.2", "syn", "toml", "unicode-normalization", - "url 2.1.0", + "url 2.1.1", ] [[package]] @@ -562,11 +555,20 @@ dependencies = [ "bitflags", ] +[[package]] +name = "cloudabi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" +dependencies = [ + "bitflags", +] + [[package]] name = "cmake" -version = "0.1.42" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" +checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb" dependencies = [ "cc", ] @@ -579,7 +581,7 @@ checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" dependencies = [ "atty", "lazy_static", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -620,14 +622,14 @@ dependencies = [ "glob", "lazy_static", "libc", - "miow 0.3.3", + "miow 0.3.5", "regex", "rustfix", "serde", "serde_json", "tracing", "walkdir", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -641,7 +643,7 @@ dependencies = [ "getopts", "libc", "log", - "miow 0.3.3", + "miow 0.3.5", "regex", "rustfix", "serde", @@ -649,14 +651,14 @@ dependencies = [ "serde_json", "tempfile", "tester", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "constant_time_eq" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "core" @@ -690,7 +692,7 @@ dependencies = [ "percent-encoding 2.1.0", "serde", "serde_json", - "url 2.1.0", + "url 2.1.1", ] [[package]] @@ -704,33 +706,36 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" +checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6" dependencies = [ + "cfg-if", "crossbeam-utils 0.7.2", ] [[package]] name = "crossbeam-deque" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" dependencies = [ "crossbeam-epoch", - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] name = "crossbeam-epoch" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "arrayvec 0.4.7", + "autocfg", "cfg-if", - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.7.2", "lazy_static", + "maybe-uninit", "memoffset", "scopeguard", ] @@ -741,14 +746,25 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.6.6", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] name = "crossbeam-utils" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" dependencies = [ "cfg-if", "lazy_static", @@ -767,21 +783,21 @@ dependencies = [ [[package]] name = "crypto-hash" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" +checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" dependencies = [ "commoncrypto", "hex 0.3.2", "openssl", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "ctor" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1" +checksum = "39858aa5bac06462d4dd4b9164848eb81ffc4aa5c479746393598fd193afa227" dependencies = [ "quote", "syn", @@ -789,9 +805,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.25" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06aa71e9208a54def20792d877bc663d6aae0732b9852e612c4a933177c31283" +checksum = "9447ad28eee2a5cfb031c329d46bef77487244fff6a724b378885b8691a35f78" dependencies = [ "curl-sys", "libc", @@ -799,14 +815,14 @@ dependencies = [ "openssl-sys", "schannel", "socket2", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "curl-sys" -version = "0.4.25" +version = "0.4.34+curl-7.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c38ca47d60b86d0cc9d42caa90a0885669c2abc9791f871c81f58cdf39e979b" +checksum = "ad4eff0be6985b7e709f64b5a541f700e9ad1407190a29f4884319eb663ed1d6" dependencies = [ "cc", "libc", @@ -815,7 +831,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -837,9 +853,9 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.2" +version = "0.99.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" +checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" dependencies = [ "proc-macro2", "quote", @@ -848,9 +864,9 @@ dependencies = [ [[package]] name = "diff" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" [[package]] name = "difference" @@ -869,9 +885,9 @@ dependencies = [ [[package]] name = "directories" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccc83e029c3cebb4c8155c644d34e3a070ccdb4ff90d369c74cd73f7cb3c984" +checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ "cfg-if", "dirs-sys", @@ -879,9 +895,9 @@ dependencies = [ [[package]] name = "dirs" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" dependencies = [ "cfg-if", "dirs-sys", @@ -889,14 +905,13 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" dependencies = [ - "cfg-if", "libc", "redox_users", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -912,9 +927,9 @@ dependencies = [ [[package]] name = "either" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" +checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" [[package]] name = "elasticlunr-rs" @@ -979,14 +994,14 @@ name = "expand-yaml-anchors" version = "0.1.0" dependencies = [ "yaml-merge-keys", - "yaml-rust 0.4.3", + "yaml-rust 0.4.4", ] [[package]] name = "failure" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" dependencies = [ "backtrace", "failure_derive", @@ -1012,14 +1027,14 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "filetime" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e" +checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1043,9 +1058,9 @@ dependencies = [ [[package]] name = "fnv" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" @@ -1064,9 +1079,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fortanix-sgx-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8cbee5e872cf7db61a999a041f9bc4706ca7bf7df4cb914f53fabb1c1bc550" +checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -1080,19 +1095,13 @@ checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" [[package]] name = "fst" -version = "0.3.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d94485a00b1827b861dd9d1a2cc9764f9044d4c535514c0760a5a2012ef3399f" +checksum = "927fb434ff9f0115b215dc0efd2e4fbdd7448522a92a1aa37c77d6a2f8f1ebd6" dependencies = [ "byteorder", ] -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -1121,9 +1130,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" +checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" [[package]] name = "fwdansi" @@ -1179,9 +1188,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e02a51cd90229028c9bd8be0a0364f85b6b3199cccaa0ef39005ddbd5ac165" +checksum = "e6ac22e49b7d886b6802c66662b12609452248b1bc9e87d6d83ecea3db96f557" dependencies = [ "bitflags", "libc", @@ -1189,7 +1198,7 @@ dependencies = [ "log", "openssl-probe", "openssl-sys", - "url 2.1.0", + "url 2.1.1", ] [[package]] @@ -1201,7 +1210,7 @@ dependencies = [ "curl", "git2", "log", - "url 2.1.0", + "url 2.1.1", ] [[package]] @@ -1212,9 +1221,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454" +checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" dependencies = [ "aho-corasick", "bstr", @@ -1225,14 +1234,14 @@ dependencies = [ [[package]] name = "handlebars" -version = "3.0.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba758d094d31274eb49d15da6f326b96bf3185239a6359bf684f3d5321148900" +checksum = "5deefd4816fb852b1ff3cb48f6c41da67be2d0e1d20b26a7a3b076da11f064b1" dependencies = [ "log", "pest", "pest_derive", - "quick-error", + "quick-error 2.0.0", "serde", "serde_json", ] @@ -1251,9 +1260,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" dependencies = [ "unicode-segmentation", ] @@ -1277,18 +1286,17 @@ checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" [[package]] name = "hex" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" [[package]] name = "home" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3753954f7bd71f0e671afb8b5a992d1724cf43b7f95a563cd4a0bde94659ca8" +checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" dependencies = [ - "scopeguard", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1311,14 +1319,14 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ - "quick-error", + "quick-error 1.2.3", ] [[package]] name = "humantime" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b6c53306532d3c8e8087b44e6580e10db51a023cf9b433cea2ac38066b92da" +checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" [[package]] name = "idna" @@ -1350,11 +1358,11 @@ checksum = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d" [[package]] name = "ignore" -version = "0.4.11" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522daefc3b69036f80c7d2990b28ff9e0471c683bad05ca258e0a01dd22c5a1e" +checksum = "22dcbf2a4a289528dbef21686354904e1c694ac642610a9bff9e7df730d9ec72" dependencies = [ - "crossbeam-channel", + "crossbeam-utils 0.7.2", "globset", "lazy_static", "log", @@ -1373,7 +1381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f" dependencies = [ "bitmaps", - "rand_core 0.5.1", + "rand_core", "rand_xoshiro", "sized-chunks", "typenum", @@ -1403,10 +1411,16 @@ dependencies = [ "remove_dir_all", "tar", "walkdir", - "winapi 0.3.8", + "winapi 0.3.9", "xz2", ] +[[package]] +name = "instant" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485" + [[package]] name = "iovec" version = "0.1.4" @@ -1418,9 +1432,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" dependencies = [ "either", ] @@ -1436,15 +1450,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "jemalloc-sys" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bef0d4ce37578dfd80b466e3d8324bd9de788e249f1accebb0c472ea4b52bdc" +checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45" dependencies = [ "cc", "fs_extra", @@ -1462,15 +1476,15 @@ dependencies = [ [[package]] name = "json" -version = "0.11.13" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be" +checksum = "92c245af8786f6ac35f95ca14feca9119e71339aaab41e878e7cdd655c97e9e5" [[package]] name = "jsonrpc-client-transports" -version = "14.0.5" +version = "14.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9ae166c4d1f702d297cd76d4b55758ace80272ffc6dbb139fdc1bf810de40b" +checksum = "2773fa94a2a1fd51efb89a8f45b8861023dbb415d18d3c9235ae9388d780f9ec" dependencies = [ "failure", "futures", @@ -1487,9 +1501,9 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "14.0.5" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3b688648f1ef5d5072229e2d672ecb92cbff7d1c79bcf3fd5898f3f3df0970" +checksum = "a0747307121ffb9703afd93afbd0fb4f854c38fb873f2c8b90e0e902f27c7b62" dependencies = [ "futures", "log", @@ -1500,18 +1514,18 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "14.0.5" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080dc110be17701097df238fad3c816d4a478a1899dfbcf8ec8957dd40ec7304" +checksum = "34221123bc79b66279a3fde2d3363553835b43092d629b34f2e760c44dc94713" dependencies = [ "jsonrpc-client-transports", ] [[package]] name = "jsonrpc-derive" -version = "14.0.5" +version = "14.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" +checksum = "0fadf6945e227246825a583514534d864554e9f23d80b3c77d034b10983db5ef" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1535,21 +1549,22 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "14.0.6" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b31c9b90731276fdd24d896f31bb10aecf2e5151733364ae81123186643d939" +checksum = "2d44f5602a11d657946aac09357956d2841299ed422035edf140c552cb057986" dependencies = [ "jsonrpc-core", "log", "parking_lot 0.10.2", + "rand", "serde", ] [[package]] name = "jsonrpc-server-utils" -version = "14.0.5" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b7635e618a0edbbe0d2a2bbbc69874277c49383fcf6c3c0414491cfb517d22" +checksum = "56cbfb462e7f902e21121d9f0d1c2b77b2c5b642e1a4e8f4ebfa2e15b94402bb" dependencies = [ "bytes", "globset", @@ -1579,9 +1594,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" @@ -1594,9 +1609,9 @@ dependencies = [ [[package]] name = "libgit2-sys" -version = "0.12.7+1.0.0" +version = "0.12.9+1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd07968649bcb7b9351ecfde53ca4d27673cccfdf57c84255ec18710f3153e0" +checksum = "9b33bf3d9d4c45b48ae1ea7c334be69994624dc0a69f833d5d9f7605f24b552b" dependencies = [ "cc", "libc", @@ -1608,9 +1623,9 @@ dependencies = [ [[package]] name = "libnghttp2-sys" -version = "0.1.2" +version = "0.1.4+1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02254d44f4435dd79e695f2c2b83cd06a47919adea30216ceaf0c57ca0a72463" +checksum = "03624ec6df166e79e139a2310ca213283d6b3c30810c54844f307086d4488df1" dependencies = [ "cc", "libc", @@ -1618,9 +1633,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36aa6e813339d3a063292b77091dfbbb6152ff9006a459895fa5bebed7d34f10" +checksum = "eafa907407504b0e683786d4aba47acf250f114d37357d56608333fd167dd0fc" dependencies = [ "cc", "libc", @@ -1632,9 +1647,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" +checksum = "6ca8894883d250240341478bf987467332fbdd5da5c42426c69a8f93dbc302f2" dependencies = [ "cc", "libc", @@ -1648,9 +1663,9 @@ version = "0.1.0" [[package]] name = "linked-hash-map" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" [[package]] name = "lock_api" @@ -1661,11 +1676,20 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lock_api" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if", ] @@ -1700,14 +1724,14 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "url 2.1.0", + "url 2.1.1", ] [[package]] name = "lzma-sys" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b5c59c57cc4d39e7999f50431aa312ea78af7c93b23fbb0c3567bd672e7f35" +checksum = "f24f76ec44a8ac23a31915d6e326bca17ce88da03096f1ff194925dc714dac99" dependencies = [ "cc", "libc", @@ -1722,15 +1746,15 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "macro-utils" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c4deaccc2ead6a28c16c0ba82f07d52b6475397415ce40876e559b0b0ea510" +checksum = "0e72f7deb758fea9ea7d290aebfa788763d0bffae12caa6406a25baaf8fa68a8" [[package]] name = "maplit" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "markup5ever" @@ -1776,6 +1800,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "md-5" version = "0.8.0" @@ -1789,9 +1819,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2567ffadc0fd26fe15d6f6e0a80639f19f6a50082fdb460d0ae5d1f7298181be" +checksum = "b75e31ae4eaa0e45e17ee2b6b9e3ed969c3c6ff12bb4c2e352c42493f4ebb706" dependencies = [ "ammonia", "anyhow", @@ -1839,16 +1869,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "memoffset" -version = "0.5.1" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" +checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" dependencies = [ - "rustc_version", + "autocfg", ] [[package]] @@ -1874,15 +1904,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.16" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ + "cfg-if", "fuchsia-zircon", "fuchsia-zircon-sys", "iovec", "kernel32-sys", - "lazycell", "libc", "log", "miow 0.2.1", @@ -1893,21 +1923,21 @@ dependencies = [ [[package]] name = "mio-named-pipes" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", "mio", - "miow 0.3.3", - "winapi 0.3.8", + "miow 0.3.5", + "winapi 0.3.9", ] [[package]] name = "mio-uds" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", @@ -1928,12 +1958,12 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" dependencies = [ "socket2", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1945,7 +1975,7 @@ dependencies = [ "compiletest_rs", "env_logger 0.7.1", "getrandom", - "hex 0.4.0", + "hex 0.4.2", "libc", "log", "rand", @@ -1956,48 +1986,47 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "new_debug_unreachable" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30" - -[[package]] -name = "nodrop" -version = "0.1.12" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] name = "num-integer" -version = "0.1.39" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ + "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] [[package]] name = "num_cpus" -version = "1.10.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ + "hermit-abi", "libc", ] @@ -2014,11 +2043,11 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.1.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a04cb71e910d0034815600180f62a95bf6e67942d7ab52a166a68c7d7e9cd0" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" dependencies = [ - "parking_lot 0.9.0", + "parking_lot 0.11.0", ] [[package]] @@ -2029,24 +2058,27 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "open" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" +checksum = "7c283bf0114efea9e42f1a60edea9859e8c47528eae09d01df4b29c1e489cc48" +dependencies = [ + "winapi 0.3.9", +] [[package]] name = "opener" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448" +checksum = "13117407ca9d0caf3a0e74f97b490a7e64c0ae3aa90a8b7085544d0c37b6f3ae" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "openssl" -version = "0.10.25" +version = "0.10.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449" +checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" dependencies = [ "bitflags", "cfg-if", @@ -2064,18 +2096,18 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.9.0+1.1.1g" +version = "111.10.2+1.1.1g" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2dbe10ddd1eb335aba3780eb2eaa13e1b7b441d2562fd962398740927f39ec4" +checksum = "a287fdb22e32b5b60624d4a5a7a02dbe82777f730ec0dbc42a0554326fef5a70" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.54" +version = "0.9.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" +checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" dependencies = [ "autocfg", "cc", @@ -2097,14 +2129,14 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "packed_simd" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d36de864f7218ec5633572a800109bbe5a1cc8d9d95a967f3daf93ea7e6ddc" +checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" dependencies = [ "cfg-if", ] @@ -2141,12 +2173,12 @@ dependencies = [ "futures", "log", "mio-named-pipes", - "miow 0.3.3", + "miow 0.3.5", "rand", "tokio", "tokio-named-pipes", "tokio-uds", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2155,7 +2187,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" dependencies = [ - "lock_api", + "lock_api 0.3.4", "parking_lot_core 0.6.2", "rustc_version", ] @@ -2166,8 +2198,19 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ - "lock_api", - "parking_lot_core 0.7.1", + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +dependencies = [ + "instant", + "lock_api 0.4.1", + "parking_lot_core 0.8.0", ] [[package]] @@ -2177,26 +2220,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" dependencies = [ "cfg-if", - "cloudabi", + "cloudabi 0.0.3", "libc", "redox_syscall", "rustc_version", - "smallvec 0.6.10", - "winapi 0.3.8", + "smallvec 0.6.13", + "winapi 0.3.9", ] [[package]] name = "parking_lot_core" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e136c1904604defe99ce5fd71a28d473fa60a12255d511aa78a9ddf11237aeb" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ "cfg-if", - "cloudabi", + "cloudabi 0.0.3", "libc", "redox_syscall", - "smallvec 1.4.0", - "winapi 0.3.8", + "smallvec 1.4.2", + "winapi 0.3.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +dependencies = [ + "cfg-if", + "cloudabi 0.1.0", + "instant", + "libc", + "redox_syscall", + "smallvec 1.4.2", + "winapi 0.3.9", ] [[package]] @@ -2219,9 +2277,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pest" -version = "2.1.0" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" dependencies = [ "ucd-trie", ] @@ -2310,9 +2368,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" [[package]] name = "polonius-engine" @@ -2361,29 +2419,42 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ "toml", ] [[package]] name = "proc-macro-error" -version = "0.2.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ + "proc-macro-error-attr", "proc-macro2", "quote", "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.3" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" +checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" dependencies = [ "unicode-xid", ] @@ -2406,18 +2477,18 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092d385624a084892d07374caa7b0994956692cf40650419a1f1a787a8d229cf" +checksum = "96e0536f6528466dbbbbe6b986c34175a8d0ff25b794c4bacda22e068cd2f2c5" dependencies = [ "cc", ] [[package]] name = "pulldown-cmark" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e142c3b8f49d2200605ee6ba0b1d757310e9e7a72afe78c36ee2ef67300ee00" +checksum = "ca36dea94d187597e104a5c8e4b07576a8a45aa5db48a65e12940d3eb7461f55" dependencies = [ "bitflags", "getopts", @@ -2427,9 +2498,9 @@ dependencies = [ [[package]] name = "punycode" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ddd112cca70a4d30883b2d21568a1d376ff8be4758649f64f973c6845128ad3" +checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe" [[package]] name = "quick-error" @@ -2437,6 +2508,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-error" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda" + [[package]] name = "quine-mc_cluskey" version = "0.2.4" @@ -2445,9 +2522,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.2" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ "proc-macro2", ] @@ -2462,7 +2539,7 @@ dependencies = [ "clap", "derive_more", "env_logger 0.7.1", - "humantime 2.0.0", + "humantime 2.0.1", "lazy_static", "log", "rls-span", @@ -2484,7 +2561,7 @@ dependencies = [ "getrandom", "libc", "rand_chacha", - "rand_core 0.5.1", + "rand_core", "rand_hc", "rand_pcg", ] @@ -2496,21 +2573,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core 0.5.1", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" - -[[package]] -name = "rand_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" - [[package]] name = "rand_core" version = "0.5.1" @@ -2526,21 +2591,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.0", - "rdrand", - "winapi 0.3.8", + "rand_core", ] [[package]] @@ -2549,7 +2600,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.5.1", + "rand_core", ] [[package]] @@ -2558,7 +2609,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" dependencies = [ - "rand_core 0.5.1", + "rand_core", ] [[package]] @@ -2567,15 +2618,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004" dependencies = [ - "rand_core 0.5.1", + "rand_core", ] [[package]] name = "rayon" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" +checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" dependencies = [ + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -2583,49 +2635,39 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" +checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" dependencies = [ "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils 0.6.5", + "crossbeam-queue 0.2.3", + "crossbeam-utils 0.7.2", "lazy_static", "num_cpus", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.0", -] - [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_users" -version = "0.3.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" +checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" dependencies = [ - "argon2rs", - "failure", - "rand_os", + "getrandom", "redox_syscall", + "rust-argon2", ] [[package]] name = "regex" -version = "1.3.7" +version = "1.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" dependencies = [ "aho-corasick", "memchr", @@ -2645,9 +2687,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" [[package]] name = "remote-test-client" @@ -2659,11 +2701,11 @@ version = "0.1.0" [[package]] name = "remove_dir_all" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2672,7 +2714,7 @@ version = "1.41.0" dependencies = [ "anyhow", "cargo", - "cargo_metadata 0.8.0", + "cargo_metadata 0.8.2", "clippy_lints", "crossbeam-channel", "difference", @@ -2680,7 +2722,7 @@ dependencies = [ "futures", "heck", "home", - "itertools 0.8.0", + "itertools 0.8.2", "jsonrpc-core", "lazy_static", "log", @@ -2710,7 +2752,7 @@ dependencies = [ "tokio-process", "tokio-timer", "toml", - "url 2.1.0", + "url 2.1.1", "walkdir", ] @@ -2722,7 +2764,7 @@ checksum = "534032993e1b60e5db934eab2dde54da7afd1e46c3465fddb2b29eb47cb1ed3a" dependencies = [ "derive-new", "fst", - "itertools 0.8.0", + "itertools 0.8.2", "json", "log", "rls-data", @@ -2787,6 +2829,18 @@ dependencies = [ "rls-span", ] +[[package]] +name = "rust-argon2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils 0.7.2", +] + [[package]] name = "rust-demangler" version = "0.0.0" @@ -2809,7 +2863,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3941333c39ffa778611a34692244052fc9ba0f6b02dcf019c8d24925707dd6" dependencies = [ "rustc-ap-rustc_data_structures", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -2827,7 +2881,7 @@ dependencies = [ "rustc-ap-rustc_serialize", "rustc-ap-rustc_span", "scoped-tls", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -2836,7 +2890,7 @@ version = "671.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9914fadee461568d19ca2ebaec8699ff898f8ffec9928154659a57ee018e5fd" dependencies = [ - "itertools 0.8.0", + "itertools 0.8.2", "log", "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_pretty", @@ -2903,10 +2957,10 @@ dependencies = [ "rustc-hash", "rustc-rayon", "rustc-rayon-core", - "smallvec 1.4.0", + "smallvec 1.4.2", "stable_deref_trait", "stacker", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2924,7 +2978,7 @@ dependencies = [ "termcolor", "termize", "unicode-width", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2946,7 +3000,7 @@ dependencies = [ "rustc-ap-rustc_serialize", "rustc-ap-rustc_session", "rustc-ap-rustc_span", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -2978,7 +3032,7 @@ version = "671.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335bfb187a2489a59ee8c67fcf5d1760e9dcdbe0f02025c199a74caa05096b15" dependencies = [ - "arrayvec 0.5.1", + "arrayvec", "rustc-ap-rustc_serialize", ] @@ -3029,7 +3083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e8c0b704e3dedb97cbb1ac566bbc0ab397ec4a4743098326a8f2230463fd9f9" dependencies = [ "indexmap", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -3129,8 +3183,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2427831f0053ea3ea73559c8eabd893133a51b251d142bacee53c62a288cb3" dependencies = [ "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils 0.6.5", + "crossbeam-queue 0.1.2", + "crossbeam-utils 0.6.6", "lazy_static", "num_cpus", ] @@ -3165,11 +3219,11 @@ dependencies = [ "quote", "serde", "serde_json", - "smallvec 0.6.10", - "smallvec 1.4.0", + "smallvec 0.6.13", + "smallvec 1.4.2", "syn", - "url 2.1.0", - "winapi 0.3.8", + "url 2.1.1", + "winapi 0.3.9", ] [[package]] @@ -3177,7 +3231,7 @@ name = "rustc_apfloat" version = "0.0.0" dependencies = [ "bitflags", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -3185,7 +3239,7 @@ name = "rustc_arena" version = "0.0.0" dependencies = [ "rustc_data_structures", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -3199,7 +3253,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3217,7 +3271,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3225,7 +3279,7 @@ dependencies = [ name = "rustc_ast_passes" version = "0.0.0" dependencies = [ - "itertools 0.8.0", + "itertools 0.8.2", "rustc_ast", "rustc_ast_pretty", "rustc_attr", @@ -3281,7 +3335,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3310,7 +3364,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3367,12 +3421,12 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", - "smallvec 1.4.0", + "smallvec 1.4.2", "stable_deref_trait", "stacker", "tempfile", "tracing", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -3404,7 +3458,7 @@ dependencies = [ "rustc_target", "tracing", "tracing-subscriber", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -3425,7 +3479,7 @@ dependencies = [ "termize", "tracing", "unicode-width", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -3445,7 +3499,7 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3478,7 +3532,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3515,7 +3569,7 @@ dependencies = [ name = "rustc_index" version = "0.0.0" dependencies = [ - "arrayvec 0.5.1", + "arrayvec", "rustc_macros", "rustc_serialize", ] @@ -3536,7 +3590,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3578,10 +3632,10 @@ dependencies = [ "rustc_traits", "rustc_ty", "rustc_typeck", - "smallvec 1.4.0", + "smallvec 1.4.2", "tempfile", "tracing", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -3652,10 +3706,10 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "stable_deref_trait", "tracing", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -3683,7 +3737,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3692,7 +3746,7 @@ name = "rustc_mir" version = "0.0.0" dependencies = [ "either", - "itertools 0.8.0", + "itertools 0.8.2", "log_settings", "polonius-engine", "rustc_apfloat", @@ -3712,7 +3766,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3735,7 +3789,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3752,7 +3806,7 @@ dependencies = [ "rustc_lexer", "rustc_session", "rustc_span", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", "unicode-normalization", ] @@ -3825,7 +3879,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3849,7 +3903,7 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3878,7 +3932,7 @@ version = "0.0.0" dependencies = [ "indexmap", "rustc_macros", - "smallvec 1.4.0", + "smallvec 1.4.2", ] [[package]] @@ -3973,7 +4027,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -3991,7 +4045,7 @@ dependencies = [ "rustc_middle", "rustc_span", "rustc_trait_selection", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -4029,7 +4083,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec 1.4.0", + "smallvec 1.4.2", "tracing", ] @@ -4046,12 +4100,13 @@ dependencies = [ name = "rustdoc" version = "0.0.0" dependencies = [ - "itertools 0.8.0", + "itertools 0.8.2", "minifier", "pulldown-cmark", "rustc-rayon", "serde", "serde_json", + "smallvec 1.4.2", "tempfile", ] @@ -4068,9 +4123,9 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804b11883a5ce0ad0378fbf95a8dea59ee6b51c331a73b8f471b6bdaa3bd40c1" +checksum = "f2c50b74badcddeb8f7652fa8323ce440b95286f8e4b64ebfd871c609672704e" dependencies = [ "anyhow", "log", @@ -4095,14 +4150,14 @@ dependencies = [ "annotate-snippets 0.6.1", "anyhow", "bytecount", - "cargo_metadata 0.8.0", + "cargo_metadata 0.8.2", "derive-new", "diff", "dirs", "env_logger 0.6.2", "getopts", "ignore", - "itertools 0.8.0", + "itertools 0.8.2", "lazy_static", "log", "regex", @@ -4120,7 +4175,7 @@ dependencies = [ "serde", "serde_json", "structopt", - "term 0.6.0", + "term 0.6.1", "thiserror", "toml", "unicode-segmentation", @@ -4130,27 +4185,27 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.0" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "same-file" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "schannel" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -4159,17 +4214,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" -[[package]] -name = "scoped_threadpool" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" - [[package]] name = "scopeguard" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" @@ -4199,18 +4248,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.99" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f" +checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" dependencies = [ "proc-macro2", "quote", @@ -4219,18 +4268,18 @@ dependencies = [ [[package]] name = "serde_ignored" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c24bbb8f4b81834f618cd3e28698235c2fba06ddf7f4fbe30519dd081364e59" +checksum = "1c2c7d39d14f2f2ea82239de71594782f186fd03501ac81f0ce08e674819ff2f" dependencies = [ "serde", ] [[package]] name = "serde_json" -version = "1.0.40" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" dependencies = [ "itoa", "ryu", @@ -4239,9 +4288,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" +checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76" dependencies = [ "proc-macro2", "quote", @@ -4271,9 +4320,9 @@ dependencies = [ [[package]] name = "shell-escape" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" +checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] name = "shlex" @@ -4282,10 +4331,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] -name = "signal-hook" -version = "0.1.7" +name = "signal-hook-registry" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f272d1b7586bec132ed427f532dd418d8beca1ca7f2caf7df35569b1415a4b4" +checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" dependencies = [ "arc-swap", "libc", @@ -4315,15 +4364,18 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "0.6.10" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] [[package]] name = "smallvec" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" [[package]] name = "socket2" @@ -4334,14 +4386,14 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "stable_deref_trait" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stacker" @@ -4353,7 +4405,7 @@ dependencies = [ "cfg-if", "libc", "psm", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -4423,19 +4475,20 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.1" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac9d6e93dd792b217bf89cda5c14566e3043960c6f9da890c2ba5d09d07804c" +checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976" dependencies = [ "clap", + "lazy_static", "structopt-derive", ] [[package]] name = "structopt-derive" -version = "0.3.1" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37" +checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99" dependencies = [ "heck", "proc-macro-error", @@ -4464,9 +4517,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.11" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" +checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" dependencies = [ "proc-macro2", "quote", @@ -4475,9 +4528,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.1" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ "proc-macro2", "quote", @@ -4487,9 +4540,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.26" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" +checksum = "c8a4c1d0bee3230179544336c15eefb563cf0302955d962e456542323e8c2e8a" dependencies = [ "filetime", "libc", @@ -4508,14 +4561,14 @@ dependencies = [ "rand", "redox_syscall", "remove_dir_all", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "tendril" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" +checksum = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b" dependencies = [ "futf", "mac", @@ -4532,13 +4585,12 @@ dependencies = [ [[package]] name = "term" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd90505d5006a4422d3520b30c781d480b3f36768c2fa2187c3e950bc110464" +checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" dependencies = [ - "byteorder", "dirs", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -4557,7 +4609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1706be6b564323ce7092f5f7e6b118a14c8ef7ed0e69c8c5329c914a9f101295" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -4583,7 +4635,7 @@ checksum = "ee72ec31009a42b53de9a6b7d8f462b493ab3b1e4767bda1fcdbb52127f13b6c" dependencies = [ "getopts", "libc", - "term 0.6.0", + "term 0.6.1", ] [[package]] @@ -4597,18 +4649,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.5" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fb62ff737e573b1e677459bea6fd023cd5d6e868c3242d3cdf3ef2f0554824" +checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.5" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24069c0ba08aab54289d6a25f5036d94afc61e1538bbc42ae5501df141c9027d" +checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ "proc-macro2", "quote", @@ -4640,15 +4692,20 @@ version = "0.1.0" [[package]] name = "time" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] +[[package]] +name = "tinyvec" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" + [[package]] name = "tokio" version = "0.1.22" @@ -4675,9 +4732,9 @@ dependencies = [ [[package]] name = "tokio-codec" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" dependencies = [ "bytes", "futures", @@ -4686,9 +4743,9 @@ dependencies = [ [[package]] name = "tokio-current-thread" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" +checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ "futures", "tokio-executor", @@ -4696,19 +4753,19 @@ dependencies = [ [[package]] name = "tokio-executor" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" +checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.7.2", "futures", ] [[package]] name = "tokio-fs" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" +checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" dependencies = [ "futures", "tokio-io", @@ -4717,9 +4774,9 @@ dependencies = [ [[package]] name = "tokio-io" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" +checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes", "futures", @@ -4741,11 +4798,11 @@ dependencies = [ [[package]] name = "tokio-process" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afbd6ef1b8cc2bd2c2b580d882774d443ebb1c6ceefe35ba9ea4ab586c89dbe8" +checksum = "382d90f43fa31caebe5d3bc6cfd854963394fff3b8cb59d5146607aaae7e7e43" dependencies = [ - "crossbeam-queue", + "crossbeam-queue 0.1.2", "futures", "lazy_static", "libc", @@ -4755,16 +4812,16 @@ dependencies = [ "tokio-io", "tokio-reactor", "tokio-signal", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "tokio-reactor" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" +checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.7.2", "futures", "lazy_static", "log", @@ -4788,26 +4845,26 @@ dependencies = [ [[package]] name = "tokio-signal" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" +checksum = "d0c34c6e548f101053321cba3da7cbb87a610b85555884c41b07da2eb91aff12" dependencies = [ "futures", "libc", "mio", "mio-uds", - "signal-hook", + "signal-hook-registry", "tokio-executor", "tokio-io", "tokio-reactor", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "tokio-sync" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" +checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" dependencies = [ "fnv", "futures", @@ -4815,9 +4872,9 @@ dependencies = [ [[package]] name = "tokio-tcp" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" +checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ "bytes", "futures", @@ -4829,13 +4886,13 @@ dependencies = [ [[package]] name = "tokio-threadpool" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" +checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" dependencies = [ "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils 0.6.5", + "crossbeam-queue 0.2.3", + "crossbeam-utils 0.7.2", "futures", "lazy_static", "log", @@ -4846,11 +4903,11 @@ dependencies = [ [[package]] name = "tokio-timer" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" +checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.7.2", "futures", "slab", "tokio-executor", @@ -4858,9 +4915,9 @@ dependencies = [ [[package]] name = "tokio-udp" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" +checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" dependencies = [ "bytes", "futures", @@ -4873,9 +4930,9 @@ dependencies = [ [[package]] name = "tokio-uds" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" +checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" dependencies = [ "bytes", "futures", @@ -4891,18 +4948,18 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.3" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" dependencies = [ "serde", ] [[package]] name = "tracing" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178" +checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c" dependencies = [ "cfg-if", "tracing-attributes", @@ -4911,9 +4968,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b" +checksum = "1fe233f4227389ab7df5b32649239da7ebe0b281824b4e84b342d04d3fd8c25e" dependencies = [ "proc-macro2", "quote", @@ -4922,26 +4979,27 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2734b5a028fa697686f16c6d18c2c6a3c7e41513f9a213abb6754c4acb3c8d7" +checksum = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545" dependencies = [ "lazy_static", ] [[package]] name = "tracing-subscriber" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b33f8b2ef2ab0c3778c12646d9c42a24f7772bee4cdafc72199644a9f58fdc" +checksum = "abd165311cc4d7a555ad11cc77a37756df836182db0d81aac908c8184c584f40" dependencies = [ "ansi_term 0.12.1", "lazy_static", "matchers", - "parking_lot 0.10.2", + "parking_lot 0.11.0", "regex", "sharded-slab", - "smallvec 1.4.0", + "smallvec 1.4.2", + "thread_local", "tracing-core", ] @@ -4953,9 +5011,9 @@ checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" [[package]] name = "ucd-parse" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6b52bf4da6512f0f07785a04769222e50d29639e7ecd016b7806fd2de306b4" +checksum = "5269f8d35df6b8b60758343a6d742ecf09e4bca13faee32af5503aebd1e11b7c" dependencies = [ "lazy_static", "regex", @@ -4963,9 +5021,9 @@ dependencies = [ [[package]] name = "ucd-trie" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "unicase" @@ -4994,18 +5052,18 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "smallvec 1.4.0", + "tinyvec", ] [[package]] name = "unicode-script" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58b33414ea8db4b7ea0343548dbdc31d27aef06beacf7044a87e564d9b0feb7d" +checksum = "79bf4d5fc96546fdb73f9827097810bbda93b11a6770ff3a54e1f445d4135787" [[package]] name = "unicode-security" @@ -5025,9 +5083,9 @@ checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" [[package]] name = "unicode-width" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -5036,9 +5094,9 @@ dependencies = [ [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "unicode_categories" @@ -5078,9 +5136,9 @@ dependencies = [ [[package]] name = "url" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ "idna 0.2.0", "matches", @@ -5090,9 +5148,9 @@ dependencies = [ [[package]] name = "utf-8" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" +checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" [[package]] name = "utf8parse" @@ -5102,15 +5160,15 @@ checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" [[package]] name = "vcpkg" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" [[package]] name = "vec_map" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "vergen" @@ -5139,12 +5197,12 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.2.7" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" dependencies = [ "same-file", - "winapi 0.3.8", + "winapi 0.3.9", "winapi-util", ] @@ -5167,9 +5225,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -5193,7 +5251,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5235,22 +5293,22 @@ dependencies = [ [[package]] name = "xz2" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8bf41d3030c3577c9458fd6640a05afbf43b150d0b531b16bd77d3f794f27a" +checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" dependencies = [ "lzma-sys", ] [[package]] name = "yaml-merge-keys" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59893318ba3ad2b704498c7761214a10eaf42c5f838bce9fc0145bf2ba658cfa" +checksum = "fd236a7dc9bb598f349fe4a8754f49181fee50284daa15cd1ba652d722280004" dependencies = [ "lazy_static", "thiserror", - "yaml-rust 0.4.3", + "yaml-rust 0.4.4", ] [[package]] @@ -5261,9 +5319,9 @@ checksum = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" [[package]] name = "yaml-rust" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" +checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" dependencies = [ "linked-hash-map", ] diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index c6b55840db993..f8729c33c6713 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1236,10 +1236,10 @@ impl BTreeMap { right_root.fix_left_border(); if left_root.height() < right_root.height() { - self.recalc_length(); + self.length = left_root.node_as_ref().calc_length(); right.length = total_num - self.len(); } else { - right.recalc_length(); + right.length = right_root.node_as_ref().calc_length(); self.length = total_num - right.len(); } @@ -1283,42 +1283,13 @@ impl BTreeMap { { DrainFilter { pred, inner: self.drain_filter_inner() } } + pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> { let root_node = self.root.as_mut().map(|r| r.node_as_mut()); let front = root_node.map(|rn| rn.first_leaf_edge()); DrainFilterInner { length: &mut self.length, cur_leaf_edge: front } } - /// Calculates the number of elements if it is incorrect. - fn recalc_length(&mut self) { - fn dfs<'a, K, V>(node: NodeRef, K, V, marker::LeafOrInternal>) -> usize - where - K: 'a, - V: 'a, - { - let mut res = node.len(); - - if let Internal(node) = node.force() { - let mut edge = node.first_edge(); - loop { - res += dfs(edge.reborrow().descend()); - match edge.right_kv() { - Ok(right_kv) => { - edge = right_kv.right_edge(); - } - Err(_) => { - break; - } - } - } - } - - res - } - - self.length = dfs(self.root.as_ref().unwrap().node_as_ref()); - } - /// Creates a consuming iterator visiting all the keys, in sorted order. /// The map cannot be used after calling this. /// The iterator element type is `K`. diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 910e7043092a5..eb8d86b9693fd 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -1,4 +1,6 @@ use crate::boxed::Box; +use crate::collections::btree::navigate::Position; +use crate::collections::btree::node; use crate::collections::btree_map::Entry::{Occupied, Vacant}; use crate::collections::BTreeMap; use crate::fmt::Debug; @@ -16,19 +18,19 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use super::super::DeterministicRng; -// Value of node::CAPACITY, thus capacity of a tree with a single level, +// Capacity of a tree with a single level, // i.e. a tree who's root is a leaf node at height 0. -const NODE_CAPACITY: usize = 11; +const NODE_CAPACITY: usize = node::CAPACITY; -// Minimum number of elements to insert in order to guarantee a tree with 2 levels, +// Minimum number of elements to insert, to guarantee a tree with 2 levels, // i.e. a tree who's root is an internal node at height 1, with edges to leaf nodes. // It's not the minimum size: removing an element from such a tree does not always reduce height. const MIN_INSERTS_HEIGHT_1: usize = NODE_CAPACITY + 1; -// Minimum number of elements to insert in order to guarantee a tree with 3 levels, +// Minimum number of elements to insert in ascending order, to guarantee a tree with 3 levels, // i.e. a tree who's root is an internal node at height 2, with edges to more internal nodes. // It's not the minimum size: removing an element from such a tree does not always reduce height. -const MIN_INSERTS_HEIGHT_2: usize = NODE_CAPACITY + (NODE_CAPACITY + 1) * NODE_CAPACITY + 1; +const MIN_INSERTS_HEIGHT_2: usize = 89; // Gather all references from a mutable iterator and make sure Miri notices if // using them is dangerous. @@ -44,11 +46,141 @@ fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator } } +struct SeriesChecker { + previous: Option, +} + +impl SeriesChecker { + fn is_ascending(&mut self, next: T) { + if let Some(previous) = self.previous { + assert!(previous < next, "{:?} >= {:?}", previous, next); + } + self.previous = Some(next); + } +} + +impl<'a, K: 'a, V: 'a> BTreeMap { + /// Panics if the map (or the code navigating it) is corrupted. + fn check(&self) + where + K: Copy + Debug + Ord, + { + if let Some(root) = &self.root { + let root_node = root.node_as_ref(); + let mut checker = SeriesChecker { previous: None }; + let mut internal_length = 0; + let mut internal_kv_count = 0; + let mut leaf_length = 0; + root_node.visit_nodes_in_order(|pos| match pos { + Position::Leaf(node) => { + let is_root = root_node.height() == 0; + let min_len = if is_root { 0 } else { node::MIN_LEN }; + assert!(node.len() >= min_len, "{} < {}", node.len(), min_len); + + for &key in node.keys() { + checker.is_ascending(key); + } + leaf_length += node.len(); + } + Position::Internal(node) => { + let is_root = root_node.height() == node.height(); + let min_len = if is_root { 1 } else { node::MIN_LEN }; + assert!(node.len() >= min_len, "{} < {}", node.len(), min_len); + + internal_length += node.len(); + } + Position::InternalKV(kv) => { + let key = *kv.into_kv().0; + checker.is_ascending(key); + + internal_kv_count += 1; + } + }); + assert_eq!(internal_length, internal_kv_count); + assert_eq!(root_node.calc_length(), internal_length + leaf_length); + assert_eq!(self.length, internal_length + leaf_length); + } else { + assert_eq!(self.length, 0); + } + } + + /// Returns the height of the root, if any. + fn height(&self) -> Option { + self.root.as_ref().map(node::Root::height) + } + + fn dump_keys(&self) -> String + where + K: Debug, + { + if let Some(root) = self.root.as_ref() { + let mut result = String::new(); + let root_node = root.node_as_ref(); + root_node.visit_nodes_in_order(|pos| match pos { + Position::Leaf(leaf) => { + let depth = root_node.height(); + let indent = " ".repeat(depth); + result += &format!("\n{}{:?}", indent, leaf.keys()) + } + Position::Internal(_) => {} + Position::InternalKV(kv) => { + let depth = root_node.height() - kv.into_node().height(); + let indent = " ".repeat(depth); + result += &format!("\n{}{:?}", indent, kv.into_kv().0); + } + }); + result + } else { + String::from("not yet allocated") + } + } +} + +// Test our value of MIN_INSERTS_HEIGHT_2. It may change according to the +// implementation of insertion, but it's best to be aware of when it does. +#[test] +fn test_levels() { + let mut map = BTreeMap::new(); + map.check(); + assert_eq!(map.height(), None); + assert_eq!(map.len(), 0); + + map.insert(0, ()); + while map.height() == Some(0) { + let last_key = *map.last_key_value().unwrap().0; + map.insert(last_key + 1, ()); + } + map.check(); + // Structure: + // - 1 element in internal root node with 2 children + // - 6 elements in left leaf child + // - 5 elements in right leaf child + assert_eq!(map.height(), Some(1)); + assert_eq!(map.len(), MIN_INSERTS_HEIGHT_1, "{}", map.dump_keys()); + + while map.height() == Some(1) { + let last_key = *map.last_key_value().unwrap().0; + map.insert(last_key + 1, ()); + } + println!("{}", map.dump_keys()); + map.check(); + // Structure: + // - 1 element in internal root node with 2 children + // - 6 elements in left internal child with 7 grandchildren + // - 42 elements in left child's 7 grandchildren with 6 elements each + // - 5 elements in right internal child with 6 grandchildren + // - 30 elements in right child's 5 first grandchildren with 6 elements each + // - 5 elements in right child's last grandchild + assert_eq!(map.height(), Some(2)); + assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2, "{}", map.dump_keys()); +} + #[test] fn test_basic_large() { let mut map = BTreeMap::new(); // Miri is too slow let size = if cfg!(miri) { MIN_INSERTS_HEIGHT_2 } else { 10000 }; + let size = size + (size % 2); // round up to even number assert_eq!(map.len(), 0); for i in 0..size { @@ -93,6 +225,7 @@ fn test_basic_large() { assert_eq!(map.remove(&(2 * i + 1)), Some(i * 200 + 100)); assert_eq!(map.len(), size / 2 - i - 1); } + map.check(); } #[test] @@ -112,7 +245,10 @@ fn test_basic_small() { assert_eq!(map.range(1..).next(), None); assert_eq!(map.range(1..=1).next(), None); assert_eq!(map.range(1..2).next(), None); + assert_eq!(map.height(), None); assert_eq!(map.insert(1, 1), None); + assert_eq!(map.height(), Some(0)); + map.check(); // 1 key-value pair: assert_eq!(map.len(), 1); @@ -131,6 +267,8 @@ fn test_basic_small() { assert_eq!(map.keys().collect::>(), vec![&1]); assert_eq!(map.values().collect::>(), vec![&2]); assert_eq!(map.insert(2, 4), None); + assert_eq!(map.height(), Some(0)); + map.check(); // 2 key-value pairs: assert_eq!(map.len(), 2); @@ -141,6 +279,8 @@ fn test_basic_small() { assert_eq!(map.keys().collect::>(), vec![&1, &2]); assert_eq!(map.values().collect::>(), vec![&2, &4]); assert_eq!(map.remove(&1), Some(2)); + assert_eq!(map.height(), Some(0)); + map.check(); // 1 key-value pair: assert_eq!(map.len(), 1); @@ -153,6 +293,8 @@ fn test_basic_small() { assert_eq!(map.keys().collect::>(), vec![&2]); assert_eq!(map.values().collect::>(), vec![&4]); assert_eq!(map.remove(&2), Some(4)); + assert_eq!(map.height(), Some(0)); + map.check(); // Empty but root is owned (Some(...)): assert_eq!(map.len(), 0); @@ -168,6 +310,8 @@ fn test_basic_small() { assert_eq!(map.range(1..=1).next(), None); assert_eq!(map.range(1..2).next(), None); assert_eq!(map.remove(&1), None); + assert_eq!(map.height(), Some(0)); + map.check(); } #[test] @@ -248,6 +392,7 @@ where assert_eq!(*k, T::try_from(i).unwrap()); assert_eq!(*v, T::try_from(size + i + 1).unwrap()); } + map.check(); } #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] @@ -268,7 +413,7 @@ fn test_iter_mut_mutation() { do_test_iter_mut_mutation::(0); do_test_iter_mut_mutation::(1); do_test_iter_mut_mutation::(MIN_INSERTS_HEIGHT_1); - do_test_iter_mut_mutation::(127); // not enough unique values to test MIN_INSERTS_HEIGHT_2 + do_test_iter_mut_mutation::(MIN_INSERTS_HEIGHT_2); do_test_iter_mut_mutation::(1); do_test_iter_mut_mutation::(MIN_INSERTS_HEIGHT_1); do_test_iter_mut_mutation::(MIN_INSERTS_HEIGHT_2); @@ -291,6 +436,7 @@ fn test_iter_mut_mutation() { fn test_values_mut() { let mut a: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)).collect(); test_all_refs(&mut 13, a.values_mut()); + a.check(); } #[test] @@ -305,6 +451,7 @@ fn test_values_mut_mutation() { let values: Vec = a.values().cloned().collect(); assert_eq!(values, [String::from("hello!"), String::from("goodbye!")]); + a.check(); } #[test] @@ -320,6 +467,7 @@ fn test_iter_entering_root_twice() { *back.1 = 42; assert_eq!(front, (&0, &mut 24)); assert_eq!(back, (&1, &mut 42)); + map.check(); } #[test] @@ -335,6 +483,7 @@ fn test_iter_descending_to_same_node_twice() { assert_eq!(front, (&0, &mut 0)); // Perform mutable access. *front.1 = 42; + map.check(); } #[test] @@ -399,6 +548,7 @@ fn test_iter_min_max() { assert_eq!(a.values().max(), Some(&42)); assert_eq!(a.values_mut().min(), Some(&mut 24)); assert_eq!(a.values_mut().max(), Some(&mut 42)); + a.check(); } fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { @@ -685,6 +835,7 @@ fn test_range_mut() { assert_eq!(pairs.next(), None); } } + map.check(); } mod test_drain_filter { @@ -695,6 +846,7 @@ mod test_drain_filter { let mut map: BTreeMap = BTreeMap::new(); map.drain_filter(|_, _| unreachable!("there's nothing to decide on")); assert!(map.is_empty()); + map.check(); } #[test] @@ -702,6 +854,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); let mut map: BTreeMap<_, _> = pairs.collect(); assert!(map.drain_filter(|_, _| false).eq(std::iter::empty())); + map.check(); } #[test] @@ -709,6 +862,7 @@ mod test_drain_filter { let pairs = (0..3).map(|i| (i, i)); let mut map: BTreeMap<_, _> = pairs.clone().collect(); assert!(map.drain_filter(|_, _| true).eq(pairs)); + map.check(); } #[test] @@ -724,6 +878,7 @@ mod test_drain_filter { ); assert!(map.keys().copied().eq(0..3)); assert!(map.values().copied().eq(6..9)); + map.check(); } #[test] @@ -738,6 +893,7 @@ mod test_drain_filter { .eq((0..3).map(|i| (i, i + 6))) ); assert!(map.is_empty()); + map.check(); } #[test] @@ -746,6 +902,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.collect(); map.drain_filter(|_, _| false); assert!(map.keys().copied().eq(0..3)); + map.check(); } #[test] @@ -755,6 +912,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i == doomed); assert_eq!(map.len(), 2); + map.check(); } } @@ -765,6 +923,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i != sacred); assert!(map.keys().copied().eq(sacred..=sacred)); + map.check(); } } @@ -774,6 +933,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.collect(); map.drain_filter(|_, _| true); assert!(map.is_empty()); + map.check(); } #[test] @@ -782,6 +942,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.collect(); map.drain_filter(|_, _| false); assert!(map.keys().copied().eq(0..NODE_CAPACITY)); + map.check(); } #[test] @@ -791,6 +952,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i == doomed); assert_eq!(map.len(), NODE_CAPACITY - 1); + map.check(); } } @@ -801,6 +963,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i != sacred); assert!(map.keys().copied().eq(sacred..=sacred)); + map.check(); } } @@ -810,6 +973,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.collect(); map.drain_filter(|_, _| true); assert!(map.is_empty()); + map.check(); } #[test] @@ -817,6 +981,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = (0..16).map(|i| (i, i)).collect(); assert_eq!(map.drain_filter(|i, _| *i % 2 == 0).count(), 8); assert_eq!(map.len(), 8); + map.check(); } #[test] @@ -825,6 +990,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.collect(); map.drain_filter(|_, _| true); assert!(map.is_empty()); + map.check(); } #[test] @@ -834,6 +1000,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i == doomed); assert_eq!(map.len(), MIN_INSERTS_HEIGHT_1 - 1); + map.check(); } } @@ -844,10 +1011,10 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i != sacred); assert!(map.keys().copied().eq(sacred..=sacred)); + map.check(); } } - #[cfg(not(miri))] // Miri is too slow #[test] fn height_2_removing_one() { let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)); @@ -855,10 +1022,10 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i == doomed); assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1); + map.check(); } } - #[cfg(not(miri))] // Miri is too slow #[test] fn height_2_keeping_one() { let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)); @@ -866,6 +1033,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.clone().collect(); map.drain_filter(|i, _| *i != sacred); assert!(map.keys().copied().eq(sacred..=sacred)); + map.check(); } } @@ -875,6 +1043,7 @@ mod test_drain_filter { let mut map: BTreeMap<_, _> = pairs.collect(); map.drain_filter(|_, _| true); assert!(map.is_empty()); + map.check(); } #[test] @@ -937,6 +1106,7 @@ mod test_drain_filter { assert_eq!(map.len(), 2); assert_eq!(map.first_entry().unwrap().key(), &4); assert_eq!(map.last_entry().unwrap().key(), &8); + map.check(); } // Same as above, but attempt to use the iterator again after the panic in the predicate @@ -975,6 +1145,7 @@ mod test_drain_filter { assert_eq!(map.len(), 2); assert_eq!(map.first_entry().unwrap().key(), &4); assert_eq!(map.last_entry().unwrap().key(), &8); + map.check(); } } @@ -1033,6 +1204,7 @@ fn test_entry() { } assert_eq!(map.get(&2).unwrap(), &200); assert_eq!(map.len(), 6); + map.check(); // Existing key (take) match map.entry(3) { @@ -1043,6 +1215,7 @@ fn test_entry() { } assert_eq!(map.get(&3), None); assert_eq!(map.len(), 5); + map.check(); // Inexistent key (insert) match map.entry(10) { @@ -1053,6 +1226,7 @@ fn test_entry() { } assert_eq!(map.get(&10).unwrap(), &1000); assert_eq!(map.len(), 6); + map.check(); } #[test] @@ -1069,6 +1243,7 @@ fn test_extend_ref() { assert_eq!(a[&1], "one"); assert_eq!(a[&2], "two"); assert_eq!(a[&3], "three"); + a.check(); } #[test] @@ -1092,6 +1267,7 @@ fn test_zst() { assert_eq!(m.len(), 1); assert_eq!(m.iter().count(), 1); + m.check(); } // This test's only purpose is to ensure that zero-sized keys with nonsensical orderings @@ -1101,6 +1277,7 @@ fn test_zst() { fn test_bad_zst() { use std::cmp::Ordering; + #[derive(Clone, Copy, Debug)] struct Bad; impl PartialEq for Bad { @@ -1128,6 +1305,7 @@ fn test_bad_zst() { for _ in 0..100 { m.insert(Bad, Bad); } + m.check(); } #[test] @@ -1139,18 +1317,21 @@ fn test_clone() { for i in 0..size { assert_eq!(map.insert(i, 10 * i), None); assert_eq!(map.len(), i + 1); + map.check(); assert_eq!(map, map.clone()); } for i in 0..size { assert_eq!(map.insert(i, 100 * i), Some(10 * i)); assert_eq!(map.len(), size); + map.check(); assert_eq!(map, map.clone()); } for i in 0..size / 2 { assert_eq!(map.remove(&(i * 2)), Some(i * 200)); assert_eq!(map.len(), size - i - 1); + map.check(); assert_eq!(map, map.clone()); } @@ -1158,16 +1339,18 @@ fn test_clone() { assert_eq!(map.remove(&(2 * i)), None); assert_eq!(map.remove(&(2 * i + 1)), Some(i * 200 + 100)); assert_eq!(map.len(), size / 2 - i - 1); + map.check(); assert_eq!(map, map.clone()); } - // Test a tree with 2 chock-full levels and a tree with 3 levels. + // Test a tree with 2 semi-full levels and a tree with 3 levels. map = (1..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)).collect(); assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1); assert_eq!(map, map.clone()); map.insert(0, 0); assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2); assert_eq!(map, map.clone()); + map.check(); } #[test] @@ -1188,8 +1371,10 @@ fn test_clone_from() { map2.insert(100 * j + 1, 2 * j + 1); } map2.clone_from(&map1); // same length + map2.check(); assert_eq!(map2, map1); map1.insert(i, 10 * i); + map1.check(); } } @@ -1246,6 +1431,7 @@ fn test_occupied_entry_key() { } assert_eq!(a.len(), 1); assert_eq!(a[key], value); + a.check(); } #[test] @@ -1264,6 +1450,7 @@ fn test_vacant_entry_key() { } assert_eq!(a.len(), 1); assert_eq!(a[key], value); + a.check(); } #[test] @@ -1288,6 +1475,21 @@ fn test_first_last_entry() { assert_eq!(v2, 24); assert_eq!(a.first_entry().unwrap().key(), &1); assert_eq!(a.last_entry().unwrap().key(), &1); + a.check(); +} + +#[test] +fn test_insert_into_full_left() { + let mut map: BTreeMap<_, _> = (0..NODE_CAPACITY).map(|i| (i * 2, ())).collect(); + assert!(map.insert(NODE_CAPACITY, ()).is_none()); + map.check(); +} + +#[test] +fn test_insert_into_full_right() { + let mut map: BTreeMap<_, _> = (0..NODE_CAPACITY).map(|i| (i * 2, ())).collect(); + assert!(map.insert(NODE_CAPACITY + 2, ()).is_none()); + map.check(); } macro_rules! create_append_test { @@ -1317,8 +1519,10 @@ macro_rules! create_append_test { } } + a.check(); assert_eq!(a.remove(&($len - 1)), Some(2 * ($len - 1))); assert_eq!(a.insert($len - 1, 20), None); + a.check(); } }; } @@ -1355,6 +1559,8 @@ fn test_split_off_empty_right() { let mut map = BTreeMap::from_iter(data.clone()); let right = map.split_off(&(data.iter().max().unwrap().0 + 1)); + map.check(); + right.check(); data.sort(); assert!(map.into_iter().eq(data)); @@ -1367,6 +1573,8 @@ fn test_split_off_empty_left() { let mut map = BTreeMap::from_iter(data.clone()); let right = map.split_off(&data.iter().min().unwrap().0); + map.check(); + right.check(); data.sort(); assert!(map.into_iter().eq(None)); @@ -1380,6 +1588,8 @@ fn test_split_off_tiny_left_height_2() { let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)); let mut left: BTreeMap<_, _> = pairs.clone().collect(); let right = left.split_off(&1); + left.check(); + right.check(); assert_eq!(left.len(), 1); assert_eq!(right.len(), MIN_INSERTS_HEIGHT_2 - 1); assert_eq!(*left.first_key_value().unwrap().0, 0); @@ -1395,6 +1605,8 @@ fn test_split_off_tiny_right_height_2() { let mut left: BTreeMap<_, _> = pairs.clone().collect(); assert_eq!(*left.last_key_value().unwrap().0, last); let right = left.split_off(&last); + left.check(); + right.check(); assert_eq!(left.len(), MIN_INSERTS_HEIGHT_2 - 1); assert_eq!(right.len(), 1); assert_eq!(*left.last_key_value().unwrap().0, last - 1); @@ -1411,6 +1623,8 @@ fn test_split_off_large_random_sorted() { let mut map = BTreeMap::from_iter(data.clone()); let key = data[data.len() / 2].0; let right = map.split_off(&key); + map.check(); + right.check(); assert!(map.into_iter().eq(data.clone().into_iter().filter(|x| x.0 < key))); assert!(right.into_iter().eq(data.into_iter().filter(|x| x.0 >= key))); diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index 33b1ee003ed3a..b7b66ac7ceccd 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -49,6 +49,29 @@ impl Handle, marker::E } } +impl Handle, marker::Edge> { + /// Given an internal edge handle, returns [`Result::Ok`] with a handle to the neighboring KV + /// on the right side, which is either in the same internal node or in an ancestor node. + /// If the internal edge is the last one in the tree, returns [`Result::Err`] with the root node. + pub fn next_kv( + self, + ) -> Result< + Handle, marker::KV>, + NodeRef, + > { + let mut edge = self; + loop { + edge = match edge.right_kv() { + Ok(internal_kv) => return Ok(internal_kv), + Err(last_edge) => match last_edge.into_node().ascend() { + Ok(parent_edge) => parent_edge, + Err(root) => return Err(root), + }, + } + } + } +} + macro_rules! def_next_kv_uncheched_dealloc { { unsafe fn $name:ident : $adjacent_kv:ident } => { /// Given a leaf edge handle into an owned tree, returns a handle to the next KV, @@ -232,6 +255,59 @@ impl NodeRef { } } +pub enum Position { + Leaf(NodeRef), + Internal(NodeRef), + InternalKV(Handle, marker::KV>), +} + +impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { + /// Visits leaf nodes and internal KVs in order of ascending keys, and also + /// visits internal nodes as a whole in a depth first order, meaning that + /// internal nodes precede their individual KVs and their child nodes. + pub fn visit_nodes_in_order(self, mut visit: F) + where + F: FnMut(Position, K, V>), + { + match self.force() { + Leaf(leaf) => visit(Position::Leaf(leaf)), + Internal(internal) => { + visit(Position::Internal(internal)); + let mut edge = internal.first_edge(); + loop { + edge = match edge.descend().force() { + Leaf(leaf) => { + visit(Position::Leaf(leaf)); + match edge.next_kv() { + Ok(kv) => { + visit(Position::InternalKV(kv)); + kv.right_edge() + } + Err(_) => return, + } + } + Internal(internal) => { + visit(Position::Internal(internal)); + internal.first_edge() + } + } + } + } + } + } + + /// Calculates the number of elements in a (sub)tree. + pub fn calc_length(self) -> usize { + let mut result = 0; + self.visit_nodes_in_order(|pos| match pos { + Position::Leaf(node) => result += node.len(), + Position::Internal(node) => result += node.len(), + Position::InternalKV(_) => (), + }); + result + } +} + impl Handle, marker::KV> { /// Returns the leaf edge closest to a KV for forward navigation. pub fn next_leaf_edge(self) -> Handle, marker::Edge> { diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 8ca0a0883cb16..80f7ff4893e21 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -622,7 +622,10 @@ impl Vec { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn shrink_to_fit(&mut self) { - if self.capacity() != self.len { + // The capacity is never less than the length, and there's nothing to do when + // they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit` + // by only calling it with a greater capacity. + if self.capacity() > self.len { self.buf.shrink_to_fit(self.len); } } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 56dddee7b7799..9326aaf56847c 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -291,6 +291,7 @@ pub trait StructuralEq { /// /// ``` /// # #[allow(dead_code)] +/// #[derive(Copy, Clone)] /// struct Point { /// x: i32, /// y: i32, @@ -315,6 +316,20 @@ pub trait StructuralEq { /// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy` /// ``` /// +/// Shared references (`&T`) are also `Copy`, so a type can be `Copy`, even when it holds +/// shared references of types `T` that are *not* `Copy`. Consider the following struct, +/// which can implement `Copy`, because it only holds a *shared reference* to our non-`Copy` +/// type `PointList` from above: +/// +/// ``` +/// # #![allow(dead_code)] +/// # struct PointList; +/// #[derive(Copy, Clone)] +/// struct PointListWrapper<'a> { +/// point_list_ref: &'a PointList, +/// } +/// ``` +/// /// ## When *can't* my type be `Copy`? /// /// Some types can't be copied safely. For example, copying `&mut T` would create an aliased diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4e58e118562ef..9107c570a8970 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -670,6 +670,9 @@ pub unsafe fn uninitialized() -> T { /// Swaps the values at two mutable locations, without deinitializing either one. /// +/// * If you want to swap with a default or dummy value, see [`take`]. +/// * If you want to swap with a passed value, returning the old value, see [`replace`]. +/// /// # Examples /// /// ``` @@ -683,6 +686,9 @@ pub unsafe fn uninitialized() -> T { /// assert_eq!(42, x); /// assert_eq!(5, y); /// ``` +/// +/// [`replace`]: fn.replace.html +/// [`take`]: fn.take.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn swap(x: &mut T, y: &mut T) { @@ -695,6 +701,9 @@ pub fn swap(x: &mut T, y: &mut T) { /// Replaces `dest` with the default value of `T`, returning the previous `dest` value. /// +/// * If you want to replace the values of two variables, see [`swap`]. +/// * If you want to replace with a passed value instead of the default value, see [`replace`]. +/// /// # Examples /// /// A simple example: @@ -747,6 +756,8 @@ pub fn swap(x: &mut T, y: &mut T) { /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html +/// [`replace`]: fn.replace.html +/// [`swap`]: fn.swap.html #[inline] #[stable(feature = "mem_take", since = "1.40.0")] pub fn take(dest: &mut T) -> T { @@ -757,6 +768,9 @@ pub fn take(dest: &mut T) -> T { /// /// Neither value is dropped. /// +/// * If you want to replace the values of two variables, see [`swap`]. +/// * If you want to replace with a default value, see [`take`]. +/// /// # Examples /// /// A simple example: @@ -810,6 +824,8 @@ pub fn take(dest: &mut T) -> T { /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html +/// [`swap`]: fn.swap.html +/// [`take`]: fn.take.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5f028f9ea76ca..68b5d1df71cb2 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1166,16 +1166,20 @@ pub unsafe fn write_volatile(dst: *mut T, src: T) { /// Any questions go to @nagisa. #[lang = "align_offset"] pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { + // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <= + // 1, where the method versions of these operations are not inlined. + use intrinsics::{unchecked_shl, unchecked_shr, unchecked_sub, wrapping_mul, wrapping_sub}; + /// Calculate multiplicative modular inverse of `x` modulo `m`. /// - /// This implementation is tailored for align_offset and has following preconditions: + /// This implementation is tailored for `align_offset` and has following preconditions: /// /// * `m` is a power-of-two; /// * `x < m`; (if `x ≥ m`, pass in `x % m` instead) /// /// Implementation of this function shall not panic. Ever. #[inline] - fn mod_inv(x: usize, m: usize) -> usize { + unsafe fn mod_inv(x: usize, m: usize) -> usize { /// Multiplicative modular inverse table modulo 2⁴ = 16. /// /// Note, that this table does not contain values where inverse does not exist (i.e., for @@ -1187,8 +1191,10 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { const INV_TABLE_MOD_SQUARED: usize = INV_TABLE_MOD * INV_TABLE_MOD; let table_inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize; + // SAFETY: `m` is required to be a power-of-two, hence non-zero. + let m_minus_one = unsafe { unchecked_sub(m, 1) }; if m <= INV_TABLE_MOD { - table_inverse & (m - 1) + table_inverse & m_minus_one } else { // We iterate "up" using the following formula: // @@ -1204,40 +1210,41 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod // usize::MAX` instead, because we take the result `mod n` at the end // anyway. - inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse))); + inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse))); if going_mod >= m { - return inverse & (m - 1); + return inverse & m_minus_one; } - going_mod = going_mod.wrapping_mul(going_mod); + going_mod = wrapping_mul(going_mod, going_mod); } } } let stride = mem::size_of::(); - let a_minus_one = a.wrapping_sub(1); - let pmoda = p as usize & a_minus_one; + // SAFETY: `a` is a power-of-two, therefore non-zero. + let a_minus_one = unsafe { unchecked_sub(a, 1) }; + if stride == 1 { + // `stride == 1` case can be computed more efficiently through `-p (mod a)`. + return wrapping_sub(0, p as usize) & a_minus_one; + } + let pmoda = p as usize & a_minus_one; if pmoda == 0 { // Already aligned. Yay! return 0; - } - - if stride <= 1 { - return if stride == 0 { - // If the pointer is not aligned, and the element is zero-sized, then no amount of - // elements will ever align the pointer. - !0 - } else { - a.wrapping_sub(pmoda) - }; + } else if stride == 0 { + // If the pointer is not aligned, and the element is zero-sized, then no amount of + // elements will ever align the pointer. + return usize::MAX; } let smoda = stride & a_minus_one; - // SAFETY: a is power-of-two so cannot be 0. stride = 0 is handled above. + // SAFETY: a is power-of-two hence non-zero. stride == 0 case is handled above. let gcdpow = unsafe { intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a)) }; - let gcd = 1usize << gcdpow; + // SAFETY: gcdpow has an upper-bound that’s at most the number of bits in an usize. + let gcd = unsafe { unchecked_shl(1usize, gcdpow) }; - if p as usize & (gcd.wrapping_sub(1)) == 0 { + // SAFETY: gcd is always greater or equal to 1. + if p as usize & unsafe { unchecked_sub(gcd, 1) } == 0 { // This branch solves for the following linear congruence equation: // // ` p + so = 0 mod a ` @@ -1245,8 +1252,8 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // `p` here is the pointer value, `s` - stride of `T`, `o` offset in `T`s, and `a` - the // requested alignment. // - // With `g = gcd(a, s)`, and the above asserting that `p` is also divisible by `g`, we can - // denote `a' = a/g`, `s' = s/g`, `p' = p/g`, then this becomes equivalent to: + // With `g = gcd(a, s)`, and the above condition asserting that `p` is also divisible by + // `g`, we can denote `a' = a/g`, `s' = s/g`, `p' = p/g`, then this becomes equivalent to: // // ` p' + s'o = 0 mod a' ` // ` o = (a' - (p' mod a')) * (s'^-1 mod a') ` @@ -1259,11 +1266,23 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // // Furthermore, the result produced by this solution is not "minimal", so it is necessary // to take the result `o mod lcm(s, a)`. We can replace `lcm(s, a)` with just a `a'`. - let a2 = a >> gcdpow; - let a2minus1 = a2.wrapping_sub(1); - let s2 = smoda >> gcdpow; - let minusp2 = a2.wrapping_sub(pmoda >> gcdpow); - return (minusp2.wrapping_mul(mod_inv(s2, a2))) & a2minus1; + + // SAFETY: `gcdpow` has an upper-bound not greater than the number of trailing 0-bits in + // `a`. + let a2 = unsafe { unchecked_shr(a, gcdpow) }; + // SAFETY: `a2` is non-zero. Shifting `a` by `gcdpow` cannot shift out any of the set bits + // in `a` (of which it has exactly one). + let a2minus1 = unsafe { unchecked_sub(a2, 1) }; + // SAFETY: `gcdpow` has an upper-bound not greater than the number of trailing 0-bits in + // `a`. + let s2 = unsafe { unchecked_shr(smoda, gcdpow) }; + // SAFETY: `gcdpow` has an upper-bound not greater than the number of trailing 0-bits in + // `a`. Furthermore, the subtraction cannot overflow, because `a2 = a >> gcdpow` will + // always be strictly greater than `(p % a) >> gcdpow`. + let minusp2 = unsafe { unchecked_sub(a2, unchecked_shr(pmoda, gcdpow)) }; + // SAFETY: `a2` is a power-of-two, as proven above. `s2` is strictly less than `a2` + // because `(s % a) >> gcdpow` is strictly less than `a >> gcdpow`. + return wrapping_mul(minusp2, unsafe { mod_inv(s2, a2) }) & a2minus1; } // Cannot be aligned at all. diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 934f581f3faeb..4705c984bd426 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2031,7 +2031,7 @@ mod traits { /// # Panics /// /// Panics if `begin` does not point to the starting byte offset of - /// a character (as defined by `is_char_boundary`), or if `begin >= len`. + /// a character (as defined by `is_char_boundary`), or if `begin > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] unsafe impl SliceIndex for ops::RangeFrom { type Output = str; diff --git a/library/core/tests/lazy.rs b/library/core/tests/lazy.rs index 1c0bddb9aef62..24f921ca7e4dc 100644 --- a/library/core/tests/lazy.rs +++ b/library/core/tests/lazy.rs @@ -122,3 +122,12 @@ fn reentrant_init() { }); eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); } + +#[test] +fn dropck() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } +} diff --git a/library/std/src/io/buffered.rs b/library/std/src/io/buffered.rs index b4c91cced43bf..f3aadf29b2f2b 100644 --- a/library/std/src/io/buffered.rs +++ b/library/std/src/io/buffered.rs @@ -21,17 +21,16 @@ use crate::memchr; /// *repeated* read calls to the same file or network socket. It does not /// help when reading very large amounts at once, or reading just one or a few /// times. It also provides no advantage when reading from a source that is -/// already in memory, like a `Vec`. +/// already in memory, like a [`Vec`]``. /// /// When the `BufReader` is dropped, the contents of its buffer will be /// discarded. Creating multiple instances of a `BufReader` on the same /// stream can cause data loss. Reading from the underlying reader after -/// unwrapping the `BufReader` with `BufReader::into_inner` can also cause +/// unwrapping the `BufReader` with [`BufReader::into_inner`] can also cause /// data loss. /// -/// [`Read`]: ../../std/io/trait.Read.html -/// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read -/// [`TcpStream`]: ../../std/net/struct.TcpStream.html +/// [`TcpStream::read`]: Read::read +/// [`TcpStream`]: crate::net::TcpStream /// /// # Examples /// @@ -155,7 +154,9 @@ impl BufReader { /// Returns a reference to the internally buffered data. /// - /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty. + /// Unlike [`fill_buf`], this will not attempt to fill the buffer if it is empty. + /// + /// [`fill_buf`]: BufRead::fill_buf /// /// # Examples /// @@ -338,27 +339,26 @@ where impl Seek for BufReader { /// Seek to an offset, in bytes, in the underlying reader. /// - /// The position used for seeking with `SeekFrom::Current(_)` is the + /// The position used for seeking with [`SeekFrom::Current`]`(_)` is the /// position the underlying reader would be at if the `BufReader` had no /// internal buffer. /// /// Seeking always discards the internal buffer, even if the seek position /// would otherwise fall within it. This guarantees that calling - /// `.into_inner()` immediately after a seek yields the underlying reader + /// [`BufReader::into_inner()`] immediately after a seek yields the underlying reader /// at the same position. /// /// To seek without discarding the internal buffer, use [`BufReader::seek_relative`]. /// /// See [`std::io::Seek`] for more details. /// - /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)` + /// Note: In the edge case where you're seeking with [`SeekFrom::Current`]`(n)` /// where `n` minus the internal buffer length overflows an `i64`, two /// seeks will be performed instead of one. If the second seek returns - /// `Err`, the underlying reader will be left at the same position it would - /// have if you called `seek` with `SeekFrom::Current(0)`. + /// [`Err`], the underlying reader will be left at the same position it would + /// have if you called `seek` with [`SeekFrom::Current`]`(0)`. /// - /// [`BufReader::seek_relative`]: struct.BufReader.html#method.seek_relative - /// [`std::io::Seek`]: trait.Seek.html + /// [`std::io::Seek`]: Seek fn seek(&mut self, pos: SeekFrom) -> io::Result { let result: u64; if let SeekFrom::Current(n) = pos { @@ -397,7 +397,7 @@ impl Seek for BufReader { /// *repeated* write calls to the same file or network socket. It does not /// help when writing very large amounts at once, or writing just one or a few /// times. It also provides no advantage when writing to a destination that is -/// in memory, like a `Vec`. +/// in memory, like a [`Vec`]`. /// /// It is critical to call [`flush`] before `BufWriter` is dropped. Though /// dropping will attempt to flush the contents of the buffer, any errors @@ -441,10 +441,9 @@ impl Seek for BufReader { /// together by the buffer and will all be written out in one system call when /// the `stream` is flushed. /// -/// [`Write`]: ../../std/io/trait.Write.html -/// [`TcpStream::write`]: ../../std/net/struct.TcpStream.html#method.write -/// [`TcpStream`]: ../../std/net/struct.TcpStream.html -/// [`flush`]: #method.flush +/// [`TcpStream::write`]: Write::write +/// [`TcpStream`]: crate::net::TcpStream +/// [`flush`]: Write::flush #[stable(feature = "rust1", since = "1.0.0")] pub struct BufWriter { inner: Option, @@ -455,7 +454,7 @@ pub struct BufWriter { panicked: bool, } -/// An error returned by `into_inner` which combines an error that +/// An error returned by [`BufWriter::into_inner`] which combines an error that /// happened while writing out the buffer, and the buffered writer object /// which may be used to recover from the condition. /// @@ -629,7 +628,7 @@ impl BufWriter { /// /// # Errors /// - /// An `Err` will be returned if an error occurs while flushing the buffer. + /// An [`Err`] will be returned if an error occurs while flushing the buffer. /// /// # Examples /// @@ -725,7 +724,8 @@ impl Drop for BufWriter { } impl IntoInnerError { - /// Returns the error which caused the call to `into_inner()` to fail. + /// Returns the error which caused the call to [`BufWriter::into_inner()`] + /// to fail. /// /// This error was returned when attempting to write the internal buffer. /// @@ -819,17 +819,15 @@ impl fmt::Display for IntoInnerError { /// Wraps a writer and buffers output to it, flushing whenever a newline /// (`0x0a`, `'\n'`) is detected. /// -/// The [`BufWriter`][bufwriter] struct wraps a writer and buffers its output. +/// The [`BufWriter`] struct wraps a writer and buffers its output. /// But it only does this batched write when it goes out of scope, or when the /// internal buffer is full. Sometimes, you'd prefer to write each line as it's /// completed, rather than the entire buffer at once. Enter `LineWriter`. It /// does exactly that. /// -/// Like [`BufWriter`][bufwriter], a `LineWriter`’s buffer will also be flushed when the +/// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the /// `LineWriter` goes out of scope or when its internal buffer is full. /// -/// [bufwriter]: struct.BufWriter.html -/// /// If there's still a partial line in the buffer when the `LineWriter` is /// dropped, it will flush those contents. /// @@ -979,7 +977,7 @@ impl LineWriter { /// /// # Errors /// - /// An `Err` will be returned if an error occurs while flushing the buffer. + /// An [`Err`] will be returned if an error occurs while flushing the buffer. /// /// # Examples /// diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index f4db5f8145060..58343f66f3ffd 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -9,7 +9,7 @@ use core::convert::TryInto; /// [`Seek`] implementation. /// /// `Cursor`s are used with in-memory buffers, anything implementing -/// `AsRef<[u8]>`, to allow them to implement [`Read`] and/or [`Write`], +/// [`AsRef`]`<[u8]>`, to allow them to implement [`Read`] and/or [`Write`], /// allowing these buffers to be used anywhere you might use a reader or writer /// that does actual I/O. /// @@ -23,12 +23,8 @@ use core::convert::TryInto; /// code, but use an in-memory buffer in our tests. We can do this with /// `Cursor`: /// -/// [`Seek`]: trait.Seek.html -/// [`Read`]: ../../std/io/trait.Read.html -/// [`Write`]: ../../std/io/trait.Write.html -/// [`Vec`]: ../../std/vec/struct.Vec.html -/// [bytes]: ../../std/primitive.slice.html -/// [`File`]: ../fs/struct.File.html +/// [bytes]: crate::slice +/// [`File`]: crate::fs::File /// /// ```no_run /// use std::io::prelude::*; @@ -81,8 +77,8 @@ pub struct Cursor { impl Cursor { /// Creates a new cursor wrapping the provided underlying in-memory buffer. /// - /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`) - /// is not empty. So writing to cursor starts with overwriting `Vec` + /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`]) + /// is not empty. So writing to cursor starts with overwriting [`Vec`] /// content, not with appending to it. /// /// # Examples diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index f7248e7547e27..e6eda2caf758f 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -4,8 +4,7 @@ use crate::fmt; use crate::result; use crate::sys; -/// A specialized [`Result`](../result/enum.Result.html) type for I/O -/// operations. +/// A specialized [`Result`] type for I/O operations. /// /// This type is broadly used across [`std::io`] for any operation which may /// produce an error. @@ -16,12 +15,13 @@ use crate::sys; /// While usual Rust style is to import types directly, aliases of [`Result`] /// often are not, to make it easier to distinguish between them. [`Result`] is /// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias -/// will generally use `io::Result` instead of shadowing the prelude's import +/// will generally use `io::Result` instead of shadowing the [prelude]'s import /// of [`std::result::Result`][`Result`]. /// -/// [`std::io`]: ../io/index.html -/// [`io::Error`]: ../io/struct.Error.html -/// [`Result`]: ../result/enum.Result.html +/// [`std::io`]: crate::io +/// [`io::Error`]: Error +/// [`Result`]: crate::result::Result +/// [prelude]: crate::prelude /// /// # Examples /// @@ -48,10 +48,9 @@ pub type Result = result::Result; /// `Error` can be created with crafted error messages and a particular value of /// [`ErrorKind`]. /// -/// [`Read`]: ../io/trait.Read.html -/// [`Write`]: ../io/trait.Write.html -/// [`Seek`]: ../io/trait.Seek.html -/// [`ErrorKind`]: enum.ErrorKind.html +/// [`Read`]: crate::io::Read +/// [`Write`]: crate::io::Write +/// [`Seek`]: crate::io::Seek #[stable(feature = "rust1", since = "1.0.0")] pub struct Error { repr: Repr, @@ -83,7 +82,7 @@ struct Custom { /// /// It is used with the [`io::Error`] type. /// -/// [`io::Error`]: struct.Error.html +/// [`io::Error`]: Error #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] @@ -137,7 +136,7 @@ pub enum ErrorKind { /// For example, a function that reads a file into a string will error with /// `InvalidData` if the file's contents are not valid UTF-8. /// - /// [`InvalidInput`]: #variant.InvalidInput + /// [`InvalidInput`]: ErrorKind::InvalidInput #[stable(feature = "io_invalid_data", since = "1.2.0")] InvalidData, /// The I/O operation's timeout expired, causing it to be canceled. @@ -150,8 +149,8 @@ pub enum ErrorKind { /// particular number of bytes but only a smaller number of bytes could be /// written. /// - /// [`write`]: ../../std/io/trait.Write.html#tymethod.write - /// [`Ok(0)`]: ../../std/io/type.Result.html + /// [`write`]: crate::io::Write::write + /// [`Ok(0)`]: Ok #[stable(feature = "rust1", since = "1.0.0")] WriteZero, /// This operation was interrupted. @@ -220,9 +219,6 @@ impl From for Error { /// let error = Error::from(not_found); /// assert_eq!("entity not found", format!("{}", error)); /// ``` - /// - /// [`ErrorKind`]: ../../std/io/enum.ErrorKind.html - /// [`Error`]: ../../std/io/struct.Error.html #[inline] fn from(kind: ErrorKind) -> Error { Error { repr: Repr::Simple(kind) } @@ -235,7 +231,7 @@ impl Error { /// /// This function is used to generically create I/O errors which do not /// originate from the OS itself. The `error` argument is an arbitrary - /// payload which will be contained in this `Error`. + /// payload which will be contained in this [`Error`]. /// /// # Examples /// @@ -264,7 +260,7 @@ impl Error { /// /// This function reads the value of `errno` for the target platform (e.g. /// `GetLastError` on Windows) and will return a corresponding instance of - /// `Error` for the error code. + /// [`Error`] for the error code. /// /// # Examples /// @@ -278,7 +274,7 @@ impl Error { Error::from_raw_os_error(sys::os::errno() as i32) } - /// Creates a new instance of an `Error` from a particular OS error code. + /// Creates a new instance of an [`Error`] from a particular OS error code. /// /// # Examples /// @@ -310,9 +306,12 @@ impl Error { /// Returns the OS error that this error represents (if any). /// - /// If this `Error` was constructed via `last_os_error` or - /// `from_raw_os_error`, then this function will return `Some`, otherwise - /// it will return `None`. + /// If this [`Error`] was constructed via [`last_os_error`] or + /// [`from_raw_os_error`], then this function will return [`Some`], otherwise + /// it will return [`None`]. + /// + /// [`last_os_error`]: Error::last_os_error + /// [`from_raw_os_error`]: Error::from_raw_os_error /// /// # Examples /// @@ -345,8 +344,10 @@ impl Error { /// Returns a reference to the inner error wrapped by this error (if any). /// - /// If this `Error` was constructed via `new` then this function will - /// return `Some`, otherwise it will return `None`. + /// If this [`Error`] was constructed via [`new`] then this function will + /// return [`Some`], otherwise it will return [`None`]. + /// + /// [`new`]: Error::new /// /// # Examples /// @@ -380,8 +381,10 @@ impl Error { /// Returns a mutable reference to the inner error wrapped by this error /// (if any). /// - /// If this `Error` was constructed via `new` then this function will - /// return `Some`, otherwise it will return `None`. + /// If this [`Error`] was constructed via [`new`] then this function will + /// return [`Some`], otherwise it will return [`None`]. + /// + /// [`new`]: Error::new /// /// # Examples /// @@ -448,8 +451,10 @@ impl Error { /// Consumes the `Error`, returning its inner error (if any). /// - /// If this `Error` was constructed via `new` then this function will - /// return `Some`, otherwise it will return `None`. + /// If this [`Error`] was constructed via [`new`] then this function will + /// return [`Some`], otherwise it will return [`None`]. + /// + /// [`new`]: Error::new /// /// # Examples /// @@ -480,7 +485,7 @@ impl Error { } } - /// Returns the corresponding `ErrorKind` for this error. + /// Returns the corresponding [`ErrorKind`] for this error. /// /// # Examples /// diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index e90ee5c285f2f..3245629483828 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -240,9 +240,9 @@ //! //! [`File`]: crate::fs::File //! [`TcpStream`]: crate::net::TcpStream -//! [`Vec`]: crate::vec::Vec +//! [`Vec`]: Vec //! [`io::stdout`]: stdout -//! [`io::Result`]: crate::io::Result +//! [`io::Result`]: self::Result //! [`?` operator]: ../../book/appendix-02-operators.html //! [`Result`]: crate::result::Result //! [`.unwrap()`]: crate::result::Result::unwrap @@ -671,15 +671,15 @@ pub trait Read { /// If the data in this stream is *not* valid UTF-8 then an error is /// returned and `buf` is unchanged. /// - /// See [`read_to_end`][readtoend] for other error semantics. + /// See [`read_to_end`] for other error semantics. /// - /// [readtoend]: Self::read_to_end + /// [`read_to_end`]: Read::read_to_end /// /// # Examples /// - /// [`File`][file]s implement `Read`: + /// [`File`]s implement `Read`: /// - /// [file]: crate::fs::File + /// [`File`]: crate::fs::File /// /// ```no_run /// use std::io; @@ -790,9 +790,9 @@ pub trait Read { /// /// # Examples /// - /// [`File`][file]s implement `Read`: + /// [`File`]s implement `Read`: /// - /// [file]: crate::fs::File + /// [`File`]: crate::fs::File /// /// ```no_run /// use std::io; @@ -834,10 +834,9 @@ pub trait Read { /// /// # Examples /// - /// [`File`][file]s implement `Read`: + /// [`File`]s implement `Read`: /// - /// [file]: crate::fs::File - /// [`Iterator`]: crate::iter::Iterator + /// [`File`]: crate::fs::File /// [`Result`]: crate::result::Result /// [`io::Error`]: self::Error /// @@ -871,9 +870,9 @@ pub trait Read { /// /// # Examples /// - /// [`File`][file]s implement `Read`: + /// [`File`]s implement `Read`: /// - /// [file]: crate::fs::File + /// [`File`]: crate::fs::File /// /// ```no_run /// use std::io; @@ -1210,8 +1209,8 @@ impl Initializer { /// throughout [`std::io`] take and provide types which implement the `Write` /// trait. /// -/// [`write`]: Self::write -/// [`flush`]: Self::flush +/// [`write`]: Write::write +/// [`flush`]: Write::flush /// [`std::io`]: self /// /// # Examples @@ -1237,7 +1236,7 @@ impl Initializer { /// The trait also provides convenience methods like [`write_all`], which calls /// `write` in a loop until its entire input has been written. /// -/// [`write_all`]: Self::write_all +/// [`write_all`]: Write::write_all #[stable(feature = "rust1", since = "1.0.0")] #[doc(spotlight)] pub trait Write { @@ -1283,30 +1282,36 @@ pub trait Write { /// Ok(()) /// } /// ``` + /// + /// [`Ok(n)`]: Ok #[stable(feature = "rust1", since = "1.0.0")] fn write(&mut self, buf: &[u8]) -> Result; - /// Like `write`, except that it writes from a slice of buffers. + /// Like [`write`], except that it writes from a slice of buffers. /// /// Data is copied from each buffer in order, with the final buffer /// read from possibly being only partially consumed. This method must - /// behave as a call to `write` with the buffers concatenated would. + /// behave as a call to [`write`] with the buffers concatenated would. /// - /// The default implementation calls `write` with either the first nonempty + /// The default implementation calls [`write`] with either the first nonempty /// buffer provided, or an empty one if none exists. + /// + /// [`write`]: Write::write #[stable(feature = "iovec", since = "1.36.0")] fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { default_write_vectored(|b| self.write(b), bufs) } - /// Determines if this `Write`er has an efficient `write_vectored` + /// Determines if this `Write`er has an efficient [`write_vectored`] /// implementation. /// - /// If a `Write`er does not override the default `write_vectored` + /// If a `Write`er does not override the default [`write_vectored`] /// implementation, code using it may want to avoid the method all together /// and coalesce writes into a single buffer for higher performance. /// /// The default implementation returns `false`. + /// + /// [`write_vectored`]: Write::write_vectored #[unstable(feature = "can_vector", issue = "69941")] fn is_write_vectored(&self) -> bool { false @@ -1354,7 +1359,7 @@ pub trait Write { /// This function will return the first error of /// non-[`ErrorKind::Interrupted`] kind that [`write`] returns. /// - /// [`write`]: Self::write + /// [`write`]: Write::write /// /// # Examples /// @@ -1395,22 +1400,21 @@ pub trait Write { /// /// If the buffer contains no data, this will never call [`write_vectored`]. /// - /// [`write_vectored`]: Self::write_vectored - /// /// # Notes /// - /// - /// Unlike `io::Write::write_vectored`, this takes a *mutable* reference to - /// a slice of `IoSlice`s, not an immutable one. That's because we need to + /// Unlike [`write_vectored`], this takes a *mutable* reference to + /// a slice of [`IoSlice`]s, not an immutable one. That's because we need to /// modify the slice to keep track of the bytes already written. /// /// Once this function returns, the contents of `bufs` are unspecified, as - /// this depends on how many calls to `write_vectored` were necessary. It is + /// this depends on how many calls to [`write_vectored`] were necessary. It is /// best to understand this function as taking ownership of `bufs` and to /// not use `bufs` afterwards. The underlying buffers, to which the - /// `IoSlice`s point (but not the `IoSlice`s themselves), are unchanged and + /// [`IoSlice`]s point (but not the [`IoSlice`]s themselves), are unchanged and /// can be reused. /// + /// [`write_vectored`]: Write::write_vectored + /// /// # Examples /// /// ``` @@ -1458,12 +1462,12 @@ pub trait Write { /// explicitly be called. The [`write!()`] macro should be favored to /// invoke this method instead. /// - /// This function internally uses the [`write_all`][writeall] method on + /// This function internally uses the [`write_all`] method on /// this trait and hence will continuously write data so long as no errors /// are received. This also means that partial writes are not indicated in /// this signature. /// - /// [writeall]: Self::write_all + /// [`write_all`]: Write::write_all /// /// # Errors /// @@ -1558,9 +1562,9 @@ pub trait Write { /// /// # Examples /// -/// [`File`][file]s implement `Seek`: +/// [`File`]s implement `Seek`: /// -/// [file]: crate::fs::File +/// [`File`]: crate::fs::File /// /// ```no_run /// use std::io; @@ -1610,7 +1614,6 @@ pub trait Seek { /// data is appended to a file). So calling this method multiple times does /// not necessarily return the same length each time. /// - /// /// # Example /// /// ```no_run @@ -1646,7 +1649,6 @@ pub trait Seek { /// /// This is equivalent to `self.seek(SeekFrom::Current(0))`. /// - /// /// # Example /// /// ```no_run @@ -1756,8 +1758,8 @@ fn read_until(r: &mut R, delim: u8, buf: &mut Vec) -> R /// [`BufReader`] to the rescue! /// /// [`File`]: crate::fs::File -/// [`read_line`]: Self::read_line -/// [`lines`]: Self::lines +/// [`read_line`]: BufRead::read_line +/// [`lines`]: BufRead::lines /// /// ```no_run /// use std::io::{self, BufReader}; @@ -1775,7 +1777,6 @@ fn read_until(r: &mut R, delim: u8, buf: &mut Vec) -> R /// Ok(()) /// } /// ``` -/// #[stable(feature = "rust1", since = "1.0.0")] pub trait BufRead: Read { /// Returns the contents of the internal buffer, filling it with more data @@ -1788,7 +1789,7 @@ pub trait BufRead: Read { /// be called with the number of bytes that are consumed from this buffer to /// ensure that the bytes are never returned twice. /// - /// [`consume`]: Self::consume + /// [`consume`]: BufRead::consume /// /// An empty buffer returned indicates that the stream has reached EOF. /// @@ -1838,7 +1839,7 @@ pub trait BufRead: Read { /// Since `consume()` is meant to be used with [`fill_buf`], /// that method's example includes an example of `consume()`. /// - /// [`fill_buf`]: Self::fill_buf + /// [`fill_buf`]: BufRead::fill_buf #[stable(feature = "rust1", since = "1.0.0")] fn consume(&mut self, amt: usize); @@ -1862,7 +1863,7 @@ pub trait BufRead: Read { /// If an I/O error is encountered then all bytes read so far will be /// present in `buf` and its length will have been adjusted appropriately. /// - /// [`fill_buf`]: Self::fill_buf + /// [`fill_buf`]: BufRead::fill_buf /// /// # Examples /// @@ -1901,22 +1902,24 @@ pub trait BufRead: Read { read_until(self, byte, buf) } - /// Read all bytes until a newline (the 0xA byte) is reached, and append + /// Read all bytes until a newline (the `0xA` byte) is reached, and append /// them to the provided buffer. /// /// This function will read bytes from the underlying stream until the - /// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes + /// newline delimiter (the `0xA` byte) or EOF is found. Once found, all bytes /// up to, and including, the delimiter (if found) will be appended to /// `buf`. /// /// If successful, this function will return the total number of bytes read. /// - /// If this function returns `Ok(0)`, the stream has reached EOF. + /// If this function returns [`Ok(0)`], the stream has reached EOF. /// /// This function is blocking and should be used carefully: it is possible for /// an attacker to continuously send bytes without ever sending a newline /// or EOF. /// + /// [`Ok(0)`]: Ok + /// /// # Errors /// /// This function has the same error semantics as [`read_until`] and will @@ -1924,7 +1927,7 @@ pub trait BufRead: Read { /// error is encountered then `buf` may contain some bytes already read in /// the event that all data read so far was valid UTF-8. /// - /// [`read_until`]: Self::read_until + /// [`read_until`]: BufRead::read_until /// /// # Examples /// @@ -1976,8 +1979,8 @@ pub trait BufRead: Read { /// also yielded an error. /// /// [`io::Result`]: self::Result - /// [`Vec`]: crate::vec::Vec - /// [`read_until`]: Self::read_until + /// [`Vec`]: Vec + /// [`read_until`]: BufRead::read_until /// /// # Examples /// @@ -2008,7 +2011,7 @@ pub trait BufRead: Read { /// /// The iterator returned from this function will yield instances of /// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline - /// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end. + /// byte (the `0xA` byte) or `CRLF` (`0xD`, `0xA` bytes) at the end. /// /// [`io::Result`]: self::Result /// diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 156f555be02d8..286eb92915e49 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -252,8 +252,7 @@ fn handle_ebadf(r: io::Result, default: T) -> io::Result { /// /// Created by the [`io::stdin`] method. /// -/// [`io::stdin`]: fn.stdin.html -/// [`BufRead`]: trait.BufRead.html +/// [`io::stdin`]: stdin /// /// ### Note: Windows Portability Consideration /// @@ -283,10 +282,6 @@ pub struct Stdin { /// This handle implements both the [`Read`] and [`BufRead`] traits, and /// is constructed via the [`Stdin::lock`] method. /// -/// [`Read`]: trait.Read.html -/// [`BufRead`]: trait.BufRead.html -/// [`Stdin::lock`]: struct.Stdin.html#method.lock -/// /// ### Note: Windows Portability Consideration /// /// When operating in a console, the Windows implementation of this stream does not support @@ -319,8 +314,6 @@ pub struct StdinLock<'a> { /// is synchronized via a mutex. If you need more explicit control over /// locking, see the [`Stdin::lock`] method. /// -/// [`Stdin::lock`]: struct.Stdin.html#method.lock -/// /// ### Note: Windows Portability Consideration /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return @@ -380,9 +373,6 @@ impl Stdin { /// returned guard also implements the [`Read`] and [`BufRead`] traits for /// accessing the underlying data. /// - /// [`Read`]: trait.Read.html - /// [`BufRead`]: trait.BufRead.html - /// /// # Examples /// /// ```no_run @@ -407,8 +397,6 @@ impl Stdin { /// For detailed semantics of this method, see the documentation on /// [`BufRead::read_line`]. /// - /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line - /// /// # Examples /// /// ```no_run @@ -542,8 +530,8 @@ impl fmt::Debug for StdinLock<'_> { /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return /// an error. /// -/// [`lock`]: #method.lock -/// [`io::stdout`]: fn.stdout.html +/// [`lock`]: Stdout::lock +/// [`io::stdout`]: stdout #[stable(feature = "rust1", since = "1.0.0")] pub struct Stdout { // FIXME: this should be LineWriter or BufWriter depending on the state of @@ -561,9 +549,6 @@ pub struct Stdout { /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return /// an error. -/// -/// [`Write`]: trait.Write.html -/// [`Stdout::lock`]: struct.Stdout.html#method.lock #[stable(feature = "rust1", since = "1.0.0")] pub struct StdoutLock<'a> { inner: ReentrantMutexGuard<'a, RefCell>>>, @@ -575,8 +560,6 @@ pub struct StdoutLock<'a> { /// is synchronized via a mutex. If you need more explicit control over /// locking, see the [`Stdout::lock`] method. /// -/// [`Stdout::lock`]: struct.Stdout.html#method.lock -/// /// ### Note: Windows Portability Consideration /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return @@ -724,7 +707,7 @@ impl fmt::Debug for StdoutLock<'_> { /// /// For more information, see the [`io::stderr`] method. /// -/// [`io::stderr`]: fn.stderr.html +/// [`io::stderr`]: stderr /// /// ### Note: Windows Portability Consideration /// When operating in a console, the Windows implementation of this stream does not support @@ -740,8 +723,6 @@ pub struct Stderr { /// This handle implements the `Write` trait and is constructed via /// the [`Stderr::lock`] method. /// -/// [`Stderr::lock`]: struct.Stderr.html#method.lock -/// /// ### Note: Windows Portability Consideration /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return @@ -819,7 +800,7 @@ impl Stderr { /// guard. /// /// The lock is released when the returned lock goes out of scope. The - /// returned guard also implements the `Write` trait for writing data. + /// returned guard also implements the [`Write`] trait for writing data. /// /// # Examples /// diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index b9d5dc27db006..a093b745b0c13 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -16,14 +16,17 @@ use crate::mem::MaybeUninit; /// If you’re wanting to copy the contents of one file to another and you’re /// working with filesystem paths, see the [`fs::copy`] function. /// -/// [`fs::copy`]: ../fs/fn.copy.html +/// [`fs::copy`]: crate::fs::copy /// /// # Errors /// -/// This function will return an error immediately if any call to `read` or -/// `write` returns an error. All instances of `ErrorKind::Interrupted` are +/// This function will return an error immediately if any call to [`read`] or +/// [`write`] returns an error. All instances of [`ErrorKind::Interrupted`] are /// handled by this function and the underlying operation is retried. /// +/// [`read`]: Read::read +/// [`write`]: Write::write +/// /// # Examples /// /// ``` @@ -70,10 +73,8 @@ where /// A reader which is always at EOF. /// -/// This struct is generally created by calling [`empty`]. Please see -/// the documentation of [`empty()`][`empty`] for more details. -/// -/// [`empty`]: fn.empty.html +/// This struct is generally created by calling [`empty()`]. Please see +/// the documentation of [`empty()`] for more details. #[stable(feature = "rust1", since = "1.0.0")] pub struct Empty { _priv: (), @@ -83,8 +84,6 @@ pub struct Empty { /// /// All reads from the returned reader will return [`Ok`]`(0)`. /// -/// [`Ok`]: ../result/enum.Result.html#variant.Ok -/// /// # Examples /// /// A slightly sad example of not reading anything into a buffer: @@ -132,10 +131,8 @@ impl fmt::Debug for Empty { /// A reader which yields one byte over and over and over and over and over and... /// -/// This struct is generally created by calling [`repeat`][repeat]. Please -/// see the documentation of `repeat()` for more details. -/// -/// [repeat]: fn.repeat.html +/// This struct is generally created by calling [`repeat()`]. Please +/// see the documentation of [`repeat()`] for more details. #[stable(feature = "rust1", since = "1.0.0")] pub struct Repeat { byte: u8, @@ -199,10 +196,8 @@ impl fmt::Debug for Repeat { /// A writer which will move data into the void. /// -/// This struct is generally created by calling [`sink`][sink]. Please -/// see the documentation of `sink()` for more details. -/// -/// [sink]: fn.sink.html +/// This struct is generally created by calling [`sink`]. Please +/// see the documentation of [`sink()`] for more details. #[stable(feature = "rust1", since = "1.0.0")] pub struct Sink { _priv: (), @@ -210,9 +205,11 @@ pub struct Sink { /// Creates an instance of a writer which will successfully consume all data. /// -/// All calls to `write` on the returned instance will return `Ok(buf.len())` +/// All calls to [`write`] on the returned instance will return `Ok(buf.len())` /// and the contents of the buffer will not be inspected. /// +/// [`write`]: Write::write +/// /// # Examples /// /// ```rust diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index c39989a60c92b..af25c39fccfd0 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -98,7 +98,6 @@ mod as_keyword {} /// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions /// [Reference on "break and loop values"]: /// ../reference/expressions/loop-expr.html#break-and-loop-values -/// mod break_keyword {} #[doc(keyword = "const")] @@ -336,7 +335,6 @@ mod else_keyword {} /// For more information, take a look at the [Rust Book] or the [Reference] /// /// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type -/// [`Option`]: option/enum.Option.html /// [Rust Book]: ../book/ch06-01-defining-an-enum.html /// [Reference]: ../reference/items/enumerations.html mod enum_keyword {} @@ -534,7 +532,6 @@ mod fn_keyword {} /// [`in`]: keyword.in.html /// [`impl`]: keyword.impl.html /// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds -/// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: /// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops @@ -993,7 +990,6 @@ mod mod_keyword {} /// For more information on the `move` keyword, see the [closure]'s section /// of the Rust book or the [threads] section /// -/// [`Fn` trait]: ../std/ops/trait.Fn.html /// [closure]: ../book/ch13-01-closures.html /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads mod move_keyword {} @@ -1413,9 +1409,7 @@ mod self_upper_keyword {} /// [`extern`]: keyword.extern.html /// [`mut`]: keyword.mut.html /// [`unsafe`]: keyword.unsafe.html -/// [`drop`]: mem/fn.drop.html -/// [`Sync`]: marker/trait.Sync.html -/// [`RefCell`]: cell/struct.RefCell.html +/// [`RefCell`]: cell::RefCell /// [Reference]: ../reference/items/static-items.html mod static_keyword {} @@ -1522,7 +1516,7 @@ mod static_keyword {} /// For more information on structs, take a look at the [Rust Book][book] or the /// [Reference][reference]. /// -/// [`PhantomData`]: marker/struct.PhantomData.html +/// [`PhantomData`]: marker::PhantomData /// [book]: ../book/ch05-01-defining-structs.html /// [reference]: ../reference/items/structs.html mod struct_keyword {} @@ -1733,8 +1727,6 @@ mod super_keyword {} /// [`for`]: keyword.for.html /// [`impl`]: keyword.impl.html /// [`unsafe`]: keyword.unsafe.html -/// [`Send`]: marker/trait.Send.html -/// [`Sync`]: marker/trait.Sync.html /// [Ref-Traits]: ../reference/items/traits.html /// [Ref-Trait-Objects]: ../reference/types/trait-object.html mod trait_keyword {} @@ -1764,7 +1756,6 @@ mod trait_keyword {} /// [`while`]: keyword.while.html /// [`match`]: ../reference/expressions/match-expr.html#match-guards /// [`false`]: keyword.false.html -/// [`bool`]: primitive.bool.html mod true_keyword {} #[doc(keyword = "type")] @@ -1986,9 +1977,6 @@ mod type_keyword {} /// [`static`]: keyword.static.html /// [`union`]: keyword.union.html /// [`impl`]: keyword.impl.html -/// [Send]: marker/trait.Send.html -/// [Sync]: marker/trait.Sync.html -/// [`Vec::set_len`]: vec/struct.Vec.html#method.set_len /// [raw pointers]: ../reference/types/pointer.html /// [memory safety]: ../book/ch19-01-unsafe-rust.html /// [Rustnomicon]: ../nomicon/index.html @@ -2178,7 +2166,7 @@ mod where_keyword {} /// /// It is available for use in stable rust from version 1.39 onwards. /// -/// [`Future`]: ./future/trait.Future.html +/// [`Future`]: future::Future /// [async book]: https://rust-lang.github.io/async-book/ mod async_keyword {} @@ -2197,7 +2185,7 @@ mod async_keyword {} /// /// It is available for use in stable rust from version 1.39 onwards. /// -/// [`Future`]: ./future/trait.Future.html +/// [`Future`]: future::Future /// [async book]: https://rust-lang.github.io/async-book/ mod await_keyword {} diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs index 60eba96bcc015..f0548582d2f5d 100644 --- a/library/std/src/lazy.rs +++ b/library/std/src/lazy.rs @@ -386,9 +386,10 @@ impl SyncOnceCell { } } -impl Drop for SyncOnceCell { +unsafe impl<#[may_dangle] T> Drop for SyncOnceCell { fn drop(&mut self) { - // Safety: The cell is being dropped, so it can't be accessed again + // Safety: The cell is being dropped, so it can't be accessed again. + // We also don't touch the `T`, which validates our usage of #[may_dangle]. unsafe { self.take_inner() }; } } @@ -516,6 +517,7 @@ mod tests { mpsc::channel, Mutex, }, + thread, }; #[test] @@ -552,26 +554,8 @@ mod tests { } } - // miri doesn't support threads - #[cfg(not(miri))] fn spawn_and_wait(f: impl FnOnce() -> R + Send + 'static) -> R { - crate::thread::spawn(f).join().unwrap() - } - - #[cfg(not(miri))] - fn spawn(f: impl FnOnce() + Send + 'static) { - let _ = crate::thread::spawn(f); - } - - // "stub threads" for Miri - #[cfg(miri)] - fn spawn_and_wait(f: impl FnOnce() -> R + Send + 'static) -> R { - f(()) - } - - #[cfg(miri)] - fn spawn(f: impl FnOnce() + Send + 'static) { - f(()) + thread::spawn(f).join().unwrap() } #[test] @@ -734,7 +718,6 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // leaks memory fn static_sync_lazy() { static XS: SyncLazy> = SyncLazy::new(|| { let mut xs = Vec::new(); @@ -752,7 +735,6 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // leaks memory fn static_sync_lazy_via_fn() { fn xs() -> &'static Vec { static XS: SyncOnceCell> = SyncOnceCell::new(); @@ -811,7 +793,6 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // deadlocks without real threads fn sync_once_cell_does_not_leak_partially_constructed_boxes() { static ONCE_CELL: SyncOnceCell = SyncOnceCell::new(); @@ -823,7 +804,7 @@ mod tests { for _ in 0..n_readers { let tx = tx.clone(); - spawn(move || { + thread::spawn(move || { loop { if let Some(msg) = ONCE_CELL.get() { tx.send(msg).unwrap(); @@ -835,7 +816,7 @@ mod tests { }); } for _ in 0..n_writers { - spawn(move || { + thread::spawn(move || { let _ = ONCE_CELL.set(MSG.to_owned()); }); } @@ -845,4 +826,13 @@ mod tests { assert_eq!(msg, MSG); } } + + #[test] + fn dropck() { + let cell = SyncOnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } + } } diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs index f174a59b49a6b..b590a0280d138 100644 --- a/library/std/src/sys/unix/ext/fs.rs +++ b/library/std/src/sys/unix/ext/fs.rs @@ -9,9 +9,7 @@ use crate::sys; use crate::sys::platform::fs::MetadataExt as UnixMetadataExt; use crate::sys_common::{AsInner, AsInnerMut, FromInner}; -/// Unix-specific extensions to [`File`]. -/// -/// [`File`]: ../../../../std/fs/struct.File.html +/// Unix-specific extensions to [`fs::File`]. #[stable(feature = "file_offset", since = "1.15.0")] pub trait FileExt { /// Reads a number of bytes starting from a given offset. @@ -55,19 +53,18 @@ pub trait FileExt { /// /// The current file cursor is not affected by this function. /// - /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`. + /// Similar to [`io::Read::read_exact`] but uses [`read_at`] instead of `read`. /// - /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact - /// [`read_at`]: #tymethod.read_at + /// [`read_at`]: FileExt::read_at /// /// # Errors /// /// If this function encounters an error of the kind - /// [`ErrorKind::Interrupted`] then the error is ignored and the operation + /// [`io::ErrorKind::Interrupted`] then the error is ignored and the operation /// will continue. /// /// If this function encounters an "end of file" before completely filling - /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`]. + /// the buffer, it returns an error of the kind [`io::ErrorKind::UnexpectedEof`]. /// The contents of `buf` are unspecified in this case. /// /// If any other read error is encountered then this function immediately @@ -77,9 +74,6 @@ pub trait FileExt { /// has read, but it will never read more than would be necessary to /// completely fill the buffer. /// - /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted - /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof - /// /// # Examples /// /// ```no_run @@ -161,19 +155,18 @@ pub trait FileExt { /// The current file cursor is not affected by this function. /// /// This method will continuously call [`write_at`] until there is no more data - /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is + /// to be written or an error of non-[`io::ErrorKind::Interrupted`] kind is /// returned. This method will not return until the entire buffer has been /// successfully written or such an error occurs. The first error that is - /// not of [`ErrorKind::Interrupted`] kind generated from this method will be + /// not of [`io::ErrorKind::Interrupted`] kind generated from this method will be /// returned. /// /// # Errors /// /// This function will return the first error of - /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns. + /// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns. /// - /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted - /// [`write_at`]: #tymethod.write_at + /// [`write_at`]: FileExt::write_at /// /// # Examples /// @@ -223,8 +216,6 @@ impl FileExt for fs::File { } /// Unix-specific extensions to [`fs::Permissions`]. -/// -/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html #[stable(feature = "fs_ext", since = "1.1.0")] pub trait PermissionsExt { /// Returns the underlying raw `st_mode` bits that contain the standard @@ -302,8 +293,6 @@ impl PermissionsExt for Permissions { } /// Unix-specific extensions to [`fs::OpenOptions`]. -/// -/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html #[stable(feature = "fs_ext", since = "1.1.0")] pub trait OpenOptionsExt { /// Sets the mode bits that a new file will be created with. @@ -372,8 +361,6 @@ impl OpenOptionsExt for OpenOptions { } /// Unix-specific extensions to [`fs::Metadata`]. -/// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Returns the ID of the device containing the file. @@ -535,7 +522,7 @@ pub trait MetadataExt { fn atime(&self) -> i64; /// Returns the last access time of the file, in nanoseconds since [`atime`]. /// - /// [`atime`]: #tymethod.atime + /// [`atime`]: MetadataExt::atime /// /// # Examples /// @@ -571,7 +558,7 @@ pub trait MetadataExt { fn mtime(&self) -> i64; /// Returns the last modification time of the file, in nanoseconds since [`mtime`]. /// - /// [`mtime`]: #tymethod.mtime + /// [`mtime`]: MetadataExt::mtime /// /// # Examples /// @@ -607,7 +594,7 @@ pub trait MetadataExt { fn ctime(&self) -> i64; /// Returns the last status change time of the file, in nanoseconds since [`ctime`]. /// - /// [`ctime`]: #tymethod.ctime + /// [`ctime`]: MetadataExt::ctime /// /// # Examples /// @@ -714,12 +701,10 @@ impl MetadataExt for fs::Metadata { } } -/// Unix-specific extensions for [`FileType`]. +/// Unix-specific extensions for [`fs::FileType`]. /// /// Adds support for special Unix file types such as block/character devices, /// pipes, and sockets. -/// -/// [`FileType`]: ../../../../std/fs/struct.FileType.html #[stable(feature = "file_type_ext", since = "1.5.0")] pub trait FileTypeExt { /// Returns `true` if this file type is a block device. @@ -813,8 +798,6 @@ impl FileTypeExt for fs::FileType { } /// Unix-specific extension methods for [`fs::DirEntry`]. -/// -/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub trait DirEntryExt { /// Returns the underlying `d_ino` field in the contained `dirent` @@ -875,8 +858,6 @@ pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> } /// Unix-specific extensions to [`fs::DirBuilder`]. -/// -/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html #[stable(feature = "dir_builder", since = "1.6.0")] pub trait DirBuilderExt { /// Sets the mode to create new directories with. This option defaults to diff --git a/library/std/src/sys/unix/ext/net.rs b/library/std/src/sys/unix/ext/net.rs index ada8eaa1c9745..55803ddfc4323 100644 --- a/library/std/src/sys/unix/ext/net.rs +++ b/library/std/src/sys/unix/ext/net.rs @@ -408,10 +408,7 @@ impl UnixStream { /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this /// method. /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err - /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read - /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// [`read`]: io::Read::read /// /// # Examples /// @@ -453,10 +450,7 @@ impl UnixStream { /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is /// passed to this method. /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err - /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write - /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// [`read`]: io::Read::read /// /// # Examples /// @@ -581,8 +575,6 @@ impl UnixStream { /// specified portions to immediately return with an appropriate value /// (see the documentation of [`Shutdown`]). /// - /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html - /// /// # Examples /// /// ```no_run @@ -852,7 +844,7 @@ impl UnixListener { /// is established. When established, the corresponding [`UnixStream`] and /// the remote peer's address will be returned. /// - /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html + /// [`UnixStream`]: crate::os::unix::net::UnixStream /// /// # Examples /// @@ -937,8 +929,6 @@ impl UnixListener { /// Ok(()) /// } /// ``` - /// - /// [`io::ErrorKind::WouldBlock`]: ../../../io/enum.ErrorKind.html#variant.WouldBlock #[stable(feature = "unix_socket", since = "1.10.0")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { self.0.set_nonblocking(nonblocking) @@ -973,9 +963,6 @@ impl UnixListener { /// The iterator will never return [`None`] and will also not yield the /// peer's [`SocketAddr`] structure. /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`SocketAddr`]: struct.SocketAddr.html - /// /// # Examples /// /// ```no_run @@ -1043,9 +1030,6 @@ impl<'a> IntoIterator for &'a UnixListener { /// /// It will never return [`None`]. /// -/// [`None`]: ../../../../std/option/enum.Option.html#variant.None -/// [`UnixListener`]: struct.UnixListener.html -/// /// # Examples /// /// ```no_run @@ -1205,9 +1189,9 @@ impl UnixDatagram { /// The [`send`] method may be used to send data to the specified address. /// [`recv`] and [`recv_from`] will only receive data from that address. /// - /// [`send`]: #method.send - /// [`recv`]: #method.recv - /// [`recv_from`]: #method.recv_from + /// [`send`]: UnixDatagram::send + /// [`recv`]: UnixDatagram::recv + /// [`recv_from`]: UnixDatagram::recv_from /// /// # Examples /// @@ -1284,7 +1268,7 @@ impl UnixDatagram { /// /// The [`connect`] method will connect the socket to a peer. /// - /// [`connect`]: #method.connect + /// [`connect`]: UnixDatagram::connect /// /// # Examples /// @@ -1432,11 +1416,8 @@ impl UnixDatagram { /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] /// is passed to this method. /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err - /// [`recv`]: #method.recv - /// [`recv_from`]: #method.recv_from - /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// [`recv`]: UnixDatagram::recv + /// [`recv_from`]: UnixDatagram::recv_from /// /// # Examples /// @@ -1479,10 +1460,8 @@ impl UnixDatagram { /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this /// method. /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`send`]: #method.send - /// [`send_to`]: #method.send_to - /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// [`send`]: UnixDatagram::send + /// [`send_to`]: UnixDatagram::send_to /// /// # Examples /// @@ -1605,8 +1584,6 @@ impl UnixDatagram { /// specified portions to immediately return with an appropriate value /// (see the documentation of [`Shutdown`]). /// - /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html - /// /// ```no_run /// use std::os::unix::net::UnixDatagram; /// use std::net::Shutdown; diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 048ce24d6ba88..82527c40e9138 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -10,8 +10,6 @@ use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; /// Unix-specific extensions to the [`process::Command`] builder. -/// -/// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { /// Sets the child process's user ID. This translates to a @@ -65,7 +63,7 @@ pub trait CommandExt { /// This method is stable and usable, but it should be unsafe. To fix /// that, it got deprecated in favor of the unsafe [`pre_exec`]. /// - /// [`pre_exec`]: #tymethod.pre_exec + /// [`pre_exec`]: CommandExt::pre_exec #[stable(feature = "process_exec", since = "1.15.0")] #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command @@ -94,8 +92,6 @@ pub trait CommandExt { /// a new child. Like spawn, however, the default behavior for the stdio /// descriptors will be to inherited from the current process. /// - /// [`process::exit`]: ../../../process/fn.exit.html - /// /// # Notes /// /// The process may be in a "broken state" if this function returns in @@ -151,8 +147,6 @@ impl CommandExt for process::Command { } /// Unix-specific extensions to [`process::ExitStatus`]. -/// -/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html #[stable(feature = "rust1", since = "1.0.0")] pub trait ExitStatusExt { /// Creates a new `ExitStatus` from the raw underlying `i32` return value of diff --git a/library/std/src/sys/unix/ext/thread.rs b/library/std/src/sys/unix/ext/thread.rs index 759ef6236e804..7221da1a9a7bb 100644 --- a/library/std/src/sys/unix/ext/thread.rs +++ b/library/std/src/sys/unix/ext/thread.rs @@ -11,9 +11,7 @@ use crate::thread::JoinHandle; #[allow(deprecated)] pub type RawPthread = pthread_t; -/// Unix-specific extensions to [`thread::JoinHandle`]. -/// -/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html +/// Unix-specific extensions to [`JoinHandle`]. #[stable(feature = "thread_extensions", since = "1.9.0")] pub trait JoinHandleExt { /// Extracts the raw pthread_t without taking ownership diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 98b6be29c073b..01121977f130b 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -162,7 +162,7 @@ impl Step for RustcDocs { let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple)); let _ = fs::remove_dir_all(&image); - let dst = image.join("share/doc/rust/html"); + let dst = image.join("share/doc/rust/html/rustc"); t!(fs::create_dir_all(&dst)); let src = builder.compiler_doc_out(host); builder.cp_r(&src, &dst); @@ -181,7 +181,7 @@ impl Step for RustcDocs { .arg(format!("--package-name={}-{}", name, host.triple)) .arg("--component-name=rustc-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rust/html"); + .arg("--bulk-dirs=share/doc/rust/html/rustc"); builder.info(&format!("Dist compiler docs ({})", host)); let _time = timeit(builder); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index f1bc3d11d8b77..eca9ddceae1b5 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -454,7 +454,8 @@ fn configure_cmake( } } cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) - .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)); + .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)) + .define("CMAKE_ASM_COMPILER", sanitize_cc(cc)); } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 1937f615e701f..af4a7bd18813e 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -7,6 +7,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![allow(incomplete_features)] #![feature(in_band_lifetimes)] #![feature(unboxed_closures)] #![feature(generators)] @@ -23,6 +24,8 @@ #![feature(associated_type_bounds)] #![feature(thread_id_value)] #![feature(extend_one)] +#![feature(const_panic)] +#![feature(const_generics)] #![allow(rustc::default_hash_types)] #[macro_use] @@ -97,6 +100,7 @@ pub mod vec_linked_list; pub mod work_queue; pub use atomic_ref::AtomicRef; pub mod frozen; +pub mod tagged_ptr; pub mod temp_dir; pub struct OnDrop(pub F); diff --git a/src/librustc_data_structures/tagged_ptr.rs b/src/librustc_data_structures/tagged_ptr.rs new file mode 100644 index 0000000000000..e3839d193651d --- /dev/null +++ b/src/librustc_data_structures/tagged_ptr.rs @@ -0,0 +1,157 @@ +//! This module implements tagged pointers. +//! +//! In order to utilize the pointer packing, you must have two types: a pointer, +//! and a tag. +//! +//! The pointer must implement the `Pointer` trait, with the primary requirement +//! being conversion to and from a usize. Note that the pointer must be +//! dereferenceable, so raw pointers generally cannot implement the `Pointer` +//! trait. This implies that the pointer must also be nonzero. +//! +//! Many common pointer types already implement the `Pointer` trait. +//! +//! The tag must implement the `Tag` trait. We assert that the tag and `Pointer` +//! are compatible at compile time. + +use std::mem::ManuallyDrop; +use std::ops::Deref; +use std::rc::Rc; +use std::sync::Arc; + +mod copy; +mod drop; + +pub use copy::CopyTaggedPtr; +pub use drop::TaggedPtr; + +/// This describes the pointer type encaspulated by TaggedPtr. +/// +/// # Safety +/// +/// The usize returned from `into_usize` must be a valid, dereferenceable, +/// pointer to `::Target`. Note that pointers to `Pointee` must +/// be thin, even though `Pointee` may not be sized. +/// +/// Note that the returned pointer from `into_usize` should be castable to `&mut +/// ::Target` if `Pointer: DerefMut`. +/// +/// The BITS constant must be correct. At least `BITS` bits, least-significant, +/// must be zero on all returned pointers from `into_usize`. +/// +/// For example, if the alignment of `Pointee` is 2, then `BITS` should be 1. +pub unsafe trait Pointer: Deref { + /// Most likely the value you want to use here is the following, unless + /// your Pointee type is unsized (e.g., `ty::List` in rustc) in which + /// case you'll need to manually figure out what the right type to pass to + /// align_of is. + /// + /// ```rust + /// std::mem::align_of::<::Target>().trailing_zeros() as usize; + /// ``` + const BITS: usize; + fn into_usize(self) -> usize; + + /// # Safety + /// + /// The passed `ptr` must be returned from `into_usize`. + /// + /// This acts as `ptr::read` semantically, it should not be called more than + /// once on non-`Copy` `Pointer`s. + unsafe fn from_usize(ptr: usize) -> Self; + + /// This provides a reference to the `Pointer` itself, rather than the + /// `Deref::Target`. It is used for cases where we want to call methods that + /// may be implement differently for the Pointer than the Pointee (e.g., + /// `Rc::clone` vs cloning the inner value). + /// + /// # Safety + /// + /// The passed `ptr` must be returned from `into_usize`. + unsafe fn with_ref R>(ptr: usize, f: F) -> R; +} + +/// This describes tags that the `TaggedPtr` struct can hold. +/// +/// # Safety +/// +/// The BITS constant must be correct. +/// +/// No more than `BITS` least significant bits may be set in the returned usize. +pub unsafe trait Tag: Copy { + const BITS: usize; + + fn into_usize(self) -> usize; + + /// # Safety + /// + /// The passed `tag` must be returned from `into_usize`. + unsafe fn from_usize(tag: usize) -> Self; +} + +unsafe impl Pointer for Box { + const BITS: usize = std::mem::align_of::().trailing_zeros() as usize; + fn into_usize(self) -> usize { + Box::into_raw(self) as usize + } + unsafe fn from_usize(ptr: usize) -> Self { + Box::from_raw(ptr as *mut T) + } + unsafe fn with_ref R>(ptr: usize, f: F) -> R { + let raw = ManuallyDrop::new(Self::from_usize(ptr)); + f(&raw) + } +} + +unsafe impl Pointer for Rc { + const BITS: usize = std::mem::align_of::().trailing_zeros() as usize; + fn into_usize(self) -> usize { + Rc::into_raw(self) as usize + } + unsafe fn from_usize(ptr: usize) -> Self { + Rc::from_raw(ptr as *const T) + } + unsafe fn with_ref R>(ptr: usize, f: F) -> R { + let raw = ManuallyDrop::new(Self::from_usize(ptr)); + f(&raw) + } +} + +unsafe impl Pointer for Arc { + const BITS: usize = std::mem::align_of::().trailing_zeros() as usize; + fn into_usize(self) -> usize { + Arc::into_raw(self) as usize + } + unsafe fn from_usize(ptr: usize) -> Self { + Arc::from_raw(ptr as *const T) + } + unsafe fn with_ref R>(ptr: usize, f: F) -> R { + let raw = ManuallyDrop::new(Self::from_usize(ptr)); + f(&raw) + } +} + +unsafe impl<'a, T: 'a> Pointer for &'a T { + const BITS: usize = std::mem::align_of::().trailing_zeros() as usize; + fn into_usize(self) -> usize { + self as *const T as usize + } + unsafe fn from_usize(ptr: usize) -> Self { + &*(ptr as *const T) + } + unsafe fn with_ref R>(ptr: usize, f: F) -> R { + f(&*(&ptr as *const usize as *const Self)) + } +} + +unsafe impl<'a, T: 'a> Pointer for &'a mut T { + const BITS: usize = std::mem::align_of::().trailing_zeros() as usize; + fn into_usize(self) -> usize { + self as *mut T as usize + } + unsafe fn from_usize(ptr: usize) -> Self { + &mut *(ptr as *mut T) + } + unsafe fn with_ref R>(ptr: usize, f: F) -> R { + f(&*(&ptr as *const usize as *const Self)) + } +} diff --git a/src/librustc_data_structures/tagged_ptr/copy.rs b/src/librustc_data_structures/tagged_ptr/copy.rs new file mode 100644 index 0000000000000..d39d146db318f --- /dev/null +++ b/src/librustc_data_structures/tagged_ptr/copy.rs @@ -0,0 +1,183 @@ +use super::{Pointer, Tag}; +use crate::stable_hasher::{HashStable, StableHasher}; +use std::fmt; +use std::marker::PhantomData; +use std::num::NonZeroUsize; + +/// A `Copy` TaggedPtr. +/// +/// You should use this instead of the `TaggedPtr` type in all cases where +/// `P: Copy`. +/// +/// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without +/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that, +/// wrap the TaggedPtr. +pub struct CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ + packed: NonZeroUsize, + data: PhantomData<(P, T)>, +} + +impl Copy for CopyTaggedPtr +where + P: Pointer, + T: Tag, + P: Copy, +{ +} + +impl Clone for CopyTaggedPtr +where + P: Pointer, + T: Tag, + P: Copy, +{ + fn clone(&self) -> Self { + *self + } +} + +// We pack the tag into the *upper* bits of the pointer to ease retrieval of the +// value; a left shift is a multiplication and those are embeddable in +// instruction encoding. +impl CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ + const TAG_BIT_SHIFT: usize = (8 * std::mem::size_of::()) - T::BITS; + const ASSERTION: () = { + assert!(T::BITS <= P::BITS); + // Used for the transmute_copy's below + assert!(std::mem::size_of::<&P::Target>() == std::mem::size_of::()); + }; + + pub fn new(pointer: P, tag: T) -> Self { + // Trigger assert! + let () = Self::ASSERTION; + let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT; + + Self { + // SAFETY: We know that the pointer is non-null, as it must be + // dereferenceable per `Pointer` safety contract. + packed: unsafe { + NonZeroUsize::new_unchecked((P::into_usize(pointer) >> T::BITS) | packed_tag) + }, + data: PhantomData, + } + } + + pub(super) fn pointer_raw(&self) -> usize { + self.packed.get() << T::BITS + } + pub fn pointer(self) -> P + where + P: Copy, + { + // SAFETY: pointer_raw returns the original pointer + // + // Note that this isn't going to double-drop or anything because we have + // P: Copy + unsafe { P::from_usize(self.pointer_raw()) } + } + pub fn pointer_ref(&self) -> &P::Target { + // SAFETY: pointer_raw returns the original pointer + unsafe { std::mem::transmute_copy(&self.pointer_raw()) } + } + pub fn pointer_mut(&mut self) -> &mut P::Target + where + P: std::ops::DerefMut, + { + // SAFETY: pointer_raw returns the original pointer + unsafe { std::mem::transmute_copy(&self.pointer_raw()) } + } + pub fn tag(&self) -> T { + unsafe { T::from_usize(self.packed.get() >> Self::TAG_BIT_SHIFT) } + } + pub fn set_tag(&mut self, tag: T) { + let mut packed = self.packed.get(); + let new_tag = T::into_usize(tag) << Self::TAG_BIT_SHIFT; + let tag_mask = (1 << T::BITS) - 1; + packed &= !(tag_mask << Self::TAG_BIT_SHIFT); + packed |= new_tag; + self.packed = unsafe { NonZeroUsize::new_unchecked(packed) }; + } +} + +impl std::ops::Deref for CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ + type Target = P::Target; + fn deref(&self) -> &Self::Target { + self.pointer_ref() + } +} + +impl std::ops::DerefMut for CopyTaggedPtr +where + P: Pointer + std::ops::DerefMut, + T: Tag, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + self.pointer_mut() + } +} + +impl fmt::Debug for CopyTaggedPtr +where + P: Pointer, + P::Target: fmt::Debug, + T: Tag + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CopyTaggedPtr") + .field("pointer", &self.pointer_ref()) + .field("tag", &self.tag()) + .finish() + } +} + +impl PartialEq for CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ + fn eq(&self, other: &Self) -> bool { + self.packed == other.packed + } +} + +impl Eq for CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ +} + +impl std::hash::Hash for CopyTaggedPtr +where + P: Pointer, + T: Tag, +{ + fn hash(&self, state: &mut H) { + self.packed.hash(state); + } +} + +impl HashStable for CopyTaggedPtr +where + P: Pointer + HashStable, + T: Tag + HashStable, +{ + fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + unsafe { + Pointer::with_ref(self.pointer_raw(), |p: &P| p.hash_stable(hcx, hasher)); + } + self.tag().hash_stable(hcx, hasher); + } +} diff --git a/src/librustc_data_structures/tagged_ptr/drop.rs b/src/librustc_data_structures/tagged_ptr/drop.rs new file mode 100644 index 0000000000000..63f64beae5a07 --- /dev/null +++ b/src/librustc_data_structures/tagged_ptr/drop.rs @@ -0,0 +1,142 @@ +use super::{Pointer, Tag}; +use crate::stable_hasher::{HashStable, StableHasher}; +use std::fmt; + +use super::CopyTaggedPtr; + +/// A TaggedPtr implementing `Drop`. +/// +/// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without +/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that, +/// wrap the TaggedPtr. +pub struct TaggedPtr +where + P: Pointer, + T: Tag, +{ + raw: CopyTaggedPtr, +} + +impl Clone for TaggedPtr +where + P: Pointer + Clone, + T: Tag, +{ + fn clone(&self) -> Self { + unsafe { Self::new(P::with_ref(self.raw.pointer_raw(), |p| p.clone()), self.raw.tag()) } + } +} + +// We pack the tag into the *upper* bits of the pointer to ease retrieval of the +// value; a right shift is a multiplication and those are embeddable in +// instruction encoding. +impl TaggedPtr +where + P: Pointer, + T: Tag, +{ + pub fn new(pointer: P, tag: T) -> Self { + TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) } + } + + pub fn pointer_ref(&self) -> &P::Target { + self.raw.pointer_ref() + } + pub fn pointer_mut(&mut self) -> &mut P::Target + where + P: std::ops::DerefMut, + { + self.raw.pointer_mut() + } + pub fn tag(&self) -> T { + self.raw.tag() + } + pub fn set_tag(&mut self, tag: T) { + self.raw.set_tag(tag); + } +} + +impl std::ops::Deref for TaggedPtr +where + P: Pointer, + T: Tag, +{ + type Target = P::Target; + fn deref(&self) -> &Self::Target { + self.raw.pointer_ref() + } +} + +impl std::ops::DerefMut for TaggedPtr +where + P: Pointer + std::ops::DerefMut, + T: Tag, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + self.raw.pointer_mut() + } +} + +impl Drop for TaggedPtr +where + P: Pointer, + T: Tag, +{ + fn drop(&mut self) { + // No need to drop the tag, as it's Copy + unsafe { + std::mem::drop(P::from_usize(self.raw.pointer_raw())); + } + } +} + +impl fmt::Debug for TaggedPtr +where + P: Pointer, + P::Target: fmt::Debug, + T: Tag + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TaggedPtr") + .field("pointer", &self.pointer_ref()) + .field("tag", &self.tag()) + .finish() + } +} + +impl PartialEq for TaggedPtr +where + P: Pointer, + T: Tag, +{ + fn eq(&self, other: &Self) -> bool { + self.raw.eq(&other.raw) + } +} + +impl Eq for TaggedPtr +where + P: Pointer, + T: Tag, +{ +} + +impl std::hash::Hash for TaggedPtr +where + P: Pointer, + T: Tag, +{ + fn hash(&self, state: &mut H) { + self.raw.hash(state); + } +} + +impl HashStable for TaggedPtr +where + P: Pointer + HashStable, + T: Tag + HashStable, +{ + fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + self.raw.hash_stable(hcx, hasher); + } +} diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 36eb272cdfc8d..b337bf0a3f922 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -29,6 +29,7 @@ use rustc_ast::visit::{FnCtxt, FnKind}; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType}; use rustc_feature::{GateIssue, Stability}; @@ -2153,44 +2154,58 @@ impl ClashingExternDeclarations { b: Ty<'tcx>, ckind: CItemKind, ) -> bool { - debug!("structurally_same_type(cx, a = {:?}, b = {:?})", a, b); - let tcx = cx.tcx; - if a == b || rustc_middle::ty::TyS::same_type(a, b) { - // All nominally-same types are structurally same, too. - true - } else { - // Do a full, depth-first comparison between the two. - use rustc_middle::ty::TyKind::*; - let a_kind = &a.kind; - let b_kind = &b.kind; - - let compare_layouts = |a, b| -> bool { - let a_layout = &cx.layout_of(a).unwrap().layout.abi; - let b_layout = &cx.layout_of(b).unwrap().layout.abi; - debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout); - a_layout == b_layout - }; + fn structurally_same_type_impl<'tcx>( + seen_types: &mut FxHashSet<(Ty<'tcx>, Ty<'tcx>)>, + cx: &LateContext<'tcx>, + a: Ty<'tcx>, + b: Ty<'tcx>, + ckind: CItemKind, + ) -> bool { + debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b); + if !seen_types.insert((a, b)) { + // We've encountered a cycle. There's no point going any further -- the types are + // structurally the same. + return true; + } + let tcx = cx.tcx; + if a == b || rustc_middle::ty::TyS::same_type(a, b) { + // All nominally-same types are structurally same, too. + true + } else { + // Do a full, depth-first comparison between the two. + use rustc_middle::ty::TyKind::*; + let a_kind = &a.kind; + let b_kind = &b.kind; + + let compare_layouts = |a, b| -> bool { + let a_layout = &cx.layout_of(a).unwrap().layout.abi; + let b_layout = &cx.layout_of(b).unwrap().layout.abi; + debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout); + a_layout == b_layout + }; + + #[allow(rustc::usage_of_ty_tykind)] + let is_primitive_or_pointer = |kind: &ty::TyKind<'_>| { + kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..)) + }; - #[allow(rustc::usage_of_ty_tykind)] - let is_primitive_or_pointer = - |kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..)); - - match (a_kind, b_kind) { - (Adt(_, a_substs), Adt(_, b_substs)) => { - let a = a.subst(cx.tcx, a_substs); - let b = b.subst(cx.tcx, b_substs); - debug!("Comparing {:?} and {:?}", a, b); - - if let (Adt(a_def, ..), Adt(b_def, ..)) = (&a.kind, &b.kind) { - // Grab a flattened representation of all fields. - let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter()); - let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter()); - compare_layouts(a, b) + ensure_sufficient_stack(|| { + match (a_kind, b_kind) { + (Adt(a_def, a_substs), Adt(b_def, b_substs)) => { + let a = a.subst(cx.tcx, a_substs); + let b = b.subst(cx.tcx, b_substs); + debug!("Comparing {:?} and {:?}", a, b); + + // Grab a flattened representation of all fields. + let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter()); + let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter()); + compare_layouts(a, b) && a_fields.eq_by( b_fields, |&ty::FieldDef { did: a_did, .. }, &ty::FieldDef { did: b_did, .. }| { - Self::structurally_same_type( + structurally_same_type_impl( + seen_types, cx, tcx.type_of(a_did), tcx.type_of(b_did), @@ -2198,78 +2213,93 @@ impl ClashingExternDeclarations { ) }, ) - } else { - unreachable!() - } - } - (Array(a_ty, a_const), Array(b_ty, b_const)) => { - // For arrays, we also check the constness of the type. - a_const.val == b_const.val - && Self::structurally_same_type(cx, a_const.ty, b_const.ty, ckind) - && Self::structurally_same_type(cx, a_ty, b_ty, ckind) - } - (Slice(a_ty), Slice(b_ty)) => Self::structurally_same_type(cx, a_ty, b_ty, ckind), - (RawPtr(a_tymut), RawPtr(b_tymut)) => { - a_tymut.mutbl == b_tymut.mutbl - && Self::structurally_same_type(cx, &a_tymut.ty, &b_tymut.ty, ckind) - } - (Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => { - // For structural sameness, we don't need the region to be same. - a_mut == b_mut && Self::structurally_same_type(cx, a_ty, b_ty, ckind) - } - (FnDef(..), FnDef(..)) => { - let a_poly_sig = a.fn_sig(tcx); - let b_poly_sig = b.fn_sig(tcx); - - // As we don't compare regions, skip_binder is fine. - let a_sig = a_poly_sig.skip_binder(); - let b_sig = b_poly_sig.skip_binder(); - - (a_sig.abi, a_sig.unsafety, a_sig.c_variadic) - == (b_sig.abi, b_sig.unsafety, b_sig.c_variadic) - && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| { - Self::structurally_same_type(cx, a, b, ckind) - }) - && Self::structurally_same_type(cx, a_sig.output(), b_sig.output(), ckind) - } - (Tuple(a_substs), Tuple(b_substs)) => { - a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| { - Self::structurally_same_type(cx, a_ty, b_ty, ckind) - }) - } - // For these, it's not quite as easy to define structural-sameness quite so easily. - // For the purposes of this lint, take the conservative approach and mark them as - // not structurally same. - (Dynamic(..), Dynamic(..)) - | (Error(..), Error(..)) - | (Closure(..), Closure(..)) - | (Generator(..), Generator(..)) - | (GeneratorWitness(..), GeneratorWitness(..)) - | (Projection(..), Projection(..)) - | (Opaque(..), Opaque(..)) => false, - - // These definitely should have been caught above. - (Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(), - - // An Adt and a primitive type. This can be FFI-safe is the ADT is an enum with a - // non-null field. - (Adt(..), other_kind) | (other_kind, Adt(..)) - if is_primitive_or_pointer(other_kind) => - { - let (primitive, adt) = - if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) }; - if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) { - ty == primitive - } else { - compare_layouts(a, b) + } + (Array(a_ty, a_const), Array(b_ty, b_const)) => { + // For arrays, we also check the constness of the type. + a_const.val == b_const.val + && structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind) + } + (Slice(a_ty), Slice(b_ty)) => { + structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind) + } + (RawPtr(a_tymut), RawPtr(b_tymut)) => { + a_tymut.mutbl == b_tymut.mutbl + && structurally_same_type_impl( + seen_types, + cx, + &a_tymut.ty, + &b_tymut.ty, + ckind, + ) + } + (Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => { + // For structural sameness, we don't need the region to be same. + a_mut == b_mut + && structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind) + } + (FnDef(..), FnDef(..)) => { + let a_poly_sig = a.fn_sig(tcx); + let b_poly_sig = b.fn_sig(tcx); + + // As we don't compare regions, skip_binder is fine. + let a_sig = a_poly_sig.skip_binder(); + let b_sig = b_poly_sig.skip_binder(); + + (a_sig.abi, a_sig.unsafety, a_sig.c_variadic) + == (b_sig.abi, b_sig.unsafety, b_sig.c_variadic) + && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| { + structurally_same_type_impl(seen_types, cx, a, b, ckind) + }) + && structurally_same_type_impl( + seen_types, + cx, + a_sig.output(), + b_sig.output(), + ckind, + ) + } + (Tuple(a_substs), Tuple(b_substs)) => { + a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| { + structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind) + }) + } + // For these, it's not quite as easy to define structural-sameness quite so easily. + // For the purposes of this lint, take the conservative approach and mark them as + // not structurally same. + (Dynamic(..), Dynamic(..)) + | (Error(..), Error(..)) + | (Closure(..), Closure(..)) + | (Generator(..), Generator(..)) + | (GeneratorWitness(..), GeneratorWitness(..)) + | (Projection(..), Projection(..)) + | (Opaque(..), Opaque(..)) => false, + + // These definitely should have been caught above. + (Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(), + + // An Adt and a primitive or pointer type. This can be FFI-safe if non-null + // enum layout optimisation is being applied. + (Adt(..), other_kind) | (other_kind, Adt(..)) + if is_primitive_or_pointer(other_kind) => + { + let (primitive, adt) = + if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) }; + if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) { + ty == primitive + } else { + compare_layouts(a, b) + } + } + // Otherwise, just compare the layouts. This may fail to lint for some + // incompatible types, but at the very least, will stop reads into + // uninitialised memory. + _ => compare_layouts(a, b), } - } - // Otherwise, just compare the layouts. This may fail to lint for some - // incompatible types, but at the very least, will stop reads into - // uninitialised memory. - _ => compare_layouts(a, b), + }) } } + let mut seen_types = FxHashSet::default(); + structurally_same_type_impl(&mut seen_types, cx, a, b, ckind) } } diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 1faed87f8ff17..53e2c3cca0023 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -1531,7 +1531,7 @@ pub enum ProjectionElem { /// ``` ConstantIndex { /// index or -index (in Python terms), depending on from_end - offset: u32, + offset: u64, /// The thing being indexed must be at least this long. For arrays this /// is always the exact length. min_length: u32, @@ -1545,8 +1545,8 @@ pub enum ProjectionElem { /// If `from_end` is true `slice[from..slice.len() - to]`. /// Otherwise `array[from..to]`. Subslice { - from: u32, - to: u32, + from: u64, + to: u64, /// Whether `to` counts from the start or end of the array/slice. /// For `PlaceElem`s this is `true` if and only if the base is a slice. /// For `ProjectionKind`, this can also be `true` for arrays. @@ -1583,7 +1583,7 @@ pub type PlaceElem<'tcx> = ProjectionElem>; // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers. #[cfg(target_arch = "x86_64")] -static_assert_size!(PlaceElem<'_>, 16); +static_assert_size!(PlaceElem<'_>, 24); /// Alias for projections as they appear in `UserTypeProjection`, where we /// need neither the `V` parameter for `Index` nor the `T` for `Field`. @@ -2297,7 +2297,7 @@ impl<'tcx> UserTypeProjections { self.map_projections(|pat_ty_proj| pat_ty_proj.index()) } - pub fn subslice(self, from: u32, to: u32) -> Self { + pub fn subslice(self, from: u64, to: u64) -> Self { self.map_projections(|pat_ty_proj| pat_ty_proj.subslice(from, to)) } @@ -2343,7 +2343,7 @@ impl UserTypeProjection { self } - pub(crate) fn subslice(mut self, from: u32, to: u32) -> Self { + pub(crate) fn subslice(mut self, from: u64, to: u64) -> Self { self.projs.push(ProjectionElem::Subslice { from, to, from_end: true }); self } diff --git a/src/librustc_middle/ty/list.rs b/src/librustc_middle/ty/list.rs index fe390adf89f9f..83a2bdf90f9af 100644 --- a/src/librustc_middle/ty/list.rs +++ b/src/librustc_middle/ty/list.rs @@ -35,6 +35,21 @@ pub struct List { opaque: OpaqueListContents, } +unsafe impl<'a, T: 'a> rustc_data_structures::tagged_ptr::Pointer for &'a List { + const BITS: usize = std::mem::align_of::().trailing_zeros() as usize; + fn into_usize(self) -> usize { + self as *const List as usize + } + unsafe fn from_usize(ptr: usize) -> Self { + &*(ptr as *const List) + } + unsafe fn with_ref R>(ptr: usize, f: F) -> R { + // Self: Copy so this is fine + let ptr = Self::from_usize(ptr); + f(&ptr) + } +} + unsafe impl Sync for List {} impl List { diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 02fd18ef968c5..4fa86a91254ce 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{self, par_iter, ParallelIterator}; +use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res}; @@ -46,7 +47,6 @@ use std::cell::RefCell; use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; use std::ops::Range; use std::ptr; use std::str; @@ -1713,34 +1713,21 @@ impl WithOptConstParam { /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] pub struct ParamEnv<'tcx> { - // We pack the caller_bounds List pointer and a Reveal enum into this usize. - // Specifically, the low bit represents Reveal, with 0 meaning `UserFacing` - // and 1 meaning `All`. The rest is the pointer. - // - // This relies on the List> type having at least 2-byte - // alignment. Lists start with a usize and are repr(C) so this should be - // fine; there is a debug_assert in the constructor as well. - // - // Note that the choice of 0 for UserFacing is intentional -- since it is the - // first variant in Reveal this means that joining the pointer is a simple `or`. - packed_data: usize, - - /// `Obligation`s that the caller must satisfy. This is basically - /// the set of bounds on the in-scope type parameters, translated + /// This packs both caller bounds and the reveal enum into one pointer. + /// + /// Caller bounds are `Obligation`s that the caller must satisfy. This is + /// basically the set of bounds on the in-scope type parameters, translated /// into `Obligation`s, and elaborated and normalized. /// - /// Note: This is packed into the `packed_data` usize above, use the - /// `caller_bounds()` method to access it. - caller_bounds: PhantomData<&'tcx List>>, - + /// Use the `caller_bounds()` method to access. + /// /// Typically, this is `Reveal::UserFacing`, but during codegen we /// want `Reveal::All`. /// - /// Note: This is packed into the caller_bounds usize above, use the reveal() - /// method to access it. - reveal: PhantomData, + /// Note: This is packed, use the reveal() method to access it. + packed: CopyTaggedPtr<&'tcx List>, traits::Reveal, true>, /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`, /// register that `def_id` (useful for transitioning to the chalk trait @@ -1748,6 +1735,23 @@ pub struct ParamEnv<'tcx> { pub def_id: Option, } +unsafe impl rustc_data_structures::tagged_ptr::Tag for traits::Reveal { + const BITS: usize = 1; + fn into_usize(self) -> usize { + match self { + traits::Reveal::UserFacing => 0, + traits::Reveal::All => 1, + } + } + unsafe fn from_usize(ptr: usize) -> Self { + match ptr { + 0 => traits::Reveal::UserFacing, + 1 => traits::Reveal::All, + _ => std::hint::unreachable_unchecked(), + } + } +} + impl<'tcx> fmt::Debug for ParamEnv<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ParamEnv") @@ -1758,24 +1762,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> { } } -impl<'tcx> Hash for ParamEnv<'tcx> { - fn hash(&self, state: &mut H) { - // List hashes as the raw pointer, so we can skip splitting into the - // pointer and the enum. - self.packed_data.hash(state); - self.def_id.hash(state); - } -} - -impl<'tcx> PartialEq for ParamEnv<'tcx> { - fn eq(&self, other: &Self) -> bool { - self.caller_bounds() == other.caller_bounds() - && self.reveal() == other.reveal() - && self.def_id == other.def_id - } -} -impl<'tcx> Eq for ParamEnv<'tcx> {} - impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.caller_bounds().hash_stable(hcx, hasher); @@ -1812,13 +1798,12 @@ impl<'tcx> ParamEnv<'tcx> { #[inline] pub fn caller_bounds(self) -> &'tcx List> { - // mask out bottom bit - unsafe { &*((self.packed_data & (!1)) as *const _) } + self.packed.pointer() } #[inline] pub fn reveal(self) -> traits::Reveal { - if self.packed_data & 1 == 0 { traits::Reveal::UserFacing } else { traits::Reveal::All } + self.packed.tag() } /// Construct a trait environment with no where-clauses in scope @@ -1840,24 +1825,11 @@ impl<'tcx> ParamEnv<'tcx> { reveal: Reveal, def_id: Option, ) -> Self { - let packed_data = caller_bounds as *const _ as usize; - // Check that we can pack the reveal data into the pointer. - debug_assert!(packed_data & 1 == 0); - ty::ParamEnv { - packed_data: packed_data - | match reveal { - Reveal::UserFacing => 0, - Reveal::All => 1, - }, - caller_bounds: PhantomData, - reveal: PhantomData, - def_id, - } + ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, reveal), def_id } } pub fn with_user_facing(mut self) -> Self { - // clear bottom bit - self.packed_data &= !1; + self.packed.set_tag(Reveal::UserFacing); self } @@ -1871,7 +1843,7 @@ impl<'tcx> ParamEnv<'tcx> { /// will be normalized to their underlying types. /// See PR #65989 and issue #65918 for more details pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self { - if self.packed_data & 1 == 1 { + if self.packed.tag() == traits::Reveal::All { return self; } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index f7031b2a59848..9d13ce9355279 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1693,8 +1693,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), maybe_uninits: &BitSet, - from: u32, - to: u32, + from: u64, + to: u64, ) { if let Some(mpi) = self.move_path_for_place(place_span.0) { let move_paths = &self.move_data.move_paths; diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index ff98de5475ecf..b341098796223 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -649,7 +649,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { PlaceTy::from_ty(match base_ty.kind { ty::Array(inner, _) => { assert!(!from_end, "array subslices should not use from_end"); - tcx.mk_array(inner, (to - from) as u64) + tcx.mk_array(inner, (to - from)) } ty::Slice(..) => { assert!(from_end, "slice subslices should use from_end"); diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index ad49090bfc50c..f4d1f3820bced 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -1,10 +1,10 @@ use crate::dataflow; -use crate::dataflow::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use crate::dataflow::on_lookup_result_bits; use crate::dataflow::MoveDataParamEnv; use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits}; use crate::dataflow::{Analysis, ResultsCursor}; +use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::transform::{MirPass, MirSource}; use crate::util::elaborate_drops::{elaborate_drop, DropFlagState, Unwind}; use crate::util::elaborate_drops::{DropElaborator, DropFlagMode, DropStyle}; @@ -48,7 +48,6 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { .into_results_cursor(body); let uninits = MaybeUninitializedPlaces::new(tcx, body, &env) - .mark_inactive_variants_as_uninit() .into_engine(tcx, body, def_id) .dead_unwinds(&dead_unwinds) .iterate_to_fixpoint() @@ -86,15 +85,15 @@ fn find_dead_unwinds<'tcx>( .iterate_to_fixpoint() .into_results_cursor(body); for (bb, bb_data) in body.basic_blocks().iter_enumerated() { - let place = match bb_data.terminator().kind { - TerminatorKind::Drop { ref place, unwind: Some(_), .. } - | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => place, + let location = match bb_data.terminator().kind { + TerminatorKind::Drop { ref location, unwind: Some(_), .. } + | TerminatorKind::DropAndReplace { ref location, unwind: Some(_), .. } => location, _ => continue, }; debug!("find_dead_unwinds @ {:?}: {:?}", bb, bb_data); - let path = match env.move_data.rev_lookup.find(place.as_ref()) { + let path = match env.move_data.rev_lookup.find(location.as_ref()) { LookupResult::Exact(e) => e, LookupResult::Parent(..) => { debug!("find_dead_unwinds: has parent; skipping"); @@ -102,11 +101,11 @@ fn find_dead_unwinds<'tcx>( } }; - flow_inits.seek_before_primary_effect(body.terminator_loc(bb)); + flow_inits.seek_before(body.terminator_loc(bb)); debug!( "find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}", bb, - place, + location, path, flow_inits.get() ); @@ -132,8 +131,8 @@ struct InitializationData<'mir, 'tcx> { impl InitializationData<'_, '_> { fn seek_before(&mut self, loc: Location) { - self.inits.seek_before_primary_effect(loc); - self.uninits.seek_before_primary_effect(loc); + self.inits.seek_before(loc); + self.uninits.seek_before(loc); } fn maybe_live_dead(&self, path: MovePathIndex) -> (bool, bool) { @@ -214,17 +213,17 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { fn field_subpath(&self, path: Self::Path, field: Field) -> Option { dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { - ProjectionElem::Field(idx, _) => idx == field, + ProjectionElem::Field(idx, _) => *idx == field, _ => false, }) } - fn array_subpath(&self, path: Self::Path, index: u32, size: u32) -> Option { + fn array_subpath(&self, path: Self::Path, index: u64, size: u64) -> Option { dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { ProjectionElem::ConstantIndex { offset, min_length, from_end } => { - debug_assert!(size == min_length, "min_length should be exact for arrays"); + debug_assert!(size == *min_length as u64, "min_length should be exact for arrays"); assert!(!from_end, "from_end should not be used for array element ConstantIndex"); - offset == index + *offset == index } _ => false, }) @@ -232,13 +231,13 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { fn deref_subpath(&self, path: Self::Path) -> Option { dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| { - e == ProjectionElem::Deref + *e == ProjectionElem::Deref }) } fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option { dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { - ProjectionElem::Downcast(_, idx) => idx == variant, + ProjectionElem::Downcast(_, idx) => *idx == variant, _ => false, }) } @@ -295,16 +294,16 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn collect_drop_flags(&mut self) { for (bb, data) in self.body.basic_blocks().iter_enumerated() { let terminator = data.terminator(); - let place = match terminator.kind { - TerminatorKind::Drop { ref place, .. } - | TerminatorKind::DropAndReplace { ref place, .. } => place, + let location = match terminator.kind { + TerminatorKind::Drop { ref location, .. } + | TerminatorKind::DropAndReplace { ref location, .. } => location, _ => continue, }; self.init_data.seek_before(self.body.terminator_loc(bb)); - let path = self.move_data().rev_lookup.find(place.as_ref()); - debug!("collect_drop_flags: {:?}, place {:?} ({:?})", bb, place, path); + let path = self.move_data().rev_lookup.find(location.as_ref()); + debug!("collect_drop_flags: {:?}, place {:?} ({:?})", bb, location, path); let path = match path { LookupResult::Exact(e) => e, @@ -316,7 +315,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { terminator.source_info.span, "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", bb, - place, + location, path ); } @@ -329,7 +328,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { debug!( "collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}", child, - place, + location, path, (maybe_live, maybe_dead) ); @@ -347,13 +346,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let resume_block = self.patch.resume_block(); match terminator.kind { - TerminatorKind::Drop { place, target, unwind } => { + TerminatorKind::Drop { location, target, unwind } => { self.init_data.seek_before(loc); - match self.move_data().rev_lookup.find(place.as_ref()) { + match self.move_data().rev_lookup.find(location.as_ref()) { LookupResult::Exact(path) => elaborate_drop( &mut Elaborator { ctxt: self }, terminator.source_info, - place, + location, path, target, if data.is_cleanup { @@ -372,10 +371,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } } } - TerminatorKind::DropAndReplace { place, ref value, target, unwind } => { + TerminatorKind::DropAndReplace { location, ref value, target, unwind } => { assert!(!data.is_cleanup); - self.elaborate_replace(loc, place, value, target, unwind); + self.elaborate_replace(loc, location, value, target, unwind); } _ => continue, } @@ -397,7 +396,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn elaborate_replace( &mut self, loc: Location, - place: Place<'tcx>, + location: Place<'tcx>, value: &Operand<'tcx>, target: BasicBlock, unwind: Option, @@ -408,7 +407,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported"); let assign = Statement { - kind: StatementKind::Assign(box (place, Rvalue::Use(value.clone()))), + kind: StatementKind::Assign(box (location, Rvalue::Use(value.clone()))), source_info: terminator.source_info, }; @@ -428,14 +427,14 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { is_cleanup: false, }); - match self.move_data().rev_lookup.find(place.as_ref()) { + match self.move_data().rev_lookup.find(location.as_ref()) { LookupResult::Exact(path) => { debug!("elaborate_drop_and_replace({:?}) - tracked {:?}", terminator, path); self.init_data.seek_before(loc); elaborate_drop( &mut Elaborator { ctxt: self }, terminator.source_info, - place, + location, path, target, Unwind::To(unwind), @@ -460,7 +459,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { debug!("elaborate_drop_and_replace({:?}) - untracked {:?}", terminator, parent); self.patch.patch_terminator( bb, - TerminatorKind::Drop { place, target, unwind: Some(unwind) }, + TerminatorKind::Drop { location, target, unwind: Some(unwind) }, ); } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 4f26f3bb45973..1c1c54434d619 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -321,6 +321,7 @@ fn mir_validated( // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. + // Also this means promotion can rely on all const checks having been done. let _ = tcx.mir_const_qualif_opt_const_arg(def); let mut body = tcx.mir_const(def).steal(); @@ -336,7 +337,7 @@ fn mir_validated( let promote: &[&dyn MirPass<'tcx>] = &[ // What we need to run borrowck etc. &promote_pass, - &simplify::SimplifyCfg::new("qualify-consts"), + &simplify::SimplifyCfg::new("promote-consts"), ]; let opt_coverage: &[&dyn MirPass<'tcx>] = if tcx.sess.opts.debugging_opts.instrument_coverage { diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index 1a22eee3a0371..e867e8b40850f 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -52,14 +52,12 @@ pub fn expand_aggregate<'tcx>( .enumerate() .map(move |(i, (op, ty))| { let lhs_field = if let AggregateKind::Array(_) = kind { - // FIXME(eddyb) `offset` should be u64. - let offset = i as u32; + let offset = i as u64; assert_eq!(offset as usize, i); tcx.mk_place_elem( lhs, ProjectionElem::ConstantIndex { offset, - // FIXME(eddyb) `min_length` doesn't appear to be used. min_length: offset + 1, from_end: false, }, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 20c2f5688eb59..fa5f9a98be2ad 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -1,6 +1,6 @@ use crate::util::patch::MirPatch; use rustc_hir as hir; -use rustc_hir::lang_items::{BoxFreeFnLangItem, DropTraitLangItem}; +use rustc_hir::lang_items; use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::traits::Reveal; @@ -12,15 +12,10 @@ use std::fmt; use std::convert::TryInto; -/// The value of an inserted drop flag. #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum DropFlagState { - /// The tracked value is initialized and needs to be dropped when leaving its scope. - Present, - - /// The tracked value is uninitialized or was moved out of and does not need to be dropped when - /// leaving its scope. - Absent, + Present, // i.e., initialized + Absent, // i.e., deinitialized or "moved" } impl DropFlagState { @@ -32,42 +27,23 @@ impl DropFlagState { } } -/// Describes how/if a value should be dropped. #[derive(Debug)] pub enum DropStyle { - /// The value is already dead at the drop location, no drop will be executed. Dead, - - /// The value is known to always be initialized at the drop location, drop will always be - /// executed. Static, - - /// Whether the value needs to be dropped depends on its drop flag. Conditional, - - /// An "open" drop is one where only the fields of a value are dropped. - /// - /// For example, this happens when moving out of a struct field: The rest of the struct will be - /// dropped in such an "open" drop. It is also used to generate drop glue for the individual - /// components of a value, for example for dropping array elements. Open, } -/// Which drop flags to affect/check with an operation. #[derive(Debug)] pub enum DropFlagMode { - /// Only affect the top-level drop flag, not that of any contained fields. Shallow, - /// Affect all nested drop flags in addition to the top-level one. Deep, } -/// Describes if unwinding is necessary and where to unwind to if a panic occurs. #[derive(Copy, Clone, Debug)] pub enum Unwind { - /// Unwind to this block. To(BasicBlock), - /// Already in an unwind path, any panic will cause an abort. InCleanup, } @@ -98,59 +74,21 @@ impl Unwind { } pub trait DropElaborator<'a, 'tcx>: fmt::Debug { - /// The type representing paths that can be moved out of. - /// - /// Users can move out of individual fields of a struct, such as `a.b.c`. This type is used to - /// represent such move paths. Sometimes tracking individual move paths is not necessary, in - /// which case this may be set to (for example) `()`. type Path: Copy + fmt::Debug; - // Accessors - fn patch(&mut self) -> &mut MirPatch<'tcx>; fn body(&self) -> &'a Body<'tcx>; fn tcx(&self) -> TyCtxt<'tcx>; fn param_env(&self) -> ty::ParamEnv<'tcx>; - // Drop logic - - /// Returns how `path` should be dropped, given `mode`. fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle; - - /// Returns the drop flag of `path` as a MIR `Operand` (or `None` if `path` has no drop flag). fn get_drop_flag(&mut self, path: Self::Path) -> Option>; - - /// Modifies the MIR patch so that the drop flag of `path` (if any) is cleared at `location`. - /// - /// If `mode` is deep, drop flags of all child paths should also be cleared by inserting - /// additional statements. fn clear_drop_flag(&mut self, location: Location, path: Self::Path, mode: DropFlagMode); - // Subpaths - - /// Returns the subpath of a field of `path` (or `None` if there is no dedicated subpath). - /// - /// If this returns `None`, `field` will not get a dedicated drop flag. fn field_subpath(&self, path: Self::Path, field: Field) -> Option; - - /// Returns the subpath of a dereference of `path` (or `None` if there is no dedicated subpath). - /// - /// If this returns `None`, `*path` will not get a dedicated drop flag. - /// - /// This is only relevant for `Box`, where the contained `T` can be moved out of the box. fn deref_subpath(&self, path: Self::Path) -> Option; - - /// Returns the subpath of downcasting `path` to one of its variants. - /// - /// If this returns `None`, the downcast of `path` will not get a dedicated drop flag. fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option; - - /// Returns the subpath of indexing a fixed-size array `path`. - /// - /// If this returns `None`, elements of `path` will not get a dedicated drop flag. - /// - /// This is only relevant for array patterns, which can move out of individual array elements. - fn array_subpath(&self, path: Self::Path, index: u32, size: u32) -> Option; + fn array_subpath(&self, path: Self::Path, index: u64, size: u64) -> Option; } #[derive(Debug)] @@ -168,14 +106,6 @@ where unwind: Unwind, } -/// "Elaborates" a drop of `place`/`path` and patches `bb`'s terminator to execute it. -/// -/// The passed `elaborator` is used to determine what should happen at the drop terminator. It -/// decides whether the drop can be statically determined or whether it needs a dynamic drop flag, -/// and whether the drop is "open", ie. should be expanded to drop all subfields of the dropped -/// value. -/// -/// When this returns, the MIR patch in the `elaborator` contains the necessary changes. pub fn elaborate_drop<'b, 'tcx, D>( elaborator: &mut D, source_info: SourceInfo, @@ -238,7 +168,7 @@ where self.elaborator.patch().patch_terminator( bb, TerminatorKind::Drop { - place: self.place, + location: self.place, target: self.succ, unwind: self.unwind.into_option(), }, @@ -279,7 +209,7 @@ where let subpath = self.elaborator.field_subpath(variant_path, field); let tcx = self.tcx(); - assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); + assert_eq!(self.elaborator.param_env().reveal, Reveal::All); let field_ty = tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); (tcx.mk_place_field(base_place, field, field_ty), subpath) @@ -426,7 +356,9 @@ where let interior = self.tcx().mk_place_deref(self.place); let interior_path = self.elaborator.deref_subpath(self.path); - let succ = self.box_free_block(adt, substs, self.succ, self.unwind); + let succ = self.succ; // FIXME(#43234) + let unwind = self.unwind; + let succ = self.box_free_block(adt, substs, succ, unwind); let unwind_succ = self.unwind.map(|unwind| self.box_free_block(adt, substs, unwind, Unwind::InCleanup)); @@ -613,7 +545,7 @@ where fn destructor_call_block(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock { debug!("destructor_call_block({:?}, {:?})", self, succ); let tcx = self.tcx(); - let drop_trait = tcx.require_lang_item(DropTraitLangItem, None); + let drop_trait = tcx.lang_items().drop_trait().unwrap(); let drop_fn = tcx.associated_items(drop_trait).in_definition_order().next().unwrap(); let ty = self.place_ty(self.place); let substs = tcx.mk_substs_trait(ty, &[]); @@ -644,7 +576,6 @@ where destination: Some((unit_temp, succ)), cleanup: unwind.into_option(), from_hir_call: true, - fn_span: self.source_info.span, }, source_info: self.source_info, }), @@ -723,7 +654,7 @@ where self.elaborator.patch().patch_terminator( drop_block, TerminatorKind::Drop { - place: tcx.mk_place_deref(ptr), + location: tcx.mk_place_deref(ptr), target: loop_block, unwind: unwind.into_option(), }, @@ -744,8 +675,8 @@ where let tcx = self.tcx(); if let Some(size) = opt_size { - let size: u32 = size.try_into().unwrap_or_else(|_| { - bug!("move out check isn't implemented for array sizes bigger than u32::MAX"); + let size: u64 = size.try_into().unwrap_or_else(|_| { + bug!("move out check isn't implemented for array sizes bigger than u64::MAX"); }); let fields: Vec<(Place<'tcx>, Option)> = (0..size) .map(|i| { @@ -922,8 +853,6 @@ where self.drop_flag_test_block(drop_block, succ, unwind) } - /// Creates a block that resets the drop flag. If `mode` is deep, all children drop flags will - /// also be cleared. fn drop_flag_reset_block( &mut self, mode: DropFlagMode, @@ -940,15 +869,13 @@ where fn elaborated_drop_block(&mut self) -> BasicBlock { debug!("elaborated_drop_block({:?})", self); - let blk = self.drop_block(self.succ, self.unwind); + let unwind = self.unwind; // FIXME(#43234) + let succ = self.succ; + let blk = self.drop_block(succ, unwind); self.elaborate_drop(blk); blk } - /// Creates a block that frees the backing memory of a `Box` if its drop is required (either - /// statically or by checking its drop flag). - /// - /// The contained value will not be dropped. fn box_free_block( &mut self, adt: &'tcx ty::AdtDef, @@ -960,8 +887,6 @@ where self.drop_flag_test_block(block, target, unwind) } - /// Creates a block that frees the backing memory of a `Box` (without dropping the contained - /// value). fn unelaborated_free_block( &mut self, adt: &'tcx ty::AdtDef, @@ -971,7 +896,8 @@ where ) -> BasicBlock { let tcx = self.tcx(); let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); - let free_func = tcx.require_lang_item(BoxFreeFnLangItem, Some(self.source_info.span)); + let free_func = + tcx.require_lang_item(lang_items::BoxFreeFnLangItem, Some(self.source_info.span)); let args = adt.variants[VariantIdx::new(0)] .fields .iter() @@ -989,7 +915,6 @@ where destination: Some((unit_temp, target)), cleanup: None, from_hir_call: false, - fn_span: self.source_info.span, }; // FIXME(#43234) let free_block = self.new_block(unwind, call); @@ -1000,7 +925,7 @@ where fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let block = - TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_option() }; + TerminatorKind::Drop { location: self.place, target, unwind: unwind.into_option() }; self.new_block(unwind, block) } @@ -1009,11 +934,6 @@ where self.new_block(unwind, block) } - /// Returns the block to jump to in order to test the drop flag and execute the drop. - /// - /// Depending on the required `DropStyle`, this might be a generated block with an `if` - /// terminator (for dynamic/open drops), or it might be `on_set` or `on_unset` itself, in case - /// the drop can be statically determined. fn drop_flag_test_block( &mut self, on_set: BasicBlock, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index e5c28f225c611..62aec66a255d5 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -308,7 +308,7 @@ impl<'a> Parser<'a> { } fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool { - match (self.expr_is_complete(lhs), self.check_assoc_op().map(|op| op.node)) { + match (self.expr_is_complete(lhs), AssocOp::from_token(&self.token)) { // Semi-statement forms are odd: // See https://github.com/rust-lang/rust/issues/29071 (true, None) => false, diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index 59edf21b733c9..832cde86d0b7b 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -70,7 +70,7 @@ impl CheckAttrVisitor<'tcx> { } else if self.tcx.sess.check_name(attr, sym::track_caller) { self.check_track_caller(&attr.span, attrs, span, target) } else if self.tcx.sess.check_name(attr, sym::doc) { - self.check_doc_alias(attr) + self.check_doc_alias(attr, hir_id, target) } else { true }; @@ -217,7 +217,7 @@ impl CheckAttrVisitor<'tcx> { } } - fn check_doc_alias(&self, attr: &Attribute) -> bool { + fn check_doc_alias(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool { if let Some(mi) = attr.meta() { if let Some(list) = mi.meta_item_list() { for meta in list { @@ -238,6 +238,28 @@ impl CheckAttrVisitor<'tcx> { .emit(); return false; } + if let Some(err) = match target { + Target::Impl => Some("implementation block"), + Target::ForeignMod => Some("extern block"), + Target::AssocTy => { + let parent_hir_id = self.tcx.hir().get_parent_item(hir_id); + let containing_item = self.tcx.hir().expect_item(parent_hir_id); + if Target::from_item(containing_item) == Target::Impl { + Some("type alias in implementation block") + } else { + None + } + } + _ => None, + } { + self.tcx + .sess + .struct_span_err( + meta.span(), + &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err,), + ) + .emit(); + } } } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d47a8273d07ea..810bf59ea6c35 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -6,9 +6,12 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit as hir_visit; +use rustc_hir::intravisit::Visitor; use rustc_hir::itemlikevisit::ParItemLikeVisitor; use rustc_hir::lang_items; use rustc_hir::ItemKind; +use rustc_middle::hir::map as hir_map; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ @@ -275,6 +278,107 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_associated_item(tcx, impl_item.hir_id, impl_item.span, method_sig); } +fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { + match param.kind { + // We currently only check wf of const params here. + hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (), + + // Const parameters are well formed if their + // type is structural match. + hir::GenericParamKind::Const { ty: hir_ty } => { + let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id)); + + let err_ty_str; + let mut is_ptr = true; + let err = if tcx.features().min_const_generics { + match ty.kind { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, + ty::FnPtr(_) => Some("function pointers"), + ty::RawPtr(_) => Some("raw pointers"), + _ => { + is_ptr = false; + err_ty_str = format!("`{}`", ty); + Some(err_ty_str.as_str()) + } + } + } else { + match ty.peel_refs().kind { + ty::FnPtr(_) => Some("function pointers"), + ty::RawPtr(_) => Some("raw pointers"), + _ => None, + } + }; + if let Some(unsupported_type) = err { + if is_ptr { + tcx.sess.span_err( + hir_ty.span, + &format!( + "using {} as const generic parameters is forbidden", + unsupported_type + ), + ) + } else { + tcx.sess + .struct_span_err( + hir_ty.span, + &format!( + "{} is forbidden as the type of a const generic parameter", + unsupported_type + ), + ) + .note("the only supported types are integers, `bool` and `char`") + .note("more complex types are supported with `#[feature(const_generics)]`") + .emit() + } + }; + + if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty) + .is_some() + { + // We use the same error code in both branches, because this is really the same + // issue: we just special-case the message for type parameters to make it + // clearer. + if let ty::Param(_) = ty.peel_refs().kind { + // Const parameters may not have type parameters as their types, + // because we cannot be sure that the type parameter derives `PartialEq` + // and `Eq` (just implementing them is not enough for `structural_match`). + struct_span_err!( + tcx.sess, + hir_ty.span, + E0741, + "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \ + used as the type of a const parameter", + ty, + ) + .span_label( + hir_ty.span, + format!("`{}` may not derive both `PartialEq` and `Eq`", ty), + ) + .note( + "it is not currently possible to use a type parameter as the type of a \ + const parameter", + ) + .emit(); + } else { + struct_span_err!( + tcx.sess, + hir_ty.span, + E0741, + "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ + the type of a const parameter", + ty, + ) + .span_label( + hir_ty.span, + format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), + ) + .emit(); + } + } + } + } +} + fn check_associated_item( tcx: TyCtxt<'_>, item_id: hir::HirId, @@ -1282,6 +1386,7 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) { fcx.select_all_obligations_or_error(); } +#[derive(Clone, Copy)] pub struct CheckTypeWellFormedVisitor<'tcx> { tcx: TyCtxt<'tcx>, } @@ -1294,21 +1399,49 @@ impl CheckTypeWellFormedVisitor<'tcx> { impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> { fn visit_item(&self, i: &'tcx hir::Item<'tcx>) { + Visitor::visit_item(&mut self.clone(), i); + } + + fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) { + Visitor::visit_trait_item(&mut self.clone(), trait_item); + } + + fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) { + Visitor::visit_impl_item(&mut self.clone(), impl_item); + } +} + +impl Visitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> { + type Map = hir_map::Map<'tcx>; + + fn nested_visit_map(&mut self) -> hir_visit::NestedVisitorMap { + hir_visit::NestedVisitorMap::OnlyBodies(self.tcx.hir()) + } + + fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { debug!("visit_item: {:?}", i); let def_id = self.tcx.hir().local_def_id(i.hir_id); self.tcx.ensure().check_item_well_formed(def_id); + hir_visit::walk_item(self, i); } - fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) { + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { debug!("visit_trait_item: {:?}", trait_item); let def_id = self.tcx.hir().local_def_id(trait_item.hir_id); self.tcx.ensure().check_trait_item_well_formed(def_id); + hir_visit::walk_trait_item(self, trait_item); } - fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) { + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { debug!("visit_impl_item: {:?}", impl_item); let def_id = self.tcx.hir().local_def_id(impl_item.hir_id); self.tcx.ensure().check_impl_item_well_formed(def_id); + hir_visit::walk_impl_item(self, impl_item); + } + + fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { + check_param_wf(self.tcx, p); + hir_visit::walk_generic_param(self, p); } } diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index f1478c8c952f8..70ed92c5614a1 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -12,7 +12,6 @@ use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; -use rustc_trait_selection::traits; use super::ItemCtxt; use super::{bad_placeholder_type, is_suggestable_infer_ty}; @@ -323,88 +322,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } Node::GenericParam(param) => match ¶m.kind { - GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty), - GenericParamKind::Const { ty: ref hir_ty, .. } => { - let ty = icx.to_ty(hir_ty); - let err_ty_str; - let err = if tcx.features().min_const_generics { - match ty.kind { - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, - ty::FnPtr(_) => Some("function pointers"), - ty::RawPtr(_) => Some("raw pointers"), - _ => { - err_ty_str = format!("`{}`", ty); - Some(err_ty_str.as_str()) - } - } - } else { - match ty.peel_refs().kind { - ty::FnPtr(_) => Some("function pointers"), - ty::RawPtr(_) => Some("raw pointers"), - _ => None, - } - }; - if let Some(unsupported_type) = err { - let mut err = tcx.sess.struct_span_err( - hir_ty.span, - &format!( - "using {} as const generic parameters is forbidden", - unsupported_type - ), - ); - - if tcx.features().min_const_generics { - err.note("the only supported types are integers, `bool` and `char`") - .note("more complex types are supported with `#[feature(const_generics)]`").emit() - } else { - err.emit(); - } - }; - if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty) - .is_some() - { - // We use the same error code in both branches, because this is really the same - // issue: we just special-case the message for type parameters to make it - // clearer. - if let ty::Param(_) = ty.peel_refs().kind { - // Const parameters may not have type parameters as their types, - // because we cannot be sure that the type parameter derives `PartialEq` - // and `Eq` (just implementing them is not enough for `structural_match`). - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \ - used as the type of a const parameter", - ty, - ) - .span_label( - hir_ty.span, - format!("`{}` may not derive both `PartialEq` and `Eq`", ty), - ) - .note( - "it is not currently possible to use a type parameter as the type of a \ - const parameter", - ) - .emit(); - } else { - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ - the type of a const parameter", - ty, - ) - .span_label( - hir_ty.span, - format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), - ) - .emit(); - } - } - ty - } + GenericParamKind::Type { default: Some(ty), .. } + | GenericParamKind::Const { ty, .. } => icx.to_ty(ty), x => bug!("unexpected non-type Node::GenericParam: {:?}", x), }, diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 4af13e4cd587a..1354ef5cbdeb4 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -14,5 +14,6 @@ minifier = "0.0.33" rayon = { version = "0.3.0", package = "rustc-rayon" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +smallvec = "1.0" tempfile = "3" itertools = "0.8" diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 914dc2e1b8847..3eac5bbda0078 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -3,6 +3,7 @@ use std::default::Default; use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; +use std::lazy::SyncOnceCell as OnceCell; use std::num::NonZeroU32; use std::rc::Rc; use std::sync::Arc; @@ -19,12 +20,14 @@ use rustc_hir::lang_items; use rustc_hir::Mutability; use rustc_index::vec::IndexVec; use rustc_middle::middle::stability; +use rustc_middle::ty::TyCtxt; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, FileName}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; +use smallvec::{smallvec, SmallVec}; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1264,6 +1267,86 @@ impl PrimitiveType { } } + pub fn impls(&self, tcx: TyCtxt<'_>) -> &'static SmallVec<[DefId; 4]> { + Self::all_impls(tcx).get(self).expect("missing impl for primitive type") + } + + pub fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap> { + static CELL: OnceCell>> = OnceCell::new(); + + CELL.get_or_init(move || { + use self::PrimitiveType::*; + + /// A macro to create a FxHashMap. + /// + /// Example: + /// + /// ``` + /// let letters = map!{"a" => "b", "c" => "d"}; + /// ``` + /// + /// Trailing commas are allowed. + /// Commas between elements are required (even if the expression is a block). + macro_rules! map { + ($( $key: expr => $val: expr ),* $(,)*) => {{ + let mut map = ::rustc_data_structures::fx::FxHashMap::default(); + $( map.insert($key, $val); )* + map + }} + } + + let single = |a: Option| a.into_iter().collect(); + let both = |a: Option, b: Option| -> SmallVec<_> { + a.into_iter().chain(b).collect() + }; + + let lang_items = tcx.lang_items(); + map! { + Isize => single(lang_items.isize_impl()), + I8 => single(lang_items.i8_impl()), + I16 => single(lang_items.i16_impl()), + I32 => single(lang_items.i32_impl()), + I64 => single(lang_items.i64_impl()), + I128 => single(lang_items.i128_impl()), + Usize => single(lang_items.usize_impl()), + U8 => single(lang_items.u8_impl()), + U16 => single(lang_items.u16_impl()), + U32 => single(lang_items.u32_impl()), + U64 => single(lang_items.u64_impl()), + U128 => single(lang_items.u128_impl()), + F32 => both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), + F64 => both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), + Char => single(lang_items.char_impl()), + Bool => single(lang_items.bool_impl()), + Str => both(lang_items.str_impl(), lang_items.str_alloc_impl()), + Slice => { + lang_items + .slice_impl() + .into_iter() + .chain(lang_items.slice_u8_impl()) + .chain(lang_items.slice_alloc_impl()) + .chain(lang_items.slice_u8_alloc_impl()) + .collect() + }, + Array => single(lang_items.array_impl()), + Tuple => smallvec![], + Unit => smallvec![], + RawPointer => { + lang_items + .const_ptr_impl() + .into_iter() + .chain(lang_items.mut_ptr_impl()) + .chain(lang_items.const_slice_ptr_impl()) + .chain(lang_items.mut_slice_ptr_impl()) + .collect() + }, + Reference => smallvec![], + Fn => smallvec![], + Never => smallvec![], + } + }) + } + pub fn to_url_str(&self) -> &'static str { self.as_str() } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index a502a27948e29..75fdcd5ec1c9c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -351,7 +351,6 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { } pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { - use self::PrimitiveType::*; let tcx = cx.tcx; for item in items { @@ -370,34 +369,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - let did = match primitive { - Isize => tcx.lang_items().isize_impl(), - I8 => tcx.lang_items().i8_impl(), - I16 => tcx.lang_items().i16_impl(), - I32 => tcx.lang_items().i32_impl(), - I64 => tcx.lang_items().i64_impl(), - I128 => tcx.lang_items().i128_impl(), - Usize => tcx.lang_items().usize_impl(), - U8 => tcx.lang_items().u8_impl(), - U16 => tcx.lang_items().u16_impl(), - U32 => tcx.lang_items().u32_impl(), - U64 => tcx.lang_items().u64_impl(), - U128 => tcx.lang_items().u128_impl(), - F32 => tcx.lang_items().f32_impl(), - F64 => tcx.lang_items().f64_impl(), - Char => tcx.lang_items().char_impl(), - Bool => tcx.lang_items().bool_impl(), - Str => tcx.lang_items().str_impl(), - Slice => tcx.lang_items().slice_impl(), - Array => tcx.lang_items().array_impl(), - Tuple => None, - Unit => None, - RawPointer => tcx.lang_items().const_ptr_impl(), - Reference => None, - Fn => None, - Never => None, - }; - if let Some(did) = did { + for &did in primitive.impls(tcx) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c21fd8da0ed9a..5049dbdb1ddc7 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -470,6 +470,10 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt sess.time("missing_docs", || { rustc_lint::check_crate(tcx, rustc_lint::builtin::MissingDoc::new); }); + for &module in tcx.hir().krate().modules.keys() { + let local_def_id = tcx.hir().local_def_id(module); + tcx.ensure().check_mod_attrs(local_def_id); + } let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); // Convert from a HirId set to a DefId set since we don't always have easy access diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 5a9e9dda6771e..ccc07645620a9 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -200,10 +200,12 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option match *clean_type { clean::ResolvedPath { ref path, .. } => { let segments = &path.segments; - let path_segment = segments.iter().last().unwrap_or_else(|| panic!( + let path_segment = segments.iter().last().unwrap_or_else(|| { + panic!( "get_index_type_name(clean_type: {:?}, accept_generic: {:?}) had length zero path", clean_type, accept_generic - )); + ) + }); Some(path_segment.name.clone()) } clean::Generic(ref s) if accept_generic => Some(s.clone()), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d5f7ddcbdfbde..3dfa7b529e34c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -12,6 +12,7 @@ #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] #![feature(never_type)] +#![feature(once_cell)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index b722cfc8f7521..0a836f46c0eb8 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -2,8 +2,9 @@ use crate::clean; use crate::config::OutputFormat; use crate::core::DocContext; use crate::fold::{self, DocFolder}; +use crate::html::markdown::{find_testable_code, ErrorCodes}; +use crate::passes::doc_test_lints::Tests; use crate::passes::Pass; - use rustc_span::symbol::sym; use rustc_span::FileName; use serde::Serialize; @@ -30,15 +31,19 @@ fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::C struct ItemCount { total: u64, with_docs: u64, + with_examples: u64, } impl ItemCount { - fn count_item(&mut self, has_docs: bool) { + fn count_item(&mut self, has_docs: bool, has_doc_example: bool) { self.total += 1; if has_docs { self.with_docs += 1; } + if has_doc_example { + self.with_examples += 1; + } } fn percentage(&self) -> Option { @@ -48,13 +53,25 @@ impl ItemCount { None } } + + fn examples_percentage(&self) -> Option { + if self.total > 0 { + Some((self.with_examples as f64 * 100.0) / self.total as f64) + } else { + None + } + } } impl ops::Sub for ItemCount { type Output = Self; fn sub(self, rhs: Self) -> Self { - ItemCount { total: self.total - rhs.total, with_docs: self.with_docs - rhs.with_docs } + ItemCount { + total: self.total - rhs.total, + with_docs: self.with_docs - rhs.with_docs, + with_examples: self.with_examples - rhs.with_examples, + } } } @@ -62,6 +79,7 @@ impl ops::AddAssign for ItemCount { fn add_assign(&mut self, rhs: Self) { self.total += rhs.total; self.with_docs += rhs.with_docs; + self.with_examples += rhs.with_examples; } } @@ -103,33 +121,55 @@ impl CoverageCalculator { let mut total = ItemCount::default(); fn print_table_line() { - println!("+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); + println!("+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); } - fn print_table_record(name: &str, count: ItemCount, percentage: f64) { + fn print_table_record( + name: &str, + count: ItemCount, + percentage: f64, + examples_percentage: f64, + ) { println!( - "| {:<35} | {:>10} | {:>10} | {:>9.1}% |", - name, count.with_docs, count.total, percentage + "| {:<35} | {:>10} | {:>10} | {:>9.1}% | {:>10} | {:>9.1}% |", + name, + count.with_docs, + count.total, + percentage, + count.with_examples, + examples_percentage, ); } print_table_line(); println!( - "| {:<35} | {:>10} | {:>10} | {:>10} |", - "File", "Documented", "Total", "Percentage" + "| {:<35} | {:>10} | {:>10} | {:>10} | {:>10} | {:>10} |", + "File", "Documented", "Total", "Percentage", "Examples", "Percentage", ); print_table_line(); for (file, &count) in &self.items { - if let Some(percentage) = count.percentage() { - print_table_record(&limit_filename_len(file.to_string()), count, percentage); + if let (Some(percentage), Some(examples_percentage)) = + (count.percentage(), count.examples_percentage()) + { + print_table_record( + &limit_filename_len(file.to_string()), + count, + percentage, + examples_percentage, + ); total += count; } } print_table_line(); - print_table_record("Total", total, total.percentage().unwrap_or(0.0)); + print_table_record( + "Total", + total, + total.percentage().unwrap_or(0.0), + total.examples_percentage().unwrap_or(0.0), + ); print_table_line(); } } @@ -137,6 +177,17 @@ impl CoverageCalculator { impl fold::DocFolder for CoverageCalculator { fn fold_item(&mut self, i: clean::Item) -> Option { let has_docs = !i.attrs.doc_strings.is_empty(); + let mut tests = Tests { found_tests: 0 }; + + find_testable_code( + &i.attrs.doc_strings.iter().map(|d| d.as_str()).collect::>().join("\n"), + &mut tests, + ErrorCodes::No, + false, + None, + ); + + let has_doc_example = tests.found_tests != 0; match i.inner { _ if !i.def_id.is_local() => { @@ -187,7 +238,10 @@ impl fold::DocFolder for CoverageCalculator { } _ => { debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename); - self.items.entry(i.source.filename.clone()).or_default().count_item(has_docs); + self.items + .entry(i.source.filename.clone()) + .or_default() + .count_item(has_docs, has_doc_example); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index d4d6a8119c316..97b9fcce05b36 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -16,6 +16,7 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::Ident; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; +use smallvec::SmallVec; use std::cell::Cell; use std::ops::Range; @@ -222,11 +223,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { disambiguator, None | Some(Disambiguator::Namespace(Namespace::TypeNS)) ) { - if let Some(prim) = is_primitive(path_str, ns) { + if let Some((path, prim)) = is_primitive(path_str, ns) { if extra_fragment.is_some() { return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive)); } - return Ok((prim, Some(path_str.to_owned()))); + return Ok((prim, Some(path.to_owned()))); } } return Ok((res, extra_fragment.clone())); @@ -239,11 +240,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { if value != (ns == ValueNS) { return Err(ErrorKind::ResolutionFailure); } - } else if let Some(prim) = is_primitive(path_str, ns) { + } else if let Some((path, prim)) = is_primitive(path_str, ns) { if extra_fragment.is_some() { return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive)); } - return Ok((prim, Some(path_str.to_owned()))); + return Ok((prim, Some(path.to_owned()))); } else { // If resolution failed, it may still be a method // because methods are not handled by the resolver @@ -269,19 +270,27 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }) .ok_or(ErrorKind::ResolutionFailure)?; - if let Some(prim) = is_primitive(&path, TypeNS) { - let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?; - return cx - .tcx - .associated_items(did) - .filter_by_name_unhygienic(item_name) - .next() - .and_then(|item| match item.kind { - ty::AssocKind::Fn => Some("method"), - _ => None, - }) - .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name)))) - .ok_or(ErrorKind::ResolutionFailure); + if let Some((path, prim)) = is_primitive(&path, TypeNS) { + for &impl_ in primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)? { + let link = cx + .tcx + .associated_items(impl_) + .find_by_name_and_namespace( + cx.tcx, + Ident::with_dummy_span(item_name), + ns, + impl_, + ) + .and_then(|item| match item.kind { + ty::AssocKind::Fn => Some("method"), + _ => None, + }) + .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name)))); + if let Some(link) = link { + return Ok(link); + } + } + return Err(ErrorKind::ResolutionFailure); } let (_, ty_res) = cx @@ -1220,33 +1229,24 @@ const PRIMITIVES: &[(&str, Res)] = &[ ("f64", Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F64))), ("str", Res::PrimTy(hir::PrimTy::Str)), ("bool", Res::PrimTy(hir::PrimTy::Bool)), + ("true", Res::PrimTy(hir::PrimTy::Bool)), + ("false", Res::PrimTy(hir::PrimTy::Bool)), ("char", Res::PrimTy(hir::PrimTy::Char)), ]; -fn is_primitive(path_str: &str, ns: Namespace) -> Option { - if ns == TypeNS { PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1) } else { None } +fn is_primitive(path_str: &str, ns: Namespace) -> Option<(&'static str, Res)> { + if ns == TypeNS { + PRIMITIVES + .iter() + .filter(|x| x.0 == path_str) + .copied() + .map(|x| if x.0 == "true" || x.0 == "false" { ("bool", x.1) } else { x }) + .next() + } else { + None + } } -fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option { - let tcx = cx.tcx; - match path_str { - "u8" => tcx.lang_items().u8_impl(), - "u16" => tcx.lang_items().u16_impl(), - "u32" => tcx.lang_items().u32_impl(), - "u64" => tcx.lang_items().u64_impl(), - "u128" => tcx.lang_items().u128_impl(), - "usize" => tcx.lang_items().usize_impl(), - "i8" => tcx.lang_items().i8_impl(), - "i16" => tcx.lang_items().i16_impl(), - "i32" => tcx.lang_items().i32_impl(), - "i64" => tcx.lang_items().i64_impl(), - "i128" => tcx.lang_items().i128_impl(), - "isize" => tcx.lang_items().isize_impl(), - "f32" => tcx.lang_items().f32_impl(), - "f64" => tcx.lang_items().f64_impl(), - "str" => tcx.lang_items().str_impl(), - "bool" => tcx.lang_items().bool_impl(), - "char" => tcx.lang_items().char_impl(), - _ => None, - } +fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option<&'static SmallVec<[DefId; 4]>> { + Some(PrimitiveType::from_symbol(Symbol::intern(path_str))?.impls(cx.tcx)) } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index a40b45f9a7e2c..24baff46dcfa5 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -34,40 +34,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { } // Also try to inline primitive impls from other crates. - let lang_items = cx.tcx.lang_items(); - let primitive_impls = [ - lang_items.isize_impl(), - lang_items.i8_impl(), - lang_items.i16_impl(), - lang_items.i32_impl(), - lang_items.i64_impl(), - lang_items.i128_impl(), - lang_items.usize_impl(), - lang_items.u8_impl(), - lang_items.u16_impl(), - lang_items.u32_impl(), - lang_items.u64_impl(), - lang_items.u128_impl(), - lang_items.f32_impl(), - lang_items.f64_impl(), - lang_items.f32_runtime_impl(), - lang_items.f64_runtime_impl(), - lang_items.bool_impl(), - lang_items.char_impl(), - lang_items.str_impl(), - lang_items.array_impl(), - lang_items.slice_impl(), - lang_items.slice_u8_impl(), - lang_items.str_alloc_impl(), - lang_items.slice_alloc_impl(), - lang_items.slice_u8_alloc_impl(), - lang_items.const_ptr_impl(), - lang_items.mut_ptr_impl(), - lang_items.const_slice_ptr_impl(), - lang_items.mut_slice_ptr_impl(), - ]; - - for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { + for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() { if !def_id.is_local() { inline::build_impl(cx, def_id, None, &mut new_items); diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index aced7d55281ad..1fdc4ee247adf 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -43,6 +43,22 @@ impl<'a, 'tcx> DocFolder for PrivateItemDocTestLinter<'a, 'tcx> { } } +pub(crate) struct Tests { + pub(crate) found_tests: usize, +} + +impl Tests { + pub(crate) fn new() -> Tests { + Tests { found_tests: 0 } + } +} + +impl crate::test::Tester for Tests { + fn add_test(&mut self, _: String, _: LangString, _: usize) { + self.found_tests += 1; + } +} + pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { let hir_id = match cx.as_local_hir_id(item.def_id) { Some(hir_id) => hir_id, @@ -52,17 +68,7 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { } }; - struct Tests { - found_tests: usize, - } - - impl crate::test::Tester for Tests { - fn add_test(&mut self, _: String, _: LangString, _: usize) { - self.found_tests += 1; - } - } - - let mut tests = Tests { found_tests: 0 }; + let mut tests = Tests::new(); find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None); diff --git a/src/test/codegen/vec-shrink-panic.rs b/src/test/codegen/vec-shrink-panic.rs new file mode 100644 index 0000000000000..690c7e6d6ced2 --- /dev/null +++ b/src/test/codegen/vec-shrink-panic.rs @@ -0,0 +1,36 @@ +// compile-flags: -O +// ignore-debug: the debug assertions get in the way +#![crate_type = "lib"] +#![feature(shrink_to)] + +// Make sure that `Vec::shrink_to_fit` never emits panics via `RawVec::shrink_to_fit`, +// "Tried to shrink to a larger capacity", because the length is *always* <= capacity. + +// CHECK-LABEL: @shrink_to_fit +#[no_mangle] +pub fn shrink_to_fit(vec: &mut Vec) { + // CHECK-NOT: panic + vec.shrink_to_fit(); +} + +// CHECK-LABEL: @issue71861 +#[no_mangle] +pub fn issue71861(n: usize) -> Box<[u32]> { + // CHECK-NOT: panic + vec![0; n].into_boxed_slice() +} + +// CHECK-LABEL: @issue75636 +#[no_mangle] +pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> { + // CHECK-NOT: panic + iter.iter().copied().collect() +} + +// Sanity-check that we do see a possible panic for an arbitrary `Vec::shrink_to`. +// CHECK-LABEL: @shrink_to +#[no_mangle] +pub fn shrink_to(vec: &mut Vec) { + // CHECK: panic + vec.shrink_to(42); +} diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs index c90cfc792a978..2c4f7544844d0 100644 --- a/src/test/mir-opt/issue-41697.rs +++ b/src/test/mir-opt/issue-41697.rs @@ -14,7 +14,7 @@ trait Foo { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir +// EMIT_MIR issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir impl Foo for [u8; 1+1] { fn get(&self) -> [u8; 2] { *self diff --git a/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.32bit b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.32bit similarity index 96% rename from src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.32bit rename to src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.32bit index 14ece035f34af..1cef88fd1096b 100644 --- a/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.32bit +++ b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.32bit @@ -1,4 +1,4 @@ -// MIR for `::{{constant}}#0` after SimplifyCfg-qualify-consts +// MIR for `::{{constant}}#0` after SimplifyCfg-promote-consts ::{{constant}}#0: usize = { let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:18:19: 18:22 diff --git a/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.64bit b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.64bit similarity index 96% rename from src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.64bit rename to src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.64bit index 14ece035f34af..1cef88fd1096b 100644 --- a/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.64bit +++ b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.64bit @@ -1,4 +1,4 @@ -// MIR for `::{{constant}}#0` after SimplifyCfg-qualify-consts +// MIR for `::{{constant}}#0` after SimplifyCfg-promote-consts ::{{constant}}#0: usize = { let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:18:19: 18:22 diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-qualify-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir similarity index 98% rename from src/test/mir-opt/loop_test.main.SimplifyCfg-qualify-consts.after.mir rename to src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir index 77bd884681272..b95e73854e352 100644 --- a/src/test/mir-opt/loop_test.main.SimplifyCfg-qualify-consts.after.mir +++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir @@ -1,4 +1,4 @@ -// MIR for `main` after SimplifyCfg-qualify-consts +// MIR for `main` after SimplifyCfg-promote-consts fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/loop_test.rs:6:11: 6:11 diff --git a/src/test/mir-opt/loop_test.rs b/src/test/mir-opt/loop_test.rs index 5d0c30d44108b..7ded5b5757f55 100644 --- a/src/test/mir-opt/loop_test.rs +++ b/src/test/mir-opt/loop_test.rs @@ -2,7 +2,7 @@ // Tests to make sure we correctly generate falseUnwind edges in loops -// EMIT_MIR loop_test.main.SimplifyCfg-qualify-consts.after.mir +// EMIT_MIR loop_test.main.SimplifyCfg-promote-consts.after.mir fn main() { // Exit early at runtime. Since only care about the generated MIR // and not the runtime behavior (which is exercised by other tests) diff --git a/src/test/rustdoc-js/doc-alias.js b/src/test/rustdoc-js/doc-alias.js index 896808d415780..ff188d5145801 100644 --- a/src/test/rustdoc-js/doc-alias.js +++ b/src/test/rustdoc-js/doc-alias.js @@ -5,7 +5,7 @@ const QUERY = [ 'StructFieldItem', 'StructMethodItem', 'ImplTraitItem', - 'ImplAssociatedConstItem', + 'StructImplConstItem', 'ImplTraitFunction', 'EnumItem', 'VariantItem', @@ -64,8 +64,16 @@ const EXPECTED = [ 'others': [], }, { - // ImplAssociatedConstItem - 'others': [], + // StructImplConstItem + 'others': [ + { + 'path': 'doc_alias::Struct', + 'name': 'ImplConstItem', + 'alias': 'StructImplConstItem', + 'href': '../doc_alias/struct.Struct.html#associatedconstant.ImplConstItem', + 'is_alias': true + }, + ], }, { 'others': [ @@ -197,6 +205,10 @@ const EXPECTED = [ 'href': '../doc_alias/constant.Const.html', 'is_alias': true }, + { + 'path': 'doc_alias::Struct', + 'name': 'ImplConstItem', + }, ], }, { diff --git a/src/test/rustdoc-js/doc-alias.rs b/src/test/rustdoc-js/doc-alias.rs index 84c638a199507..41caa98643cdd 100644 --- a/src/test/rustdoc-js/doc-alias.rs +++ b/src/test/rustdoc-js/doc-alias.rs @@ -7,16 +7,14 @@ pub struct Struct { } impl Struct { + #[doc(alias = "StructImplConstItem")] + pub const ImplConstItem: i32 = 0; #[doc(alias = "StructMethodItem")] pub fn method(&self) {} } impl Trait for Struct { - // Shouldn't be listed in aliases! - #[doc(alias = "ImplTraitItem")] type Target = u32; - // Shouldn't be listed in aliases! - #[doc(alias = "ImplAssociatedConstItem")] const AssociatedConst: i32 = 12; #[doc(alias = "ImplTraitFunction")] diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.rs b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs new file mode 100644 index 0000000000000..545964c7bd61b --- /dev/null +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs @@ -0,0 +1,23 @@ +#![feature(doc_alias)] + +pub struct Bar; +pub trait Foo { + type X; + fn foo() -> Self::X; +} + +#[doc(alias = "foo")] //~ ERROR +extern {} + +#[doc(alias = "bar")] //~ ERROR +impl Bar { + #[doc(alias = "const")] + pub const A: u32 = 0; +} + +#[doc(alias = "foobar")] //~ ERROR +impl Foo for Bar { + #[doc(alias = "assoc")] //~ ERROR + type X = i32; + fn foo() -> Self::X { 0 } +} diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr new file mode 100644 index 0000000000000..a66e9939eaf18 --- /dev/null +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -0,0 +1,26 @@ +error: `#[doc(alias = "...")]` isn't allowed on extern block + --> $DIR/check-doc-alias-attr-location.rs:9:7 + | +LL | #[doc(alias = "foo")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:12:7 + | +LL | #[doc(alias = "bar")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:18:7 + | +LL | #[doc(alias = "foobar")] + | ^^^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block + --> $DIR/check-doc-alias-attr-location.rs:20:11 + | +LL | #[doc(alias = "assoc")] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/check-doc-alias-attr.rs b/src/test/rustdoc-ui/check-doc-alias-attr.rs new file mode 100644 index 0000000000000..b02cc1a4545b1 --- /dev/null +++ b/src/test/rustdoc-ui/check-doc-alias-attr.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] +#![feature(doc_alias)] + +#[doc(alias = "foo")] // ok! +pub struct Bar; + +#[doc(alias)] //~ ERROR +#[doc(alias = 0)] //~ ERROR +#[doc(alias("bar"))] //~ ERROR +pub struct Foo; diff --git a/src/test/rustdoc-ui/check-doc-alias-attr.stderr b/src/test/rustdoc-ui/check-doc-alias-attr.stderr new file mode 100644 index 0000000000000..268230ab44a0a --- /dev/null +++ b/src/test/rustdoc-ui/check-doc-alias-attr.stderr @@ -0,0 +1,20 @@ +error: doc alias attribute expects a string: #[doc(alias = "0")] + --> $DIR/check-doc-alias-attr.rs:7:7 + | +LL | #[doc(alias)] + | ^^^^^ + +error: doc alias attribute expects a string: #[doc(alias = "0")] + --> $DIR/check-doc-alias-attr.rs:8:7 + | +LL | #[doc(alias = 0)] + | ^^^^^^^^^ + +error: doc alias attribute expects a string: #[doc(alias = "0")] + --> $DIR/check-doc-alias-attr.rs:9:7 + | +LL | #[doc(alias("bar"))] + | ^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/rustdoc-ui/coverage/basic.stdout b/src/test/rustdoc-ui/coverage/basic.stdout index 3e91660631626..7e795acc575bc 100644 --- a/src/test/rustdoc-ui/coverage/basic.stdout +++ b/src/test/rustdoc-ui/coverage/basic.stdout @@ -1,7 +1,7 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...est/rustdoc-ui/coverage/basic.rs | 7 | 14 | 50.0% | -+-------------------------------------+------------+------------+------------+ -| Total | 7 | 14 | 50.0% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...est/rustdoc-ui/coverage/basic.rs | 7 | 14 | 50.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 7 | 14 | 50.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/doc-examples.rs b/src/test/rustdoc-ui/coverage/doc-examples.rs new file mode 100644 index 0000000000000..cd718f8a34d11 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/doc-examples.rs @@ -0,0 +1,27 @@ +// compile-flags:-Z unstable-options --show-coverage +// check-pass + +//! This test ensure that only rust code examples are counted. + +/// Doc +/// +/// ``` +/// let x = 2; +/// ``` +pub struct Foo; + +/// Doc +/// +/// ```text +/// yolo +/// ``` +pub trait Bar {} + +/// Doc +/// +/// ```ignore (just for the sake of this test) +/// let x = 2; +/// ``` +pub fn foo(a: Foo, b: u32, c: T, d: D) -> u32 { + 0 +} diff --git a/src/test/rustdoc-ui/coverage/doc-examples.stdout b/src/test/rustdoc-ui/coverage/doc-examples.stdout new file mode 100644 index 0000000000000..f25cf79a3f35d --- /dev/null +++ b/src/test/rustdoc-ui/coverage/doc-examples.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...tdoc-ui/coverage/doc-examples.rs | 4 | 4 | 100.0% | 2 | 50.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 4 | 4 | 100.0% | 2 | 50.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/empty.stdout b/src/test/rustdoc-ui/coverage/empty.stdout index 11b514fbfeaef..2a6a2231e5b57 100644 --- a/src/test/rustdoc-ui/coverage/empty.stdout +++ b/src/test/rustdoc-ui/coverage/empty.stdout @@ -1,7 +1,7 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...est/rustdoc-ui/coverage/empty.rs | 0 | 1 | 0.0% | -+-------------------------------------+------------+------------+------------+ -| Total | 0 | 1 | 0.0% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...est/rustdoc-ui/coverage/empty.rs | 0 | 1 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 0 | 1 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/enums.stdout b/src/test/rustdoc-ui/coverage/enums.stdout index 87e2ad9f20df6..dd86f61f8d501 100644 --- a/src/test/rustdoc-ui/coverage/enums.stdout +++ b/src/test/rustdoc-ui/coverage/enums.stdout @@ -1,7 +1,7 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...est/rustdoc-ui/coverage/enums.rs | 6 | 8 | 75.0% | -+-------------------------------------+------------+------------+------------+ -| Total | 6 | 8 | 75.0% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...est/rustdoc-ui/coverage/enums.rs | 6 | 8 | 75.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 6 | 8 | 75.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/exotic.stdout b/src/test/rustdoc-ui/coverage/exotic.stdout index 2bacfcfcecabe..f920a3abd36bb 100644 --- a/src/test/rustdoc-ui/coverage/exotic.stdout +++ b/src/test/rustdoc-ui/coverage/exotic.stdout @@ -1,8 +1,8 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...st/rustdoc-ui/coverage/exotic.rs | 1 | 1 | 100.0% | -| | 2 | 2 | 100.0% | -+-------------------------------------+------------+------------+------------+ -| Total | 3 | 3 | 100.0% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...st/rustdoc-ui/coverage/exotic.rs | 1 | 1 | 100.0% | 0 | 0.0% | +| | 2 | 2 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 3 | 3 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/json.stdout b/src/test/rustdoc-ui/coverage/json.stdout index 63b22a7d94b00..7b5b083e1584c 100644 --- a/src/test/rustdoc-ui/coverage/json.stdout +++ b/src/test/rustdoc-ui/coverage/json.stdout @@ -1 +1 @@ -{"$DIR/json.rs":{"total":13,"with_docs":7}} +{"$DIR/json.rs":{"total":13,"with_docs":7,"with_examples":0}} diff --git a/src/test/rustdoc-ui/coverage/private.stdout b/src/test/rustdoc-ui/coverage/private.stdout index 0d4c7c68fd05e..bca3d51da59d0 100644 --- a/src/test/rustdoc-ui/coverage/private.stdout +++ b/src/test/rustdoc-ui/coverage/private.stdout @@ -1,7 +1,7 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...t/rustdoc-ui/coverage/private.rs | 4 | 7 | 57.1% | -+-------------------------------------+------------+------------+------------+ -| Total | 4 | 7 | 57.1% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...t/rustdoc-ui/coverage/private.rs | 4 | 7 | 57.1% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 4 | 7 | 57.1% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/statics-consts.stdout b/src/test/rustdoc-ui/coverage/statics-consts.stdout index 8459f90ae7b31..31b48cc602a76 100644 --- a/src/test/rustdoc-ui/coverage/statics-consts.stdout +++ b/src/test/rustdoc-ui/coverage/statics-consts.stdout @@ -1,7 +1,7 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...oc-ui/coverage/statics-consts.rs | 6 | 7 | 85.7% | -+-------------------------------------+------------+------------+------------+ -| Total | 6 | 7 | 85.7% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...oc-ui/coverage/statics-consts.rs | 6 | 7 | 85.7% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 6 | 7 | 85.7% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/traits.stdout b/src/test/rustdoc-ui/coverage/traits.stdout index e347a4da0b978..ac63b65023d0b 100644 --- a/src/test/rustdoc-ui/coverage/traits.stdout +++ b/src/test/rustdoc-ui/coverage/traits.stdout @@ -1,7 +1,7 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...st/rustdoc-ui/coverage/traits.rs | 6 | 7 | 85.7% | -+-------------------------------------+------------+------------+------------+ -| Total | 6 | 7 | 85.7% | -+-------------------------------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+------------+ +| File | Documented | Total | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+------------+ +| ...st/rustdoc-ui/coverage/traits.rs | 6 | 7 | 85.7% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ +| Total | 6 | 7 | 85.7% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc/intra-doc-link-true-false.rs b/src/test/rustdoc/intra-doc-link-true-false.rs new file mode 100644 index 0000000000000..7b21e93414740 --- /dev/null +++ b/src/test/rustdoc/intra-doc-link-true-false.rs @@ -0,0 +1,10 @@ +#![deny(broken_intra_doc_links)] +#![crate_name = "foo"] + +// ignore-tidy-linelength + +// @has foo/index.html +// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'true' +// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'false' + +//! A `bool` is either [`true`] or [`false`]. diff --git a/src/test/rustdoc/intra-link-primitive-non-default-impl.rs b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs new file mode 100644 index 0000000000000..160b18a967b20 --- /dev/null +++ b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs @@ -0,0 +1,32 @@ +#![deny(broken_intra_doc_links)] + +// ignore-tidy-linelength + +// @has intra_link_primitive_non_default_impl/fn.str_methods.html +/// [`str::trim`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim"]' 'str::trim' +/// [`str::to_lowercase`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.to_lowercase"]' 'str::to_lowercase' +/// [`str::into_boxed_bytes`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.into_boxed_bytes"]' 'str::into_boxed_bytes' +/// [`str::replace`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html#method.replace"]' 'str::replace' +pub fn str_methods() {} + +// @has intra_link_primitive_non_default_impl/fn.f32_methods.html +/// [f32::powi] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.powi"]' 'f32::powi' +/// [f32::sqrt] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.sqrt"]' 'f32::sqrt' +/// [f32::mul_add] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.mul_add"]' 'f32::mul_add' +pub fn f32_methods() {} + +// @has intra_link_primitive_non_default_impl/fn.f64_methods.html +/// [`f64::powi`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.powi"]' 'f64::powi' +/// [`f64::sqrt`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.sqrt"]' 'f64::sqrt' +/// [`f64::mul_add`] +// @has - '//*[@href="https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.mul_add"]' 'f64::mul_add' +pub fn f64_methods() {} diff --git a/src/test/ui/check-doc-alias-attr-location.rs b/src/test/ui/check-doc-alias-attr-location.rs new file mode 100644 index 0000000000000..dac9b7372e08b --- /dev/null +++ b/src/test/ui/check-doc-alias-attr-location.rs @@ -0,0 +1,24 @@ +#![crate_type="lib"] +#![feature(doc_alias)] + +pub struct Bar; +pub trait Foo { + type X; + fn foo() -> Self::X; +} + +#[doc(alias = "foo")] //~ ERROR +extern {} + +#[doc(alias = "bar")] //~ ERROR +impl Bar { + #[doc(alias = "const")] + const A: u32 = 0; +} + +#[doc(alias = "foobar")] //~ ERROR +impl Foo for Bar { + #[doc(alias = "assoc")] //~ ERROR + type X = i32; + fn foo() -> Self::X { 0 } +} diff --git a/src/test/ui/check-doc-alias-attr-location.stderr b/src/test/ui/check-doc-alias-attr-location.stderr new file mode 100644 index 0000000000000..29a99e4470e5f --- /dev/null +++ b/src/test/ui/check-doc-alias-attr-location.stderr @@ -0,0 +1,26 @@ +error: `#[doc(alias = "...")]` isn't allowed on extern block + --> $DIR/check-doc-alias-attr-location.rs:10:7 + | +LL | #[doc(alias = "foo")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:13:7 + | +LL | #[doc(alias = "bar")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:19:7 + | +LL | #[doc(alias = "foobar")] + | ^^^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block + --> $DIR/check-doc-alias-attr-location.rs:21:11 + | +LL | #[doc(alias = "assoc")] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr index 61d23475c6f79..809514e8a1c9d 100644 --- a/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr +++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr @@ -14,7 +14,7 @@ LL | arr: [u8; CFG.arr_size], | = help: it is currently only allowed to use either `CFG` or `{ CFG }` as generic constants -error: using `Config` as const generic parameters is forbidden +error: `Config` is forbidden as the type of a const generic parameter --> $DIR/array-size-in-generic-struct-param.rs:18:21 | LL | struct B { diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs index aa1a3b9cf2888..8bd3b78725957 100644 --- a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs +++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs @@ -16,7 +16,7 @@ struct Config { } struct B { - //[min]~^ ERROR using `Config` as const generic parameters is forbidden + //[min]~^ ERROR `Config` is forbidden arr: [u8; CFG.arr_size], //[full]~^ ERROR constant expression depends on a generic parameter //[min]~^^ ERROR generic parameters must not be used inside of non trivial diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr index bdd1da96c7565..81dbaee0ec514 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr +++ b/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr @@ -28,7 +28,7 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here LL | fn bar() {} | ^ explicit lifetime name needed here -error: using `&'static u8` as const generic parameters is forbidden +error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:11:19 | LL | struct A; @@ -37,7 +37,7 @@ LL | struct A; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static u8` as const generic parameters is forbidden +error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:16:15 | LL | impl A { @@ -46,7 +46,7 @@ LL | impl A { = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static u8` as const generic parameters is forbidden +error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:24:15 | LL | impl B for A {} @@ -55,7 +55,7 @@ LL | impl B for A {} = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static u8` as const generic parameters is forbidden +error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:28:17 | LL | fn bar() {} @@ -64,7 +64,7 @@ LL | fn bar() {} = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static u8` as const generic parameters is forbidden +error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:19:21 | LL | fn foo(&self) {} diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.rs b/src/test/ui/const-generics/const-param-elided-lifetime.rs index 814b71d4b741f..633e876f1d7dd 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.rs +++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs @@ -10,23 +10,23 @@ struct A; //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden +//[min]~^^ ERROR `&'static u8` is forbidden trait B {} impl A { //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden +//[min]~^^ ERROR `&'static u8` is forbidden fn foo(&self) {} //~^ ERROR `&` without an explicit lifetime name cannot be used here - //[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden + //[min]~^^ ERROR `&'static u8` is forbidden } impl B for A {} //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden +//[min]~^^ ERROR `&'static u8` is forbidden fn bar() {} //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden +//[min]~^^ ERROR `&'static u8` is forbidden fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index 103f4c36faef3..b00a160787629 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -10,7 +10,7 @@ error[E0770]: the type of const parameters must not depend on other generic para LL | pub struct SelfDependent; | ^ the type must not depend on the parameter `N` -error: using `[u8; _]` as const generic parameters is forbidden +error: `[u8; _]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:12:47 | LL | pub struct Dependent([(); N]); @@ -19,7 +19,7 @@ LL | pub struct Dependent([(); N]); = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `[u8; _]` as const generic parameters is forbidden +error: `[u8; _]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:16:35 | LL | pub struct SelfDependent; diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs index d21a7cec117ee..29371eeb21d1c 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -11,10 +11,10 @@ pub struct Dependent([(); N]); //~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR using `[u8; _]` as const generic parameters is forbidden +//[min]~^^ ERROR `[u8; _]` is forbidden pub struct SelfDependent; //~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR using `[u8; _]` as const generic parameters is forbidden +//[min]~^^ ERROR `[u8; _]` is forbidden fn main() {} diff --git a/src/test/ui/const-generics/different_byref.min.stderr b/src/test/ui/const-generics/different_byref.min.stderr index 770491179abb5..050b28abe5088 100644 --- a/src/test/ui/const-generics/different_byref.min.stderr +++ b/src/test/ui/const-generics/different_byref.min.stderr @@ -1,4 +1,4 @@ -error: using `[usize; 1]` as const generic parameters is forbidden +error: `[usize; 1]` is forbidden as the type of a const generic parameter --> $DIR/different_byref.rs:8:23 | LL | struct Const {} diff --git a/src/test/ui/const-generics/different_byref.rs b/src/test/ui/const-generics/different_byref.rs index ec85ed775d4f5..cd3960eeb8e0d 100644 --- a/src/test/ui/const-generics/different_byref.rs +++ b/src/test/ui/const-generics/different_byref.rs @@ -6,7 +6,7 @@ #![cfg_attr(min, feature(min_const_generics))] struct Const {} -//[min]~^ using `[usize; 1]` as const generic parameters is forbidden +//[min]~^ ERROR `[usize; 1]` is forbidden fn main() { let mut x = Const::<{ [3] }> {}; diff --git a/src/test/ui/const-generics/fn-const-param-call.min.stderr b/src/test/ui/const-generics/fn-const-param-call.min.stderr index 83acd04e4640b..f1bd8def9ff16 100644 --- a/src/test/ui/const-generics/fn-const-param-call.min.stderr +++ b/src/test/ui/const-generics/fn-const-param-call.min.stderr @@ -3,18 +3,12 @@ error: using function pointers as const generic parameters is forbidden | LL | struct Wrapper u32>; | ^^^^^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` error: using function pointers as const generic parameters is forbidden --> $DIR/fn-const-param-call.rs:14:15 | LL | impl u32> Wrapper { | ^^^^^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/fn-const-param-infer.min.stderr b/src/test/ui/const-generics/fn-const-param-infer.min.stderr index 27d1101cbcb05..4bdc9b89af607 100644 --- a/src/test/ui/const-generics/fn-const-param-infer.min.stderr +++ b/src/test/ui/const-generics/fn-const-param-infer.min.stderr @@ -3,9 +3,6 @@ error: using function pointers as const generic parameters is forbidden | LL | struct Checked bool>; | ^^^^^^^^^^^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` error: aborting due to previous error diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr index 25aa354022304..40d8f44cafc04 100644 --- a/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr @@ -1,4 +1,4 @@ -error: using `A` as const generic parameters is forbidden +error: `A` is forbidden as the type of a const generic parameter --> $DIR/forbid-non-structural_match-types.rs:10:19 | LL | struct B; // ok @@ -7,7 +7,7 @@ LL | struct B; // ok = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `C` as const generic parameters is forbidden +error: `C` is forbidden as the type of a const generic parameter --> $DIR/forbid-non-structural_match-types.rs:15:19 | LL | struct D; diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.rs b/src/test/ui/const-generics/forbid-non-structural_match-types.rs index 86540db2d03a0..e7356d485dbff 100644 --- a/src/test/ui/const-generics/forbid-non-structural_match-types.rs +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.rs @@ -8,11 +8,11 @@ struct A; struct B; // ok -//[min]~^ ERROR using `A` as const generic parameters is forbidden +//[min]~^ ERROR `A` is forbidden struct C; struct D; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]` -//[min]~^ ERROR using `C` as const generic parameters is forbidden +//[min]~^ ERROR `C` is forbidden fn main() {} diff --git a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr index 3ff17ddb3bcf3..786ded3c2fe42 100644 --- a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr +++ b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr @@ -1,4 +1,4 @@ -error: using `&'static str` as const generic parameters is forbidden +error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-66596-impl-trait-for-str-const-arg.rs:9:25 | LL | trait Trait { diff --git a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs index d458a366fb373..11d4bf4c3e6aa 100644 --- a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs +++ b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs @@ -7,7 +7,7 @@ trait Trait { -//[min]~^ ERROR using `&'static str` as const generic parameters is forbidden +//[min]~^ ERROR `&'static str` is forbidden type Assoc; } diff --git a/src/test/ui/const-generics/issues/issue-56445.min.stderr b/src/test/ui/const-generics/issues/issue-56445.min.stderr index ca35ee5b2905d..bcb27d8d1e197 100644 --- a/src/test/ui/const-generics/issues/issue-56445.min.stderr +++ b/src/test/ui/const-generics/issues/issue-56445.min.stderr @@ -6,15 +6,6 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | = note: for more information, see issue #74052 -error: using `&'static str` as const generic parameters is forbidden - --> $DIR/issue-56445.rs:9:25 - | -LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); - | ^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0771`. diff --git a/src/test/ui/const-generics/issues/issue-56445.rs b/src/test/ui/const-generics/issues/issue-56445.rs index 174eb16abfc5f..0bcde348b05d5 100644 --- a/src/test/ui/const-generics/issues/issue-56445.rs +++ b/src/test/ui/const-generics/issues/issue-56445.rs @@ -8,6 +8,5 @@ use std::marker::PhantomData; struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); //~^ ERROR: use of non-static lifetime `'a` in const generic -//[min]~| ERROR: using `&'static str` as const impl Bug<'_, ""> {} diff --git a/src/test/ui/const-generics/issues/issue-74950.min.stderr b/src/test/ui/const-generics/issues/issue-74950.min.stderr new file mode 100644 index 0000000000000..f093e6651bc28 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-74950.min.stderr @@ -0,0 +1,47 @@ +error: `Inner` is forbidden as the type of a const generic parameter + --> $DIR/issue-74950.rs:18:23 + | +LL | struct Outer; + | ^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `Inner` is forbidden as the type of a const generic parameter + --> $DIR/issue-74950.rs:18:23 + | +LL | struct Outer; + | ^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `Inner` is forbidden as the type of a const generic parameter + --> $DIR/issue-74950.rs:18:23 + | +LL | struct Outer; + | ^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `Inner` is forbidden as the type of a const generic parameter + --> $DIR/issue-74950.rs:18:23 + | +LL | struct Outer; + | ^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `Inner` is forbidden as the type of a const generic parameter + --> $DIR/issue-74950.rs:18:23 + | +LL | struct Outer; + | ^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/const-generics/issues/issue-74950.rs b/src/test/ui/const-generics/issues/issue-74950.rs new file mode 100644 index 0000000000000..39f91f2b83dfb --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-74950.rs @@ -0,0 +1,25 @@ +// [full] build-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + + +#[derive(PartialEq, Eq)] +struct Inner; + +// Note: We emit the error 5 times if we don't deduplicate: +// - struct definition +// - impl PartialEq +// - impl Eq +// - impl StructuralPartialEq +// - impl StructuralEq +#[derive(PartialEq, Eq)] +struct Outer; +//[min]~^ `Inner` is forbidden +//[min]~| `Inner` is forbidden +//[min]~| `Inner` is forbidden +//[min]~| `Inner` is forbidden +//[min]~| `Inner` is forbidden + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-75047.rs b/src/test/ui/const-generics/issues/issue-75047.rs new file mode 100644 index 0000000000000..5d068d851c10b --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-75047.rs @@ -0,0 +1,15 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +struct Bar(T); + +impl Bar { + const fn value() -> usize { + 42 + } +} + +struct Foo::value()]>; + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.rs b/src/test/ui/const-generics/min_const_generics/complex-types.rs index a396fa83aa629..98bc99d019421 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-types.rs +++ b/src/test/ui/const-generics/min_const_generics/complex-types.rs @@ -1,18 +1,17 @@ #![feature(min_const_generics)] struct Foo; -//~^ ERROR using `[u8; 0]` as const generic parameters is forbidden +//~^ ERROR `[u8; 0]` is forbidden struct Bar; -//~^ ERROR using `()` as const generic parameters is forbidden - +//~^ ERROR `()` is forbidden #[derive(PartialEq, Eq)] struct No; struct Fez; -//~^ ERROR using `No` as const generic parameters is forbidden +//~^ ERROR `No` is forbidden struct Faz; -//~^ ERROR using `&'static u8` as const generic parameters is forbidden +//~^ ERROR `&'static u8` is forbidden fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.stderr b/src/test/ui/const-generics/min_const_generics/complex-types.stderr index 835b1f1a3e867..4772aaf1b3e0c 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-types.stderr +++ b/src/test/ui/const-generics/min_const_generics/complex-types.stderr @@ -1,4 +1,4 @@ -error: using `[u8; 0]` as const generic parameters is forbidden +error: `[u8; 0]` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:3:21 | LL | struct Foo; @@ -7,7 +7,7 @@ LL | struct Foo; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `()` as const generic parameters is forbidden +error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:6:21 | LL | struct Bar; @@ -16,8 +16,8 @@ LL | struct Bar; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `No` as const generic parameters is forbidden - --> $DIR/complex-types.rs:12:21 +error: `No` is forbidden as the type of a const generic parameter + --> $DIR/complex-types.rs:11:21 | LL | struct Fez; | ^^ @@ -25,8 +25,8 @@ LL | struct Fez; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static u8` as const generic parameters is forbidden - --> $DIR/complex-types.rs:15:21 +error: `&'static u8` is forbidden as the type of a const generic parameter + --> $DIR/complex-types.rs:14:21 | LL | struct Faz; | ^^^^^^^^^^^ diff --git a/src/test/ui/const-generics/nested-type.full.stderr b/src/test/ui/const-generics/nested-type.full.stderr index 012b8fe587b30..ded6f882caf42 100644 --- a/src/test/ui/const-generics/nested-type.full.stderr +++ b/src/test/ui/const-generics/nested-type.full.stderr @@ -1,159 +1,16 @@ -error[E0391]: cycle detected when computing type of `Foo` - --> $DIR/nested-type.rs:7:1 +error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants + --> $DIR/nested-type.rs:16:5 | -LL | struct Foo $DIR/nested-type.rs:7:18 - | -LL | struct Foo $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires type-checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`... - --> $DIR/nested-type.rs:11:5 - | -LL | struct Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing the variances for items in this crate... - = note: ...which again requires computing type of `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/nested-type.rs:3:1 - | -LL | / #![cfg_attr(full, feature(const_generics))] -LL | | #![cfg_attr(full, allow(incomplete_features))] -LL | | #![cfg_attr(min, feature(min_const_generics))] -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ -error[E0391]: cycle detected when computing type of `Foo` - --> $DIR/nested-type.rs:7:1 - | -LL | struct Foo $DIR/nested-type.rs:7:18 - | -LL | struct Foo $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires type-checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`... - --> $DIR/nested-type.rs:11:5 - | -LL | struct Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing the variances for items in this crate... - = note: ...which again requires computing type of `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/nested-type.rs:3:1 +error[E0080]: evaluation of constant value failed + --> $DIR/nested-type.rs:16:5 | -LL | / #![cfg_attr(full, feature(const_generics))] -LL | | #![cfg_attr(full, allow(incomplete_features))] -LL | | #![cfg_attr(min, feature(min_const_generics))] -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0015, E0080. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/const-generics/nested-type.min.stderr b/src/test/ui/const-generics/nested-type.min.stderr index ebe818785ac7c..55f6fe7cc16e8 100644 --- a/src/test/ui/const-generics/nested-type.min.stderr +++ b/src/test/ui/const-generics/nested-type.min.stderr @@ -1,175 +1,32 @@ -error: using `[u8; _]` as const generic parameters is forbidden +error: `[u8; _]` is forbidden as the type of a const generic parameter --> $DIR/nested-type.rs:7:21 | LL | struct Foo; LL | | -LL | | -LL | | +LL | | impl Foo { ... | -LL | | Foo::<17>::value() +LL | | LL | | }]>; | |__^ | = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error[E0391]: cycle detected when computing type of `Foo` - --> $DIR/nested-type.rs:7:1 - | -LL | struct Foo $DIR/nested-type.rs:7:18 +error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants + --> $DIR/nested-type.rs:16:5 | -LL | struct Foo $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires type-checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`... - --> $DIR/nested-type.rs:11:5 - | -LL | struct Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing the variances for items in this crate... - = note: ...which again requires computing type of `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/nested-type.rs:3:1 - | -LL | / #![cfg_attr(full, feature(const_generics))] -LL | | #![cfg_attr(full, allow(incomplete_features))] -LL | | #![cfg_attr(min, feature(min_const_generics))] -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ -error[E0391]: cycle detected when computing type of `Foo` - --> $DIR/nested-type.rs:7:1 - | -LL | struct Foo $DIR/nested-type.rs:7:18 - | -LL | struct Foo $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires const-evaluating `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 +error[E0080]: evaluation of constant value failed + --> $DIR/nested-type.rs:16:5 | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires type-checking `Foo::{{constant}}#0`... - --> $DIR/nested-type.rs:7:26 - | -LL | struct Foo::value() -LL | | }]>; - | |_^ -note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`... - --> $DIR/nested-type.rs:11:5 - | -LL | struct Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing the variances for items in this crate... - = note: ...which again requires computing type of `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/nested-type.rs:3:1 - | -LL | / #![cfg_attr(full, feature(const_generics))] -LL | | #![cfg_attr(full, allow(incomplete_features))] -LL | | #![cfg_attr(min, feature(min_const_generics))] -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ +LL | Foo::<17>::value() + | ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value` error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0015, E0080. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/const-generics/nested-type.rs b/src/test/ui/const-generics/nested-type.rs index 98a5a0dd3d8fd..8372551fb450b 100644 --- a/src/test/ui/const-generics/nested-type.rs +++ b/src/test/ui/const-generics/nested-type.rs @@ -4,10 +4,7 @@ #![cfg_attr(full, allow(incomplete_features))] #![cfg_attr(min, feature(min_const_generics))] -struct Foo; impl Foo { @@ -17,6 +14,8 @@ struct Foo::value() + //~^ ERROR calls in constants are limited to constant functions + //~| ERROR evaluation of constant value failed }]>; fn main() {} diff --git a/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr b/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr index dc4bb8b0f042a..ffaab51f766d8 100644 --- a/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr +++ b/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr @@ -3,18 +3,12 @@ error: using raw pointers as const generic parameters is forbidden | LL | struct Const; | ^^^^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` error: using raw pointers as const generic parameters is forbidden --> $DIR/raw-ptr-const-param-deref.rs:12:15 | LL | impl Const

{ | ^^^^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/raw-ptr-const-param.min.stderr b/src/test/ui/const-generics/raw-ptr-const-param.min.stderr index f387974a21aca..d317aa0f585cf 100644 --- a/src/test/ui/const-generics/raw-ptr-const-param.min.stderr +++ b/src/test/ui/const-generics/raw-ptr-const-param.min.stderr @@ -3,9 +3,6 @@ error: using raw pointers as const generic parameters is forbidden | LL | struct Const; | ^^^^^^^^^^ - | - = note: the only supported types are integers, `bool` and `char` - = note: more complex types are supported with `#[feature(const_generics)]` error: aborting due to previous error diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr b/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr index e86f885b9bbad..1f711bef4aa63 100644 --- a/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr +++ b/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr @@ -1,4 +1,4 @@ -error: using `&'static str` as const generic parameters is forbidden +error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/slice-const-param-mismatch.rs:8:29 | LL | struct ConstString; @@ -7,7 +7,7 @@ LL | struct ConstString; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static [u8]` as const generic parameters is forbidden +error: `&'static [u8]` is forbidden as the type of a const generic parameter --> $DIR/slice-const-param-mismatch.rs:10:28 | LL | struct ConstBytes; diff --git a/src/test/ui/const-generics/slice-const-param.min.stderr b/src/test/ui/const-generics/slice-const-param.min.stderr index e2ffc67c3579c..2a49619e6614a 100644 --- a/src/test/ui/const-generics/slice-const-param.min.stderr +++ b/src/test/ui/const-generics/slice-const-param.min.stderr @@ -1,4 +1,4 @@ -error: using `&'static str` as const generic parameters is forbidden +error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/slice-const-param.rs:8:40 | LL | pub fn function_with_str() -> &'static str { @@ -7,7 +7,7 @@ LL | pub fn function_with_str() -> &'static str { = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `&'static [u8]` as const generic parameters is forbidden +error: `&'static [u8]` is forbidden as the type of a const generic parameter --> $DIR/slice-const-param.rs:13:41 | LL | pub fn function_with_bytes() -> &'static [u8] { diff --git a/src/test/ui/const-generics/slice-const-param.rs b/src/test/ui/const-generics/slice-const-param.rs index 1b6d2f6216c44..f76e948c4af2b 100644 --- a/src/test/ui/const-generics/slice-const-param.rs +++ b/src/test/ui/const-generics/slice-const-param.rs @@ -6,12 +6,12 @@ #![cfg_attr(min, feature(min_const_generics))] pub fn function_with_str() -> &'static str { - //[min]~^ ERROR using `&'static str` as const + //[min]~^ ERROR `&'static str` is forbidden STRING } pub fn function_with_bytes() -> &'static [u8] { - //[min]~^ ERROR using `&'static [u8]` as const + //[min]~^ ERROR `&'static [u8]` is forbidden BYTES } diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs index 467daef63f6a6..44421b077fa26 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs @@ -5,10 +5,8 @@ fn test_and() { let b = false; let _ = a and b; //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator if a and b { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } @@ -20,10 +18,8 @@ fn test_or() { let b = false; let _ = a or b; //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator if a or b { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } @@ -32,7 +28,6 @@ fn test_and_par() { let a = true; let b = false; if (a and b) { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -41,7 +36,6 @@ fn test_or_par() { let a = true; let b = false; if (a or b) { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } @@ -50,7 +44,6 @@ fn test_while_and() { let a = true; let b = false; while a and b { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -59,7 +52,6 @@ fn test_while_or() { let a = true; let b = false; while a or b { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr index e8731cf238ec4..528c62f501e0d 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -7,23 +7,7 @@ LL | let _ = a and b; = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15 - | -LL | let _ = a and b; - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10 - | -LL | if a and b { - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10 | LL | if a and b { | ^^^ help: use `&&` to perform logical conjunction @@ -31,7 +15,7 @@ LL | if a and b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15 | LL | let _ = a or b; | ^^ help: use `||` to perform logical disjunction @@ -39,23 +23,7 @@ LL | let _ = a or b; = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15 - | -LL | let _ = a or b; - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10 - | -LL | if a or b { - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10 | LL | if a or b { | ^^ help: use `||` to perform logical disjunction @@ -63,31 +31,15 @@ LL | if a or b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11 | LL | if (a and b) { | ^^^ help: use `&&` to perform logical conjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators -error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11 - | -LL | if (a and b) { - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11 - | -LL | if (a or b) { - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11 | LL | if (a or b) { | ^^ help: use `||` to perform logical disjunction @@ -95,31 +47,15 @@ LL | if (a or b) { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13 | LL | while a and b { | ^^^ help: use `&&` to perform logical conjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators -error: `and` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13 - | -LL | while a and b { - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13 - | -LL | while a or b { - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - error: `or` is not a logical operator - --> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13 | LL | while a or b { | ^^ help: use `||` to perform logical disjunction @@ -127,13 +63,13 @@ LL | while a or b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error[E0308]: mismatched types - --> $DIR/issue-54109-and_instead_of_ampersands.rs:15:33 + --> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer | | | expected due to this -error: aborting due to 17 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.fixed b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed index 21471d75c8215..5079a37f4da7f 100644 --- a/src/test/ui/did_you_mean/issue-54109-without-witness.fixed +++ b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed @@ -11,10 +11,8 @@ fn test_and() { let b = false; let _ = a && b; //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator if a && b { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -24,10 +22,8 @@ fn test_or() { let b = false; let _ = a || b; //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator if a || b { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } @@ -36,7 +32,6 @@ fn test_and_par() { let a = true; let b = false; if (a && b) { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -45,7 +40,6 @@ fn test_or_par() { let a = true; let b = false; if (a || b) { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } @@ -54,7 +48,6 @@ fn test_while_and() { let a = true; let b = false; while a && b { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -63,7 +56,6 @@ fn test_while_or() { let a = true; let b = false; while a || b { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.rs b/src/test/ui/did_you_mean/issue-54109-without-witness.rs index bb9a3a195962e..00660a938d5d6 100644 --- a/src/test/ui/did_you_mean/issue-54109-without-witness.rs +++ b/src/test/ui/did_you_mean/issue-54109-without-witness.rs @@ -11,10 +11,8 @@ fn test_and() { let b = false; let _ = a and b; //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator if a and b { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -24,10 +22,8 @@ fn test_or() { let b = false; let _ = a or b; //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator if a or b { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } @@ -36,7 +32,6 @@ fn test_and_par() { let a = true; let b = false; if (a and b) { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -45,7 +40,6 @@ fn test_or_par() { let a = true; let b = false; if (a or b) { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } @@ -54,7 +48,6 @@ fn test_while_and() { let a = true; let b = false; while a and b { //~ ERROR `and` is not a logical operator - //~| ERROR `and` is not a logical operator println!("both"); } } @@ -63,7 +56,6 @@ fn test_while_or() { let a = true; let b = false; while a or b { //~ ERROR `or` is not a logical operator - //~| ERROR `or` is not a logical operator println!("both"); } } diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr index fe48af592db91..0350890c1fde0 100644 --- a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr +++ b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr @@ -7,23 +7,7 @@ LL | let _ = a and b; = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:13:15 - | -LL | let _ = a and b; - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:16:10 - | -LL | if a and b { - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:16:10 + --> $DIR/issue-54109-without-witness.rs:15:10 | LL | if a and b { | ^^^ help: use `&&` to perform logical conjunction @@ -31,7 +15,7 @@ LL | if a and b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:26:15 + --> $DIR/issue-54109-without-witness.rs:24:15 | LL | let _ = a or b; | ^^ help: use `||` to perform logical disjunction @@ -39,23 +23,7 @@ LL | let _ = a or b; = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:26:15 - | -LL | let _ = a or b; - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:29:10 - | -LL | if a or b { - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:29:10 + --> $DIR/issue-54109-without-witness.rs:26:10 | LL | if a or b { | ^^ help: use `||` to perform logical disjunction @@ -63,31 +31,15 @@ LL | if a or b { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:38:11 + --> $DIR/issue-54109-without-witness.rs:34:11 | LL | if (a and b) { | ^^^ help: use `&&` to perform logical conjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators -error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:38:11 - | -LL | if (a and b) { - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:47:11 - | -LL | if (a or b) { - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:47:11 + --> $DIR/issue-54109-without-witness.rs:42:11 | LL | if (a or b) { | ^^ help: use `||` to perform logical disjunction @@ -95,36 +47,20 @@ LL | if (a or b) { = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:56:13 + --> $DIR/issue-54109-without-witness.rs:50:13 | LL | while a and b { | ^^^ help: use `&&` to perform logical conjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators -error: `and` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:56:13 - | -LL | while a and b { - | ^^^ help: use `&&` to perform logical conjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - -error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:65:13 - | -LL | while a or b { - | ^^ help: use `||` to perform logical disjunction - | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators - error: `or` is not a logical operator - --> $DIR/issue-54109-without-witness.rs:65:13 + --> $DIR/issue-54109-without-witness.rs:58:13 | LL | while a or b { | ^^ help: use `||` to perform logical disjunction | = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators -error: aborting due to 16 previous errors +error: aborting due to 8 previous errors diff --git a/src/test/ui/issues/issue-75599.rs b/src/test/ui/issues/issue-75599.rs new file mode 100644 index 0000000000000..0857676e4ed58 --- /dev/null +++ b/src/test/ui/issues/issue-75599.rs @@ -0,0 +1,24 @@ +// check-pass +#![allow(non_upper_case_globals)] + +const or: usize = 1; +const and: usize = 2; + +mod or { + pub const X: usize = 3; +} + +mod and { + pub const X: usize = 4; +} + +fn main() { + match 0 { + 0 => {} + or => {} + and => {} + or::X => {} + and::X => {} + _ => {} + } +} diff --git a/src/test/ui/lint/clashing-extern-fn-recursion.rs b/src/test/ui/lint/clashing-extern-fn-recursion.rs new file mode 100644 index 0000000000000..ab0fd0a2e7085 --- /dev/null +++ b/src/test/ui/lint/clashing-extern-fn-recursion.rs @@ -0,0 +1,119 @@ +// check-pass +// +// This tests checks that clashing_extern_declarations handles types that are recursive through a +// pointer or ref argument. See #75512. + +#![crate_type = "lib"] + +mod raw_ptr_recursion { + mod a { + #[repr(C)] + struct Pointy { + pointy: *const Pointy, + } + + extern "C" { + fn run_pointy(pointy: Pointy); + } + } + mod b { + #[repr(C)] + struct Pointy { + pointy: *const Pointy, + } + + extern "C" { + fn run_pointy(pointy: Pointy); + } + } +} + +mod raw_ptr_recursion_once_removed { + mod a { + #[repr(C)] + struct Pointy1 { + pointy_two: *const Pointy2, + } + + #[repr(C)] + struct Pointy2 { + pointy_one: *const Pointy1, + } + + extern "C" { + fn run_pointy2(pointy: Pointy2); + } + } + + mod b { + #[repr(C)] + struct Pointy1 { + pointy_two: *const Pointy2, + } + + #[repr(C)] + struct Pointy2 { + pointy_one: *const Pointy1, + } + + extern "C" { + fn run_pointy2(pointy: Pointy2); + } + } +} + +mod ref_recursion { + mod a { + #[repr(C)] + struct Reffy<'a> { + reffy: &'a Reffy<'a>, + } + + extern "C" { + fn reffy_recursion(reffy: Reffy); + } + } + mod b { + #[repr(C)] + struct Reffy<'a> { + reffy: &'a Reffy<'a>, + } + + extern "C" { + fn reffy_recursion(reffy: Reffy); + } + } +} + +mod ref_recursion_once_removed { + mod a { + #[repr(C)] + struct Reffy1<'a> { + reffy: &'a Reffy2<'a>, + } + + struct Reffy2<'a> { + reffy: &'a Reffy1<'a>, + } + + extern "C" { + #[allow(improper_ctypes)] + fn reffy_once_removed(reffy: Reffy1); + } + } + mod b { + #[repr(C)] + struct Reffy1<'a> { + reffy: &'a Reffy2<'a>, + } + + struct Reffy2<'a> { + reffy: &'a Reffy1<'a>, + } + + extern "C" { + #[allow(improper_ctypes)] + fn reffy_once_removed(reffy: Reffy1); + } + } +} diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 1f988f7d81b72..4f98944e4c8eb 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -18,6 +18,7 @@ const LICENSES: &[&str] = &[ "Unlicense/MIT", "Unlicense OR MIT", "0BSD OR MIT OR Apache-2.0", // adler license + "Zlib OR Apache-2.0 OR MIT", // tinyvec ]; /// These are exceptions to Rust's permissive licensing policy, and @@ -25,24 +26,24 @@ const LICENSES: &[&str] = &[ /// tooling. It is _crucial_ that no exception crates be dependencies /// of the Rust runtime (std/test). const EXCEPTIONS: &[(&str, &str)] = &[ - ("mdbook", "MPL-2.0"), // mdbook - ("openssl", "Apache-2.0"), // cargo, mdbook - ("rdrand", "ISC"), // mdbook, rustfmt - ("fuchsia-cprng", "BSD-3-Clause"), // mdbook, rustfmt - ("fuchsia-zircon-sys", "BSD-3-Clause"), // rustdoc, rustc, cargo - ("fuchsia-zircon", "BSD-3-Clause"), // rustdoc, rustc, cargo (jobserver & tempdir) - ("colored", "MPL-2.0"), // rustfmt - ("ordslice", "Apache-2.0"), // rls - ("cloudabi", "BSD-2-Clause"), // (rls -> crossbeam-channel 0.2 -> rand 0.5) - ("ryu", "Apache-2.0 OR BSL-1.0"), // rls/cargo/... (because of serde) - ("bytesize", "Apache-2.0"), // cargo - ("im-rc", "MPL-2.0+"), // cargo - ("constant_time_eq", "CC0-1.0"), // rustfmt - ("sized-chunks", "MPL-2.0+"), // cargo via im-rc - ("bitmaps", "MPL-2.0+"), // cargo via im-rc + ("mdbook", "MPL-2.0"), // mdbook + ("openssl", "Apache-2.0"), // cargo, mdbook + ("fuchsia-zircon-sys", "BSD-3-Clause"), // rustdoc, rustc, cargo + ("fuchsia-zircon", "BSD-3-Clause"), // rustdoc, rustc, cargo (jobserver & tempdir) + ("colored", "MPL-2.0"), // rustfmt + ("ordslice", "Apache-2.0"), // rls + ("cloudabi", "BSD-2-Clause"), // (rls -> crossbeam-channel 0.2 -> rand 0.5) + ("ryu", "Apache-2.0 OR BSL-1.0"), // rls/cargo/... (because of serde) + ("bytesize", "Apache-2.0"), // cargo + ("im-rc", "MPL-2.0+"), // cargo + ("constant_time_eq", "CC0-1.0"), // rustfmt + ("sized-chunks", "MPL-2.0+"), // cargo via im-rc + ("bitmaps", "MPL-2.0+"), // cargo via im-rc + ("crossbeam-queue", "MIT/Apache-2.0 AND BSD-2-Clause"), // rls via rayon + ("arrayref", "BSD-2-Clause"), // cargo-miri/directories/.../rust-argon2 (redox) + ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target - ("crossbeam-channel", "MIT/Apache-2.0 AND BSD-2-Clause"), // cargo ]; /// These are the root crates that are part of the runtime. The licenses for @@ -69,8 +70,8 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "bitflags", "block-buffer", "block-padding", - "byte-tools", "byteorder", + "byte-tools", "cc", "cfg-if", "chalk-derive", @@ -103,6 +104,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "hermit-abi", "humantime", "indexmap", + "instant", "itertools", "jobserver", "kernel32-sys", @@ -112,13 +114,13 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "lock_api", "log", "log_settings", + "maybe-uninit", "md-5", "measureme", "memchr", "memmap", "memoffset", "miniz_oxide", - "nodrop", "num_cpus", "object", "once_cell", @@ -233,6 +235,14 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { } Some(pkg_license) => { if pkg_license.as_str() != *license { + if *name == "crossbeam-queue" + && *license == "MIT/Apache-2.0 AND BSD-2-Clause" + { + // We have two versions of crossbeam-queue and both + // are fine. + continue; + } + println!("dependency exception `{}` license has changed", name); println!(" previously `{}` now `{}`", license, pkg_license); println!(" update EXCEPTIONS for the new license");