From bb0424d6232d9439df6ba4ea58552cc88bdc09be Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 17 Aug 2020 11:21:44 -0400 Subject: [PATCH 01/64] Update dependencies This runs cargo update, applying the following changes: Adding arrayref v0.3.6 Adding base64 v0.11.0 Adding blake2b_simd v0.5.10 Adding cloudabi v0.1.0 Adding crossbeam-queue v0.2.3 Adding instant v0.1.6 Adding lock_api v0.4.1 Adding maybe-uninit v2.0.0 Adding parking_lot_core v0.7.2 Adding parking_lot_core v0.8.0 Adding parking_lot v0.11.0 Adding proc-macro-error-attr v1.0.4 Adding quick-error v2.0.0 Adding rust-argon2 v0.7.0 Adding signal-hook-registry v1.2.1 Adding smallvec v0.6.13 Adding smallvec v1.4.2 Adding tinyvec v0.3.3 Removing argon2rs v0.2.5 Removing arrayvec v0.4.7 Removing blake2-rfc v0.2.18 Removing fuchsia-cprng v0.1.1 Removing nodrop v0.1.12 Removing parking_lot_core v0.7.1 Removing rand_core v0.3.0 Removing rand_core v0.4.0 Removing rand_os v0.1.3 Removing rdrand v0.4.0 Removing scoped_threadpool v0.1.9 Removing signal-hook v0.1.7 Removing smallvec v0.6.10 Removing smallvec v1.4.0 Updating aho-corasick v0.7.10 -> v0.7.13 Updating anyhow v1.0.31 -> v1.0.32 Updating arc-swap v0.3.7 -> v0.4.7 Updating bitmaps v2.0.0 -> v2.1.0 Updating bstr v0.1.3 -> v0.2.13 Updating byteorder v1.3.2 -> v1.3.4 Updating bytesize v1.0.0 -> v1.0.1 Updating bytes v0.4.11 -> v0.4.12 Updating cargo_metadata v0.8.0 -> v0.8.2 Updating chrono v0.4.6 -> v0.4.15 Updating clap v2.33.0 -> v2.33.3 Updating cmake v0.1.42 -> v0.1.44 Updating constant_time_eq v0.1.3 -> v0.1.5 Updating crossbeam-channel v0.4.0 -> v0.4.3 Updating crossbeam-deque v0.7.1 -> v0.7.3 Updating crossbeam-epoch v0.7.2 -> v0.8.2 Updating crossbeam-utils v0.6.5 -> v0.6.6 Updating crypto-hash v0.3.1 -> v0.3.4 Updating ctor v0.1.13 -> v0.1.15 Updating curl-sys v0.4.25 -> v0.4.34+curl-7.71.1 Updating curl v0.4.25 -> v0.4.31 Updating derive_more v0.99.2 -> v0.99.9 Updating diff v0.1.11 -> v0.1.12 Updating directories v2.0.1 -> v2.0.2 Updating dirs-sys v0.3.3 -> v0.3.5 Updating dirs v2.0.1 -> v2.0.2 Updating either v1.5.0 -> v1.6.0 Updating failure v0.1.5 -> v0.1.8 Updating filetime v0.2.9 -> v0.2.12 Updating fnv v1.0.6 -> v1.0.7 Updating fortanix-sgx-abi v0.3.2 -> v0.3.3 Updating fst v0.3.0 -> v0.3.5 Updating futures v0.1.28 -> v0.1.29 Updating git2 v0.13.5 -> v0.13.8 Updating globset v0.4.3 -> v0.4.5 Updating handlebars v3.0.1 -> v3.4.0 Updating heck v0.3.0 -> v0.3.1 Updating hex v0.4.0 -> v0.4.2 Updating home v0.5.1 -> v0.5.3 Updating humantime v2.0.0 -> v2.0.1 Updating ignore v0.4.11 -> v0.4.16 Updating itertools v0.8.0 -> v0.8.2 Updating itoa v0.4.4 -> v0.4.6 Updating jemalloc-sys v0.3.0 -> v0.3.2 Updating jsonrpc-client-transports v14.0.5 -> v14.2.1 Updating jsonrpc-core-client v14.0.5 -> v14.2.0 Updating jsonrpc-core v14.0.5 -> v14.2.0 Updating jsonrpc-derive v14.0.5 -> v14.2.1 Updating jsonrpc-pubsub v14.0.6 -> v14.2.0 Updating jsonrpc-server-utils v14.0.5 -> v14.2.0 Updating json v0.11.13 -> v0.11.15 Updating lazycell v1.2.1 -> v1.3.0 Updating libgit2-sys v0.12.7+1.0.0 -> v0.12.9+1.0.1 Updating libnghttp2-sys v0.1.2 -> v0.1.4+1.41.0 Updating libssh2-sys v0.2.14 -> v0.2.18 Updating libz-sys v1.0.25 -> v1.0.27 Updating linked-hash-map v0.5.2 -> v0.5.3 Updating log v0.4.8 -> v0.4.11 Updating lzma-sys v0.1.14 -> v0.1.16 Updating macro-utils v0.1.2 -> v0.1.3 Updating maplit v1.0.1 -> v1.0.2 Updating mdbook v0.4.0 -> v0.4.2 Updating memoffset v0.5.1 -> v0.5.5 Updating mio-named-pipes v0.1.6 -> v0.1.7 Updating mio-uds v0.6.7 -> v0.6.8 Updating mio v0.6.16 -> v0.6.22 Updating miow v0.3.3 -> v0.3.5 Updating net2 v0.2.33 -> v0.2.34 Updating new_debug_unreachable v1.0.3 -> v1.0.4 Updating num_cpus v1.10.1 -> v1.13.0 Updating num-integer v0.1.39 -> v0.1.43 Updating num-traits v0.2.6 -> v0.2.12 Updating once_cell v1.1.0 -> v1.4.0 Updating opener v0.4.0 -> v0.4.1 Updating openssl-src v111.9.0+1.1.1g -> v111.10.2+1.1.1g Updating openssl-sys v0.9.54 -> v0.9.58 Updating openssl v0.10.25 -> v0.10.30 Updating open v1.2.1 -> v1.4.0 Updating packed_simd v0.3.1 -> v0.3.3 Updating pest v2.1.0 -> v2.1.3 Updating pkg-config v0.3.17 -> v0.3.18 Updating proc-macro2 v1.0.3 -> v1.0.19 Updating proc-macro-crate v0.1.4 -> v0.1.5 Updating proc-macro-error v0.2.6 -> v1.0.4 Updating psm v0.1.10 -> v0.1.11 Updating pulldown-cmark v0.7.1 -> v0.7.2 Updating punycode v0.4.0 -> v0.4.1 Updating quote v1.0.2 -> v1.0.7 Updating rayon-core v1.6.0 -> v1.7.1 Updating rayon v1.2.0 -> v1.3.1 Updating redox_syscall v0.1.56 -> v0.1.57 Updating redox_users v0.3.0 -> v0.3.4 Updating regex-syntax v0.6.17 -> v0.6.18 Updating regex v1.3.7 -> v1.3.9 Updating remove_dir_all v0.5.2 -> v0.5.3 Updating rustfix v0.5.0 -> v0.5.1 Updating ryu v1.0.0 -> v1.0.5 Updating same-file v1.0.4 -> v1.0.6 Updating schannel v0.1.16 -> v0.1.19 Updating scopeguard v1.0.0 -> v1.1.0 Updating serde_derive v1.0.106 -> v1.0.115 Updating serde_ignored v0.1.0 -> v0.1.2 Updating serde_json v1.0.40 -> v1.0.57 Updating serde_repr v0.1.5 -> v0.1.6 Updating serde v1.0.99 -> v1.0.115 Updating shell-escape v0.1.4 -> v0.1.5 Updating stable_deref_trait v1.1.0 -> v1.2.0 Updating stacker v0.1.9 -> v0.1.11 Updating structopt-derive v0.3.1 -> v0.4.9 Updating structopt v0.3.1 -> v0.3.16 Updating synstructure v0.12.1 -> v0.12.4 Updating syn v1.0.11 -> v1.0.38 Updating tar v0.4.26 -> v0.4.29 Updating tendril v0.4.0 -> v0.4.1 Updating term v0.6.0 -> v0.6.1 Updating thiserror-impl v1.0.5 -> v1.0.20 Updating thiserror v1.0.5 -> v1.0.20 Updating time v0.1.42 -> v0.1.43 Updating tokio-codec v0.1.1 -> v0.1.2 Updating tokio-current-thread v0.1.6 -> v0.1.7 Updating tokio-executor v0.1.9 -> v0.1.10 Updating tokio-fs v0.1.6 -> v0.1.7 Updating tokio-io v0.1.12 -> v0.1.13 Updating tokio-process v0.2.4 -> v0.2.5 Updating tokio-reactor v0.1.11 -> v0.1.12 Updating tokio-signal v0.2.7 -> v0.2.9 Updating tokio-sync v0.1.7 -> v0.1.8 Updating tokio-tcp v0.1.3 -> v0.1.4 Updating tokio-threadpool v0.1.17 -> v0.1.18 Updating tokio-timer v0.2.12 -> v0.2.13 Updating tokio-udp v0.1.5 -> v0.1.6 Updating tokio-uds v0.2.5 -> v0.2.7 Updating toml v0.5.3 -> v0.5.6 Updating tracing-attributes v0.1.9 -> v0.1.10 Updating tracing-core v0.1.12 -> v0.1.14 Updating tracing-subscriber v0.2.10 -> v0.2.11 Updating tracing v0.1.18 -> v0.1.19 Updating ucd-parse v0.1.4 -> v0.1.8 Updating ucd-trie v0.1.1 -> v0.1.3 Updating unicode-normalization v0.1.12 -> v0.1.13 Updating unicode-script v0.5.1 -> v0.5.2 Updating unicode-width v0.1.6 -> v0.1.8 Updating unicode-xid v0.2.0 -> v0.2.1 Updating url v2.1.0 -> v2.1.1 Updating utf-8 v0.7.2 -> v0.7.5 Updating vcpkg v0.2.8 -> v0.2.10 Updating vec_map v0.8.1 -> v0.8.2 Updating version_check v0.9.1 -> v0.9.2 Updating walkdir v2.2.7 -> v2.3.1 Updating winapi v0.3.8 -> v0.3.9 Updating xz2 v0.1.5 -> v0.1.6 Updating yaml-merge-keys v0.4.0 -> v0.4.1 Updating yaml-rust v0.4.3 -> v0.4.4 --- Cargo.lock | 1137 +++++++++++++++++++++++++++------------------------- 1 file changed, 597 insertions(+), 540 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c767817ae563..3cb73a340492f 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 = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if", + "cloudabi 0.0.3", + "libc", + "redox_syscall", + "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 = "0e136c1904604defe99ce5fd71a28d473fa60a12255d511aa78a9ddf11237aeb" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ "cfg-if", - "cloudabi", + "cloudabi 0.1.0", + "instant", "libc", "redox_syscall", - "smallvec 1.4.0", - "winapi 0.3.8", + "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,7 +4100,7 @@ dependencies = [ name = "rustdoc" version = "0.0.0" dependencies = [ - "itertools 0.8.0", + "itertools 0.8.2", "minifier", "pulldown-cmark", "rustc-rayon", @@ -4068,9 +4122,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 +4149,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 +4174,7 @@ dependencies = [ "serde", "serde_json", "structopt", - "term 0.6.0", + "term 0.6.1", "thiserror", "toml", "unicode-segmentation", @@ -4130,27 +4184,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 +4213,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 +4247,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 +4267,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 +4287,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 +4319,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 +4330,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 +4363,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 +4385,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 +4404,7 @@ dependencies = [ "cfg-if", "libc", "psm", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -4423,19 +4474,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 +4516,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 +4527,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 +4539,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 +4560,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 +4584,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 +4608,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 +4634,7 @@ checksum = "ee72ec31009a42b53de9a6b7d8f462b493ab3b1e4767bda1fcdbb52127f13b6c" dependencies = [ "getopts", "libc", - "term 0.6.0", + "term 0.6.1", ] [[package]] @@ -4597,18 +4648,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 +4691,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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" + [[package]] name = "tokio" version = "0.1.22" @@ -4675,9 +4731,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 +4742,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 +4752,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 +4773,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 +4797,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 +4811,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 +4844,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 +4871,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 +4885,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 +4902,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 +4914,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 +4929,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 +4947,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 +4967,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 +4978,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 +5010,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 +5020,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 +5051,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 +5082,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 +5093,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 +5135,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 +5147,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 +5159,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" @@ -5124,9 +5181,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "vte" @@ -5139,12 +5196,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 +5224,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 +5250,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 +5292,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 +5318,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", ] From 10f4aa57ffb0dc32d7610fbdd5b1596b4723ec4a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 17 Aug 2020 15:13:04 -0400 Subject: [PATCH 02/64] Update license check post-cargo update --- src/tools/tidy/src/deps.rs | 45 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 1f988f7d81b72..9ed3c6e0d98ba 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -25,24 +25,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 +69,8 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "bitflags", "block-buffer", "block-padding", - "byte-tools", "byteorder", + "byte-tools", "cc", "cfg-if", "chalk-derive", @@ -103,6 +103,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "hermit-abi", "humantime", "indexmap", + "instant", "itertools", "jobserver", "kernel32-sys", @@ -112,13 +113,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 +234,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"); From 4f2d8f31b281fa86798eb7c6306782be1ed19c7c Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 17 Aug 2020 16:07:09 -0700 Subject: [PATCH 03/64] Resolve licensing by updating tinyvec 0.3.3 -> 0.3.4 Per https://github.com/rust-lang/rust/pull/75555#issuecomment-675090858 Zlib license might be OK. "OR Apache-2.0 OR MIT" definitely is. unicode-normalization depends on this and rustc_parse, clippy, and many other things depend on unicode-normalization. --- Cargo.lock | 4 ++-- src/tools/tidy/src/deps.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cb73a340492f..977733ffac5ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4701,9 +4701,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" [[package]] name = "tokio" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 9ed3c6e0d98ba..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 From f9b80059d4405128153bade03276fdef221d3efe Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 17 Aug 2020 17:09:36 -0700 Subject: [PATCH 04/64] Downgrade version_check 0.9.2 -> 0.9.1 0.9.2 is a breaking change to the #[cfg(version)] test in src/test/ui/feature-gates/feature-gate-config-version.* Let's downgrade for now. --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 977733ffac5ea..985dbb046d0c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5181,9 +5181,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" [[package]] name = "vte" From 4400c8fef5bd99735005a3c4f626b57bab6484e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 18 Aug 2020 12:55:54 -0700 Subject: [PATCH 05/64] Fix asm compiler flags change from cmake 0.1.44 cmake-rs@8141f0e changed the logic for handling asm compiler flags. This change was pulled in with the cmake 0.1.42 -> 0.1.44 update. This introduced two new flags to the LLVM build, breaking it: "-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_ASM_COMPILER=/usr/bin/cc" This patch should resolve the breakage by handling it in bootstrap. --- src/bootstrap/native.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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()); From 23c3459f1e2d9502fedb627b0a6b2a7764aacf7c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 18 Aug 2020 11:45:40 -0700 Subject: [PATCH 06/64] Don't panic in Vec::shrink_to_fit --- library/alloc/src/vec.rs | 5 +++- src/test/codegen/vec-shrink-panic.rs | 36 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/test/codegen/vec-shrink-panic.rs 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/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); +} From 0fa8af96c9f861c6a6a2ab843543ff61b26cf78b Mon Sep 17 00:00:00 2001 From: Ryan Scheel Date: Sat, 1 Aug 2020 22:56:25 -0700 Subject: [PATCH 07/64] See also X-Link mem::{swap, take, replace} --- library/core/src/mem/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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"] From 28660fcc1d2cb6b28ec0ae8c697d392ad7f9a902 Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Sun, 2 Aug 2020 14:57:19 +0200 Subject: [PATCH 08/64] docs(marker/copy): clarify that `&T` is also `Copy` In the current documentation about the `Copy` marker trait, there is a section about "additional implementors", which list additional implementors of the `Copy` trait. The fact that shared references are also `Copy` is mixed with another point, which makes it hard to recognize and make it seem not as important. This clarifies the fact that shared references are also `Copy`, by mentioning it as a separate item in the list of "additional implementors". --- library/core/src/marker.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 56dddee7b7799..255f4474ea07d 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -347,9 +347,8 @@ pub trait StructuralEq { /// * Tuple types, if each component also implements `Copy` (e.g., `()`, `(i32, bool)`) /// * Closure types, if they capture no value from the environment /// or if all such captured values implement `Copy` themselves. -/// Note that variables captured by shared reference always implement `Copy` -/// (even if the referent doesn't), -/// while variables captured by mutable reference never implement `Copy`. +/// * Variables captured by shared reference (e.g. `&T`) implement `Copy`, even if the referent (`T`) doesn't, +/// while variables captured by mutable reference (e.g. `&mut T`) never implement `Copy`. /// /// [`Vec`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html From 06092d4b65bdeb9ab49d1e130f3d7350a9a01311 Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Sun, 16 Aug 2020 20:03:34 +0200 Subject: [PATCH 09/64] docs(marker/copy): provide example for `&T` being `Copy` In the current documentation about the `Copy` marker trait, there is a section with examples of structs that can implement `Copy`. Currently there is no example for showing that shared references (`&T`) are also `Copy`. It is worth to have a dedicated example for `&T` being `Copy`, because shared references are an integral part of the language and it being `Copy` is not as intuitive as other types that share this behaviour like `i32` or `bool`. The example picks up on the previous non-`Copy` struct and shows that structs can be `Copy`, even when they hold a shared reference to a non-`Copy` type. --- library/core/src/marker.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 255f4474ea07d..1458d25d7f7d2 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -315,6 +315,18 @@ 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 struct 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; +/// 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 @@ -347,8 +359,9 @@ pub trait StructuralEq { /// * Tuple types, if each component also implements `Copy` (e.g., `()`, `(i32, bool)`) /// * Closure types, if they capture no value from the environment /// or if all such captured values implement `Copy` themselves. -/// * Variables captured by shared reference (e.g. `&T`) implement `Copy`, even if the referent (`T`) doesn't, -/// while variables captured by mutable reference (e.g. `&mut T`) never implement `Copy`. +/// Note that variables captured by shared reference always implement `Copy` +/// (even if the referent doesn't), +/// while variables captured by mutable reference never implement `Copy`. /// /// [`Vec`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html @@ -539,7 +552,7 @@ macro_rules! impls { /// For a more in-depth explanation of how to use `PhantomData`, please see /// [the Nomicon](../../nomicon/phantom-data.html). /// -/// # A ghastly note 👻👻👻 +/// # A ghastly note /// /// Though they both have scary names, `PhantomData` and 'phantom types' are /// related, but not identical. A phantom type parameter is simply a type From 8c7b1f6cbc428a2e00d1b9825fd0edf68ac2a673 Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Sun, 16 Aug 2020 20:17:28 +0200 Subject: [PATCH 10/64] rephrase: struct -> type Co-authored-by: Joshua Nelson --- library/core/src/marker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 1458d25d7f7d2..b698cbd7802de 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -315,7 +315,7 @@ 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 struct can be `Copy`, even when it holds +/// 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: From b9354c1cec166f2aad63adc8061066c8a47afcef Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Sun, 16 Aug 2020 20:19:21 +0200 Subject: [PATCH 11/64] add back emojis that have been removed accidentally Co-authored-by: Joshua Nelson --- library/core/src/marker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b698cbd7802de..a9f8e332d2851 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -552,7 +552,7 @@ macro_rules! impls { /// For a more in-depth explanation of how to use `PhantomData`, please see /// [the Nomicon](../../nomicon/phantom-data.html). /// -/// # A ghastly note +/// # A ghastly note 👻👻👻 /// /// Though they both have scary names, `PhantomData` and 'phantom types' are /// related, but not identical. A phantom type parameter is simply a type From 0bb35ff770c1702ce89b321f6338465e6d590dc7 Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Sun, 16 Aug 2020 22:15:59 +0200 Subject: [PATCH 12/64] add empty line above code block Co-authored-by: Poliorcetics --- library/core/src/marker.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index a9f8e332d2851..85e2e3830a513 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -319,6 +319,7 @@ pub trait StructuralEq { /// 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; From 594c6b0a612cd0ecbd9b4e4f5d03cd999c776149 Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Sun, 16 Aug 2020 22:25:59 +0200 Subject: [PATCH 13/64] docs: add `derive` for struct Code blocks in doc comments are compiled and run, so we show `Copy` works in this example. Co-authored-by: Poliorcetics --- library/core/src/marker.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 85e2e3830a513..f113f9392301a 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -323,6 +323,7 @@ pub trait StructuralEq { /// ``` /// # #![allow(dead_code)] /// # struct PointList; +/// #[derive(Copy, Clone)] /// struct PointListWrapper<'a> { /// point_list_ref: &'a PointList, /// } From f6f733c99a5716c1c9c7d08260541c44b8faf6ae Mon Sep 17 00:00:00 2001 From: Jan Riemer Date: Tue, 18 Aug 2020 18:40:19 +0200 Subject: [PATCH 14/64] docs: add another `derive` for `Copy`able struct This adds another `derive` for a `Copy`able struct, so that we are consistent with `derive` annotations. --- library/core/src/marker.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index f113f9392301a..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, From dd6ff5fa7d57bc6b6d65d6b9a499eb3e6e1942c8 Mon Sep 17 00:00:00 2001 From: Jack Champagne Date: Thu, 13 Aug 2020 16:58:50 -0400 Subject: [PATCH 15/64] Fix documentation error --- library/core/src/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 2250b11e35457cf29f984fb25de8d9b2c9da0333 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sat, 15 Aug 2020 13:18:54 +1000 Subject: [PATCH 16/64] Add test demonstrating the issue. --- .../ui/lint/clashing-extern-fn-recursion.rs | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/test/ui/lint/clashing-extern-fn-recursion.rs 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..51bfd2032838c --- /dev/null +++ b/src/test/ui/lint/clashing-extern-fn-recursion.rs @@ -0,0 +1,117 @@ +// 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 Reffy1<'a>, + } + + struct Reffy2<'a> { + reffy: &'a Reffy2<'a>, + } + + extern "C" { + fn reffy_once_removed(reffy: Reffy1); + } + } + mod b { + #[repr(C)] + struct Reffy1<'a> { + reffy: &'a Reffy1<'a>, + } + + struct Reffy2<'a> { + reffy: &'a Reffy2<'a>, + } + + extern "C" { + fn reffy_once_removed(reffy: Reffy1); + } + } +} From ae14024af9ef025b5580d01f7d167511c17fd740 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sat, 15 Aug 2020 15:05:18 +1000 Subject: [PATCH 17/64] Fix stack overflow for recursive types. Adds a seen set to structurally_same_type to avoid recursing indefinitely when a reference or pointer member introduces a cycle in the visited types. --- src/librustc_lint/builtin.rs | 289 ++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 102 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 36eb272cdfc8d..c0cb6154bf446 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2153,44 +2153,99 @@ 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 - }; + // In order to avoid endlessly recursing on recursive types, we maintain a "seen" set. + // We'll need to store every combination of types we encounter anyway, so we also memoize + // the result. + struct SeenSet<'tcx>(FxHashMap<(Ty<'tcx>, Ty<'tcx>), Option>); + + enum SeenSetResult { + /// We've never seen this combination of types. + Unseen, + /// We've seen this combination of types, but are still computing the result. + Computing, + /// We've seen this combination of types, and have already computed the result. + Computed(bool), + } + + impl<'tcx> SeenSet<'tcx> { + fn new() -> Self { + SeenSet(FxHashMap::default()) + } + /// Mark (a, b) as `Computing`. + fn mark_computing(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + self.0.insert((a, b), None); + } + /// Mark (a, b) as `Computed(result)`. + fn mark_computed(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, result: bool) { + *self.0.get_mut(&(a, b)).expect("Missing prior call to mark_computing") = + Some(result); + } + fn get(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> SeenSetResult { + match self.0.get(&(a, b)) { + None => SeenSetResult::Unseen, + Some(None) => SeenSetResult::Computing, + Some(Some(b)) => SeenSetResult::Computed(*b), + } + } + } + fn structurally_same_type_impl<'tcx>( + seen_types: &mut SeenSet<'tcx>, + cx: &LateContext<'tcx>, + a: Ty<'tcx>, + b: Ty<'tcx>, + ckind: CItemKind, + ) -> bool { + debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b); + match seen_types.get(a, b) { + // If we've already computed the result, just return the memoized result. + SeenSetResult::Computed(result) => result, + // We are already in the process of computing structural sameness for this type, + // meaning we've found a cycle. The types are structurally same, then. + SeenSetResult::Computing => true, + // We haven't seen this combination of types at all -- compute their sameness. + SeenSetResult::Unseen => { + seen_types.mark_computing(a, b); + let tcx = cx.tcx; + let result = 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(..)) + }; - #[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) + 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) && 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 +2253,108 @@ 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) - } + } 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 + && structurally_same_type_impl( + seen_types, cx, a_const.ty, b_const.ty, ckind, + ) + && 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 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) + } + } + // 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), + } + }; + seen_types.mark_computed(a, b, result); + result } - // 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 = SeenSet::new(); + structurally_same_type_impl(&mut seen_types, cx, a, b, ckind) } } From 94f294e347a196b68938029b0c7ea99c9884fccc Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sun, 16 Aug 2020 10:26:45 +1000 Subject: [PATCH 18/64] Actually introduce a cycle in Reffy test. --- src/test/ui/lint/clashing-extern-fn-recursion.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/ui/lint/clashing-extern-fn-recursion.rs b/src/test/ui/lint/clashing-extern-fn-recursion.rs index 51bfd2032838c..ab0fd0a2e7085 100644 --- a/src/test/ui/lint/clashing-extern-fn-recursion.rs +++ b/src/test/ui/lint/clashing-extern-fn-recursion.rs @@ -89,28 +89,30 @@ mod ref_recursion_once_removed { mod a { #[repr(C)] struct Reffy1<'a> { - reffy: &'a Reffy1<'a>, + reffy: &'a Reffy2<'a>, } struct Reffy2<'a> { - reffy: &'a 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 Reffy1<'a>, + reffy: &'a Reffy2<'a>, } struct Reffy2<'a> { - reffy: &'a Reffy2<'a>, + reffy: &'a Reffy1<'a>, } extern "C" { + #[allow(improper_ctypes)] fn reffy_once_removed(reffy: Reffy1); } } From c3075e0ff439eb91a335570271574c523bc8f81f Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sun, 16 Aug 2020 10:41:59 +1000 Subject: [PATCH 19/64] Remove unnecessary rebinding of def ids. --- src/librustc_lint/builtin.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c0cb6154bf446..61b86118dd65b 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2228,18 +2228,15 @@ impl ClashingExternDeclarations { }; match (a_kind, b_kind) { - (Adt(_, a_substs), Adt(_, b_substs)) => { + (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); - 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) + // 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, .. }, @@ -2253,9 +2250,6 @@ impl ClashingExternDeclarations { ) }, ) - } else { - unreachable!() - } } (Array(a_ty, a_const), Array(b_ty, b_const)) => { // For arrays, we also check the constness of the type. From 996667d8874411b0c5ef2b5179930b9cbbc21671 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sun, 16 Aug 2020 10:47:35 +1000 Subject: [PATCH 20/64] Remove structural equiv check for Array const. --- src/librustc_lint/builtin.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 61b86118dd65b..f78b6f3c22032 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2254,9 +2254,6 @@ impl ClashingExternDeclarations { (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_const.ty, b_const.ty, ckind, - ) && structurally_same_type_impl( seen_types, cx, a_ty, b_ty, ckind, ) From 5ae1b0f51d7da1257333918ffdc6b40fca0c938d Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sun, 16 Aug 2020 10:50:20 +1000 Subject: [PATCH 21/64] Reduce indentation by replacing match arm w/ early return. --- src/librustc_lint/builtin.rs | 243 +++++++++++++++++------------------ 1 file changed, 118 insertions(+), 125 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f78b6f3c22032..be81e94aef844 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2198,45 +2198,46 @@ impl ClashingExternDeclarations { debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b); match seen_types.get(a, b) { // If we've already computed the result, just return the memoized result. - SeenSetResult::Computed(result) => result, + SeenSetResult::Computed(result) => return result, // We are already in the process of computing structural sameness for this type, // meaning we've found a cycle. The types are structurally same, then. - SeenSetResult::Computing => true, - // We haven't seen this combination of types at all -- compute their sameness. - SeenSetResult::Unseen => { - seen_types.mark_computing(a, b); - let tcx = cx.tcx; - let result = 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 - }; + SeenSetResult::Computing => return true, + // We haven't seen this combination of types at all -- continue on to computing + // their sameness. + SeenSetResult::Unseen => (), + } + seen_types.mark_computing(a, b); + let tcx = cx.tcx; + let result = 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(..)) - }; + #[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_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); + 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) + // 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, .. }, @@ -2250,99 +2251,91 @@ impl ClashingExternDeclarations { ) }, ) - } - (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 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) - } - } - // 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), + } + (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 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) } - }; - seen_types.mark_computed(a, b, result); - result + } + // 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), } - } + }; + seen_types.mark_computed(a, b, result); + result } let mut seen_types = SeenSet::new(); structurally_same_type_impl(&mut seen_types, cx, a, b, ckind) From ea4014b6938f9202d62e3d48a7a4783b472dcd21 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sun, 16 Aug 2020 11:01:14 +1000 Subject: [PATCH 22/64] Don't memoize seen types. That cache is unlikely to be particularly useful within a single invocation of structurally_same_type, especially compared to memoizing results across _all_ invocations of that function. --- src/librustc_lint/builtin.rs | 60 ++++++------------------------------ 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index be81e94aef844..3367aced74dd4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2153,62 +2153,22 @@ impl ClashingExternDeclarations { b: Ty<'tcx>, ckind: CItemKind, ) -> bool { - // In order to avoid endlessly recursing on recursive types, we maintain a "seen" set. - // We'll need to store every combination of types we encounter anyway, so we also memoize - // the result. - struct SeenSet<'tcx>(FxHashMap<(Ty<'tcx>, Ty<'tcx>), Option>); - - enum SeenSetResult { - /// We've never seen this combination of types. - Unseen, - /// We've seen this combination of types, but are still computing the result. - Computing, - /// We've seen this combination of types, and have already computed the result. - Computed(bool), - } - - impl<'tcx> SeenSet<'tcx> { - fn new() -> Self { - SeenSet(FxHashMap::default()) - } - /// Mark (a, b) as `Computing`. - fn mark_computing(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { - self.0.insert((a, b), None); - } - /// Mark (a, b) as `Computed(result)`. - fn mark_computed(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, result: bool) { - *self.0.get_mut(&(a, b)).expect("Missing prior call to mark_computing") = - Some(result); - } - fn get(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> SeenSetResult { - match self.0.get(&(a, b)) { - None => SeenSetResult::Unseen, - Some(None) => SeenSetResult::Computing, - Some(Some(b)) => SeenSetResult::Computed(*b), - } - } - } fn structurally_same_type_impl<'tcx>( - seen_types: &mut SeenSet<'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); - match seen_types.get(a, b) { - // If we've already computed the result, just return the memoized result. - SeenSetResult::Computed(result) => return result, - // We are already in the process of computing structural sameness for this type, - // meaning we've found a cycle. The types are structurally same, then. - SeenSetResult::Computing => return true, - // We haven't seen this combination of types at all -- continue on to computing - // their sameness. - SeenSetResult::Unseen => (), + if seen_types.contains(&(a, b)) { + // We've encountered a cycle. There's no point going any further -- the types are + // structurally the same. + return true; } - seen_types.mark_computing(a, b); + seen_types.insert((a, b)); let tcx = cx.tcx; - let result = if a == b || rustc_middle::ty::TyS::same_type(a, b) { + if a == b || rustc_middle::ty::TyS::same_type(a, b) { // All nominally-same types are structurally same, too. true } else { @@ -2333,11 +2293,9 @@ impl ClashingExternDeclarations { // uninitialised memory. _ => compare_layouts(a, b), } - }; - seen_types.mark_computed(a, b, result); - result + } } - let mut seen_types = SeenSet::new(); + let mut seen_types = FxHashSet::default(); structurally_same_type_impl(&mut seen_types, cx, a, b, ckind) } } From a552b02f33c44d508d4d8b29dee10758558d4e43 Mon Sep 17 00:00:00 2001 From: jumbatm Date: Sun, 16 Aug 2020 17:14:09 +1000 Subject: [PATCH 23/64] Avoid double hashset lookup. Co-authored-by: Bastian Kauschke --- src/librustc_lint/builtin.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3367aced74dd4..42033c48dfd01 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2161,12 +2161,11 @@ impl ClashingExternDeclarations { ckind: CItemKind, ) -> bool { debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b); - if seen_types.contains(&(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; } - seen_types.insert((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. From 2ee3426a1d34a3ccc0ec40afd137081e95d55498 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sun, 16 Aug 2020 18:04:14 +1000 Subject: [PATCH 24/64] Also accept Refs for is_primitive_or_pointer --- src/librustc_lint/builtin.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 42033c48dfd01..2fe213fc40ca8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2184,8 +2184,9 @@ impl ClashingExternDeclarations { }; #[allow(rustc::usage_of_ty_tykind)] - let is_primitive_or_pointer = - |kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..)); + let is_primitive_or_pointer = |kind: &ty::TyKind<'_>| { + kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..)) + }; match (a_kind, b_kind) { (Adt(a_def, a_substs), Adt(b_def, b_substs)) => { @@ -2274,8 +2275,8 @@ impl ClashingExternDeclarations { // 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. + // 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) => { From 5e21ac2988e2d5718d71135e79975dd42f1286b7 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Tue, 18 Aug 2020 02:00:35 +1000 Subject: [PATCH 25/64] Wrap recursion in `ensure_sufficient_stack`. --- src/librustc_lint/builtin.rs | 179 ++++++++++++++++++----------------- 1 file changed, 91 insertions(+), 88 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2fe213fc40ca8..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}; @@ -2188,16 +2189,17 @@ impl ClashingExternDeclarations { kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..)) }; - 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); + 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) + // 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, .. }, @@ -2211,88 +2213,89 @@ impl ClashingExternDeclarations { ) }, ) - } - (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| { + } + (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) - }) - } - // 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) } + (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(); From 9930c8bf6a573a5bd3c9e81309471ba05442afe2 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Mon, 17 Aug 2020 22:17:14 +0200 Subject: [PATCH 26/64] Move to intra doc links for keyword documentation --- library/std/src/keyword_docs.rs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) 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 {} From 10dbfabe1609bd88ca50064c1a98afc6d61dfd68 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 19:51:09 -0400 Subject: [PATCH 27/64] Resolve true and false as booleans --- .../passes/collect_intra_doc_links.rs | 25 +++++++++++++------ src/test/rustdoc/intra-doc-link-true-false.rs | 10 ++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 src/test/rustdoc/intra-doc-link-true-false.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index d4d6a8119c316..edfe8c05c6db9 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -222,11 +222,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 +239,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,7 +269,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }) .ok_or(ErrorKind::ResolutionFailure)?; - if let Some(prim) = is_primitive(&path, TypeNS) { + if let Some((path, prim)) = is_primitive(&path, TypeNS) { let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?; return cx .tcx @@ -1220,11 +1220,22 @@ 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 { 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`]. From 0cd951c78641cfd9a3788ed433558202a86c658f Mon Sep 17 00:00:00 2001 From: Tyson Nottingham Date: Mon, 17 Aug 2020 19:15:51 -0700 Subject: [PATCH 28/64] Don't emit "is not a logical operator" error outside of associative expressions Avoid showing this error where it doesn't make sense by not assuming "and" and "or" were intended to mean "&&" and "||" until after we decide to continue parsing input as an associative expression. Note that the decision of whether or not to continue parsing input as an associative expression doesn't actually depend on this assumption. Fixes #75599 --- src/librustc_parse/parser/expr.rs | 2 +- .../issue-54109-and_instead_of_ampersands.rs | 8 -- ...sue-54109-and_instead_of_ampersands.stderr | 82 ++----------------- .../issue-54109-without-witness.fixed | 8 -- .../issue-54109-without-witness.rs | 8 -- .../issue-54109-without-witness.stderr | 80 ++---------------- src/test/ui/issues/issue-75599.rs | 24 ++++++ 7 files changed, 42 insertions(+), 170 deletions(-) create mode 100644 src/test/ui/issues/issue-75599.rs 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/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 => {} + _ => {} + } +} From cf1ec819ef774fd271cfcc0cd2fefe93f65fb710 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 18 Aug 2020 13:31:23 +0200 Subject: [PATCH 29/64] Add doc examples count for --show-coverage --- src/librustdoc/html/render/cache.rs | 6 +- .../passes/calculate_doc_coverage.rs | 80 ++++++++++++++++--- src/librustdoc/passes/doc_test_lints.rs | 28 ++++--- 3 files changed, 88 insertions(+), 26 deletions(-) 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/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/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); From a7ee17ef54a63aaea8bb88d1189278d831101f1a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 18 Aug 2020 13:31:40 +0200 Subject: [PATCH 30/64] Update rustdoc-ui tests --- src/test/rustdoc-ui/coverage/basic.stdout | 14 +++++----- src/test/rustdoc-ui/coverage/doc-examples.rs | 27 +++++++++++++++++++ .../rustdoc-ui/coverage/doc-examples.stdout | 7 +++++ src/test/rustdoc-ui/coverage/empty.stdout | 14 +++++----- src/test/rustdoc-ui/coverage/enums.stdout | 14 +++++----- src/test/rustdoc-ui/coverage/exotic.stdout | 16 +++++------ src/test/rustdoc-ui/coverage/json.stdout | 2 +- src/test/rustdoc-ui/coverage/private.stdout | 14 +++++----- .../rustdoc-ui/coverage/statics-consts.stdout | 14 +++++----- src/test/rustdoc-ui/coverage/traits.stdout | 14 +++++----- 10 files changed, 85 insertions(+), 51 deletions(-) create mode 100644 src/test/rustdoc-ui/coverage/doc-examples.rs create mode 100644 src/test/rustdoc-ui/coverage/doc-examples.stdout 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% | ++-------------------------------------+------------+------------+------------+------------+------------+ From 10ed3306dd72f0464102e4925059d42611b8b485 Mon Sep 17 00:00:00 2001 From: Prabakaran Kumaresshan <4676330+nixphix@users.noreply.github.com> Date: Tue, 18 Aug 2020 22:11:20 +0530 Subject: [PATCH 31/64] Switch to intra-doc links in /src/sys/unix/ext/*.rs --- library/std/src/sys/unix/ext/fs.rs | 45 +++++++-------------- library/std/src/sys/unix/ext/net.rs | 52 ++++++++++--------------- library/std/src/sys/unix/ext/process.rs | 8 +--- library/std/src/sys/unix/ext/thread.rs | 4 +- 4 files changed, 35 insertions(+), 74 deletions(-) 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..f43869a1b2c83 100644 --- a/library/std/src/sys/unix/ext/net.rs +++ b/library/std/src/sys/unix/ext/net.rs @@ -408,10 +408,9 @@ 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 + /// [`None`]: crate::option::Option::None + /// [`Err`]: crate::result::Result::Err + /// [`read`]: io::Read::read /// /// # Examples /// @@ -453,10 +452,9 @@ 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 + /// [`None`]: crate::option::Option::None + /// [`Err`]: crate::result::Result::Err + /// [`read`]: io::Read::read /// /// # Examples /// @@ -581,8 +579,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 +848,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 +933,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,8 +967,7 @@ 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 + /// [`None`]: crate::option::Option::None /// /// # Examples /// @@ -1043,8 +1036,7 @@ impl<'a> IntoIterator for &'a UnixListener { /// /// It will never return [`None`]. /// -/// [`None`]: ../../../../std/option/enum.Option.html#variant.None -/// [`UnixListener`]: struct.UnixListener.html +/// [`None`]: crate::option::Option::None /// /// # Examples /// @@ -1205,9 +1197,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 +1276,7 @@ impl UnixDatagram { /// /// The [`connect`] method will connect the socket to a peer. /// - /// [`connect`]: #method.connect + /// [`connect`]: UnixDatagram::connect /// /// # Examples /// @@ -1432,11 +1424,10 @@ 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 + /// [`None`]: crate::option::Option::None + /// [`Err`]: crate::result::Result::Err + /// [`recv`]: UnixDatagram::recv + /// [`recv_from`]: UnixDatagram::recv_from /// /// # Examples /// @@ -1479,10 +1470,9 @@ 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 + /// [`None`]: crate::option::Option::None + /// [`send`]: UnixDatagram::send + /// [`send_to`]: UnixDatagram::send_to /// /// # Examples /// @@ -1605,8 +1595,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 From 6e1d6b8103ad29f376bacc7230de200cdc131fc9 Mon Sep 17 00:00:00 2001 From: Prabakaran Kumaresshan <4676330+nixphix@users.noreply.github.com> Date: Wed, 19 Aug 2020 06:19:35 +0530 Subject: [PATCH 32/64] resolve comments --- library/std/src/sys/unix/ext/net.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/library/std/src/sys/unix/ext/net.rs b/library/std/src/sys/unix/ext/net.rs index f43869a1b2c83..55803ddfc4323 100644 --- a/library/std/src/sys/unix/ext/net.rs +++ b/library/std/src/sys/unix/ext/net.rs @@ -408,8 +408,6 @@ impl UnixStream { /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this /// method. /// - /// [`None`]: crate::option::Option::None - /// [`Err`]: crate::result::Result::Err /// [`read`]: io::Read::read /// /// # Examples @@ -452,8 +450,6 @@ impl UnixStream { /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is /// passed to this method. /// - /// [`None`]: crate::option::Option::None - /// [`Err`]: crate::result::Result::Err /// [`read`]: io::Read::read /// /// # Examples @@ -967,8 +963,6 @@ impl UnixListener { /// The iterator will never return [`None`] and will also not yield the /// peer's [`SocketAddr`] structure. /// - /// [`None`]: crate::option::Option::None - /// /// # Examples /// /// ```no_run @@ -1036,8 +1030,6 @@ impl<'a> IntoIterator for &'a UnixListener { /// /// It will never return [`None`]. /// -/// [`None`]: crate::option::Option::None -/// /// # Examples /// /// ```no_run @@ -1424,8 +1416,6 @@ impl UnixDatagram { /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] /// is passed to this method. /// - /// [`None`]: crate::option::Option::None - /// [`Err`]: crate::result::Result::Err /// [`recv`]: UnixDatagram::recv /// [`recv_from`]: UnixDatagram::recv_from /// @@ -1470,7 +1460,6 @@ impl UnixDatagram { /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this /// method. /// - /// [`None`]: crate::option::Option::None /// [`send`]: UnixDatagram::send /// [`send_to`]: UnixDatagram::send_to /// From 688e4ec0dc0a496cfc619b17c4672f2d3df803f1 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 16 Aug 2020 16:59:43 +0300 Subject: [PATCH 33/64] Improve `align_offset` at opt-level <= 1 At opt-level <= 1, the methods such as `wrapping_mul` are not being inlined, causing significant bloating and slowdowns of the implementation at these optimisation levels. With use of these intrinsics, the codegen of this function at -Copt_level=1 is the same as it is at -Copt_level=3. --- library/core/src/ptr/mod.rs | 55 +++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5f028f9ea76ca..78308f97461c1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1166,6 +1166,10 @@ 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: @@ -1175,7 +1179,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { /// /// 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,17 +1210,18 @@ 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); + // SAFETY: `a` is a power-of-two, hence non-zero. + let a_minus_one = unsafe { unchecked_sub(a, 1) }; let pmoda = p as usize & a_minus_one; if pmoda == 0 { @@ -1228,16 +1235,18 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // elements will ever align the pointer. !0 } else { - a.wrapping_sub(pmoda) + wrapping_sub(a, pmoda) }; } 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 +1254,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 +1268,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. From 07f70cd4235f9a8a4962964b9877bff7c27b3914 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 16 Aug 2020 17:10:54 +0300 Subject: [PATCH 34/64] Improve codegen of align_offset when stride == 1 Previously checking for `pmoda == 0` would get LLVM to generate branchy code, when, for `stride = 1` the offset can be computed without such a branch by doing effectively a `-p % a`. For well-known (constant) alignments, with the new ordering of these conditionals, we end up generating 2 to 3 cheap instructions on x86_64: movq %rdi, %rax negl %eax andl $7, %eax instead of 5+ as previously. For unknown alignments the new code also generates just 3 instructions: negq %rdi leaq -1(%rsi), %rax andq %rdi, %rax --- library/core/src/ptr/mod.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 78308f97461c1..68b5d1df71cb2 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1172,7 +1172,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { /// 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) @@ -1220,23 +1220,21 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { } let stride = mem::size_of::(); - // SAFETY: `a` is a power-of-two, hence non-zero. + // SAFETY: `a` is a power-of-two, therefore non-zero. let a_minus_one = unsafe { unchecked_sub(a, 1) }; - let pmoda = p as usize & a_minus_one; + 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 { - wrapping_sub(a, 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; From c4cc5f7520a3d085d18472e0dfb8563f9ec81922 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 6 Jul 2020 16:11:12 +0200 Subject: [PATCH 35/64] Add checks for doc alias on which item it's used --- src/librustdoc/visit_ast.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ac9f839600baf..e3a8e0e7495f0 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -31,6 +31,27 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec { std::iter::once(crate_name).chain(relative).collect() } +fn check_doc_alias_attrs( + attrs: &[ast::Attribute], + item_kind: &str, + diagnostic: &::rustc_errors::Handler, +) { + for attr in attrs { + if let Some(attr) = attr.meta() { + if let Some(list) = attr.meta_item_list() { + for meta in list { + if meta.check_name(sym::alias) { + diagnostic.span_err( + meta.span(), + &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", item_kind), + ); + } + } + } + } + } +} + // Also, is there some reason that this doesn't use the 'visit' // framework from syntax?. @@ -387,6 +408,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match item.kind { hir::ItemKind::ForeignMod(ref fm) => { + check_doc_alias_attrs(&item.attrs, "extern block", self.cx.sess().diagnostic()); for item in fm.items { self.visit_foreign_item(item, None, om); } @@ -561,6 +583,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self_ty, ref items, } => { + check_doc_alias_attrs( + &item.attrs, + "implementation block", + self.cx.sess().diagnostic(), + ); // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. if !self.inlining && of_trait.is_none() { From d598d122692b3a35e43fb6a14420e740cc6b83de Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 6 Jul 2020 16:11:32 +0200 Subject: [PATCH 36/64] Add more tests for doc alias --- .../check-doc-alias-attr-location.rs | 13 ++++++++++++ .../check-doc-alias-attr-location.stderr | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/test/rustdoc-ui/check-doc-alias-attr-location.rs create mode 100644 src/test/rustdoc-ui/check-doc-alias-attr-location.stderr 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..e209da6e2c3ae --- /dev/null +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs @@ -0,0 +1,13 @@ +#![feature(doc_alias)] + +pub struct Bar; +pub trait Foo {} + +#[doc(alias = "foo")] //~ ERROR +extern {} + +#[doc(alias = "bar")] //~ ERROR +impl Bar {} + +#[doc(alias = "foobar")] //~ ERROR +impl Foo for Bar {} 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..74adc1bc07399 --- /dev/null +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -0,0 +1,20 @@ +error: `#[doc(alias = "...")]` isn't allowed on extern block + --> $DIR/check-doc-alias-attr-location.rs:6:7 + | +LL | #[doc(alias = "foo")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:9:7 + | +LL | #[doc(alias = "bar")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:12:7 + | +LL | #[doc(alias = "foobar")] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + From e700c5cc7dc50b04aee93afa5493a9d80ebb4c49 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Jul 2020 21:04:54 +0200 Subject: [PATCH 37/64] Add doc(alias) attribute checks for associated consts and associated types --- src/librustdoc/visit_ast.rs | 30 +++++++++++++++++-- .../check-doc-alias-attr-location.rs | 16 ++++++++-- .../check-doc-alias-attr-location.stderr | 20 ++++++++++--- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e3a8e0e7495f0..b8bb3d703dd08 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -591,8 +591,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. if !self.inlining && of_trait.is_none() { - let items = - items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); + let items = items + .iter() + .map(|item| { + let item = self.cx.tcx.hir().impl_item(item.id); + self.check_impl_doc_alias_attr(item); + item + }) + .collect(); let i = Impl { unsafety, polarity, @@ -608,11 +614,31 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { vis: &item.vis, }; om.impls.push(i); + } else if of_trait.is_some() { + for item in items.iter() { + self.check_impl_doc_alias_attr(self.cx.tcx.hir().impl_item(item.id)); + } } } } } + fn check_impl_doc_alias_attr(&self, item: &hir::ImplItem<'_>) { + match item.kind { + hir::ImplItemKind::Const(_, _) => check_doc_alias_attrs( + &item.attrs, + "const in implementation block", + self.cx.sess().diagnostic(), + ), + hir::ImplItemKind::TyAlias(_) => check_doc_alias_attrs( + &item.attrs, + "type alias in implementation block", + self.cx.sess().diagnostic(), + ), + hir::ImplItemKind::Fn(_, _) => {} + } + } + fn visit_foreign_item( &mut self, item: &'tcx hir::ForeignItem<'_>, diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.rs b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs index e209da6e2c3ae..8a97cf7f8e892 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.rs +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs @@ -1,13 +1,23 @@ #![feature(doc_alias)] pub struct Bar; -pub trait Foo {} +pub trait Foo { + type X; + fn foo() -> Self::X; +} #[doc(alias = "foo")] //~ ERROR extern {} #[doc(alias = "bar")] //~ ERROR -impl Bar {} +impl Bar { + #[doc(alias = "const")] //~ ERROR + const A: u32 = 0; +} #[doc(alias = "foobar")] //~ ERROR -impl Foo for Bar {} +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 index 74adc1bc07399..5fe943debdeb0 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -1,20 +1,32 @@ error: `#[doc(alias = "...")]` isn't allowed on extern block - --> $DIR/check-doc-alias-attr-location.rs:6:7 + --> $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:9:7 + --> $DIR/check-doc-alias-attr-location.rs:12:7 | LL | #[doc(alias = "bar")] | ^^^^^^^^^^^^^ +error: `#[doc(alias = "...")]` isn't allowed on const in implementation block + --> $DIR/check-doc-alias-attr-location.rs:14:11 + | +LL | #[doc(alias = "const")] + | ^^^^^^^^^^^^^^^ + error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:12:7 + --> $DIR/check-doc-alias-attr-location.rs:18:7 | LL | #[doc(alias = "foobar")] | ^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +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 5 previous errors From 6a326a4d68177faedc70c326118f4e2b13d82d05 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Jul 2020 21:50:28 +0200 Subject: [PATCH 38/64] Remove invalid #[doc(alias)] from doc-alias search-index test --- src/test/rustdoc-js/doc-alias.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/rustdoc-js/doc-alias.rs b/src/test/rustdoc-js/doc-alias.rs index 84c638a199507..28a720d06e8d3 100644 --- a/src/test/rustdoc-js/doc-alias.rs +++ b/src/test/rustdoc-js/doc-alias.rs @@ -12,11 +12,7 @@ impl Struct { } 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")] From 917ef1e21ccd10bbdd79b9c50de58ef5473115f5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 1 Aug 2020 16:22:20 +0200 Subject: [PATCH 39/64] Put back attributes check pass in rustdoc --- src/librustdoc/core.rs | 4 ++++ src/test/rustdoc-ui/check-doc-alias-attr.rs | 10 ++++++++++ .../rustdoc-ui/check-doc-alias-attr.stderr | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/test/rustdoc-ui/check-doc-alias-attr.rs create mode 100644 src/test/rustdoc-ui/check-doc-alias-attr.stderr 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/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 + From f974efcc6946c0e42a72f347d6b4bbdfcc51ddbe Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 1 Aug 2020 17:37:30 +0200 Subject: [PATCH 40/64] Move #[doc(alias)] attribute checks in rustc --- src/librustc_passes/check_attr.rs | 30 +++++++++- src/librustdoc/visit_ast.rs | 57 +------------------ .../check-doc-alias-attr-location.stderr | 12 ++-- src/test/ui/check-doc-alias-attr-location.rs | 24 ++++++++ .../ui/check-doc-alias-attr-location.stderr | 32 +++++++++++ 5 files changed, 92 insertions(+), 63 deletions(-) create mode 100644 src/test/ui/check-doc-alias-attr-location.rs create mode 100644 src/test/ui/check-doc-alias-attr-location.stderr diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index 59edf21b733c9..7c17c289a56fa 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,32 @@ impl CheckAttrVisitor<'tcx> { .emit(); return false; } + if let Some(err) = match target { + Target::Impl => Some("implementation block"), + Target::ForeignMod => Some("extern block"), + Target::AssocConst | 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(if target == Target::AssocConst { + "const in implementation block" + } else { + "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/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index b8bb3d703dd08..ac9f839600baf 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -31,27 +31,6 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec { std::iter::once(crate_name).chain(relative).collect() } -fn check_doc_alias_attrs( - attrs: &[ast::Attribute], - item_kind: &str, - diagnostic: &::rustc_errors::Handler, -) { - for attr in attrs { - if let Some(attr) = attr.meta() { - if let Some(list) = attr.meta_item_list() { - for meta in list { - if meta.check_name(sym::alias) { - diagnostic.span_err( - meta.span(), - &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", item_kind), - ); - } - } - } - } - } -} - // Also, is there some reason that this doesn't use the 'visit' // framework from syntax?. @@ -408,7 +387,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match item.kind { hir::ItemKind::ForeignMod(ref fm) => { - check_doc_alias_attrs(&item.attrs, "extern block", self.cx.sess().diagnostic()); for item in fm.items { self.visit_foreign_item(item, None, om); } @@ -583,22 +561,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self_ty, ref items, } => { - check_doc_alias_attrs( - &item.attrs, - "implementation block", - self.cx.sess().diagnostic(), - ); // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. if !self.inlining && of_trait.is_none() { - let items = items - .iter() - .map(|item| { - let item = self.cx.tcx.hir().impl_item(item.id); - self.check_impl_doc_alias_attr(item); - item - }) - .collect(); + let items = + items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); let i = Impl { unsafety, polarity, @@ -614,31 +581,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { vis: &item.vis, }; om.impls.push(i); - } else if of_trait.is_some() { - for item in items.iter() { - self.check_impl_doc_alias_attr(self.cx.tcx.hir().impl_item(item.id)); - } } } } } - fn check_impl_doc_alias_attr(&self, item: &hir::ImplItem<'_>) { - match item.kind { - hir::ImplItemKind::Const(_, _) => check_doc_alias_attrs( - &item.attrs, - "const in implementation block", - self.cx.sess().diagnostic(), - ), - hir::ImplItemKind::TyAlias(_) => check_doc_alias_attrs( - &item.attrs, - "type alias in implementation block", - self.cx.sess().diagnostic(), - ), - hir::ImplItemKind::Fn(_, _) => {} - } - } - fn visit_foreign_item( &mut self, item: &'tcx hir::ForeignItem<'_>, diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr index 5fe943debdeb0..cc51101c16455 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -10,18 +10,18 @@ error: `#[doc(alias = "...")]` isn't allowed on implementation block LL | #[doc(alias = "bar")] | ^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on const in implementation block - --> $DIR/check-doc-alias-attr-location.rs:14:11 - | -LL | #[doc(alias = "const")] - | ^^^^^^^^^^^^^^^ - 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 const in implementation block + --> $DIR/check-doc-alias-attr-location.rs:14:11 + | +LL | #[doc(alias = "const")] + | ^^^^^^^^^^^^^^^ + error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block --> $DIR/check-doc-alias-attr-location.rs:20:11 | 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..9f0b1dcf44af2 --- /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")] //~ ERROR + 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..b4a0847a002ba --- /dev/null +++ b/src/test/ui/check-doc-alias-attr-location.stderr @@ -0,0 +1,32 @@ +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 const in implementation block + --> $DIR/check-doc-alias-attr-location.rs:15:11 + | +LL | #[doc(alias = "const")] + | ^^^^^^^^^^^^^^^ + +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 5 previous errors + From b7d1e33ff19583b3fd6577e9925b3acf09489a4e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Aug 2020 00:12:49 +0200 Subject: [PATCH 41/64] Allow #[doc(alias)] on impl const items --- src/librustc_passes/check_attr.rs | 8 ++------ src/test/rustdoc-js/doc-alias.js | 18 +++++++++++++++--- src/test/rustdoc-js/doc-alias.rs | 2 ++ .../check-doc-alias-attr-location.rs | 4 ++-- .../check-doc-alias-attr-location.stderr | 8 +------- src/test/ui/check-doc-alias-attr-location.rs | 2 +- .../ui/check-doc-alias-attr-location.stderr | 8 +------- 7 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index 7c17c289a56fa..832cde86d0b7b 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -241,15 +241,11 @@ impl CheckAttrVisitor<'tcx> { if let Some(err) = match target { Target::Impl => Some("implementation block"), Target::ForeignMod => Some("extern block"), - Target::AssocConst | Target::AssocTy => { + 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(if target == Target::AssocConst { - "const in implementation block" - } else { - "type alias in implementation block" - }) + Some("type alias in implementation block") } else { None } 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 28a720d06e8d3..41caa98643cdd 100644 --- a/src/test/rustdoc-js/doc-alias.rs +++ b/src/test/rustdoc-js/doc-alias.rs @@ -7,6 +7,8 @@ pub struct Struct { } impl Struct { + #[doc(alias = "StructImplConstItem")] + pub const ImplConstItem: i32 = 0; #[doc(alias = "StructMethodItem")] pub fn method(&self) {} } diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.rs b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs index 8a97cf7f8e892..545964c7bd61b 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.rs +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs @@ -11,8 +11,8 @@ extern {} #[doc(alias = "bar")] //~ ERROR impl Bar { - #[doc(alias = "const")] //~ ERROR - const A: u32 = 0; + #[doc(alias = "const")] + pub const A: u32 = 0; } #[doc(alias = "foobar")] //~ ERROR diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr index cc51101c16455..a66e9939eaf18 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -16,17 +16,11 @@ error: `#[doc(alias = "...")]` isn't allowed on implementation block LL | #[doc(alias = "foobar")] | ^^^^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on const in implementation block - --> $DIR/check-doc-alias-attr-location.rs:14:11 - | -LL | #[doc(alias = "const")] - | ^^^^^^^^^^^^^^^ - 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 5 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/check-doc-alias-attr-location.rs b/src/test/ui/check-doc-alias-attr-location.rs index 9f0b1dcf44af2..dac9b7372e08b 100644 --- a/src/test/ui/check-doc-alias-attr-location.rs +++ b/src/test/ui/check-doc-alias-attr-location.rs @@ -12,7 +12,7 @@ extern {} #[doc(alias = "bar")] //~ ERROR impl Bar { - #[doc(alias = "const")] //~ ERROR + #[doc(alias = "const")] const A: u32 = 0; } diff --git a/src/test/ui/check-doc-alias-attr-location.stderr b/src/test/ui/check-doc-alias-attr-location.stderr index b4a0847a002ba..29a99e4470e5f 100644 --- a/src/test/ui/check-doc-alias-attr-location.stderr +++ b/src/test/ui/check-doc-alias-attr-location.stderr @@ -16,17 +16,11 @@ error: `#[doc(alias = "...")]` isn't allowed on implementation block LL | #[doc(alias = "foobar")] | ^^^^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on const in implementation block - --> $DIR/check-doc-alias-attr-location.rs:15:11 - | -LL | #[doc(alias = "const")] - | ^^^^^^^^^^^^^^^ - 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 5 previous errors +error: aborting due to 4 previous errors From a12256c276275713843d6444041add3a96ae2288 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 18 Aug 2020 12:01:43 +0200 Subject: [PATCH 42/64] BTreeMap: check some invariants, avoid recursion in depth first search --- library/alloc/src/collections/btree/map.rs | 35 +-- .../alloc/src/collections/btree/map/tests.rs | 232 +++++++++++++++++- .../alloc/src/collections/btree/navigate.rs | 76 ++++++ 3 files changed, 302 insertions(+), 41 deletions(-) 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> { From bbcd1eced98c11f9a1cbf61c79af05969c2914a7 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 2 Aug 2020 21:28:18 +0200 Subject: [PATCH 43/64] move const param structural match checks to wfcheck --- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 116 +++++++++++- src/librustc_typeck/collect/type_of.rs | 85 +-------- .../ui/const-generics/issues/issue-75047.rs | 15 ++ .../ui/const-generics/nested-type.full.stderr | 163 ++--------------- .../ui/const-generics/nested-type.min.stderr | 167 ++---------------- src/test/ui/const-generics/nested-type.rs | 6 +- 7 files changed, 155 insertions(+), 401 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-75047.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 824e81a974ca6..dc4f181ec939b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -729,8 +729,8 @@ impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> { } pub fn check_wf_new(tcx: TyCtxt<'_>) { - let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); - tcx.hir().krate().par_visit_all_item_likes(&visit); + let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); + tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor()); } fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d47a8273d07ea..740f30f5224d0 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -6,9 +6,11 @@ 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::itemlikevisit::ParItemLikeVisitor; +use rustc_hir::intravisit as hir_visit; +use rustc_hir::intravisit::Visitor; 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 +277,95 @@ 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 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(); + } + } + } + } +} + fn check_associated_item( tcx: TyCtxt<'_>, item_id: hir::HirId, @@ -1292,23 +1383,38 @@ impl CheckTypeWellFormedVisitor<'tcx> { } } -impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> { - fn visit_item(&self, i: &'tcx hir::Item<'tcx>) { +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); + // No need to walk further here, there is nothing interesting + // inside of generic params we don't already check in `check_param_wf`. } } 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/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/nested-type.full.stderr b/src/test/ui/const-generics/nested-type.full.stderr index 012b8fe587b30..a55d43d395c84 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:17: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:17: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..17e2eef7278a0 100644 --- a/src/test/ui/const-generics/nested-type.min.stderr +++ b/src/test/ui/const-generics/nested-type.min.stderr @@ -4,172 +4,29 @@ error: using `[u8; _]` as const generic parameters is forbidden LL | struct Foo; LL | | ... | -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 - | -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[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants + --> $DIR/nested-type.rs:17: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() + | ^^^^^^^^^^^^^^^^^^ -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:17: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..70d6ac42e9ff2 100644 --- a/src/test/ui/const-generics/nested-type.rs +++ b/src/test/ui/const-generics/nested-type.rs @@ -5,9 +5,7 @@ #![cfg_attr(min, feature(min_const_generics))] struct Foo; impl Foo { @@ -17,6 +15,8 @@ struct Foo::value() + //~^ ERROR calls in constants are limited to constant functions + //~| ERROR evaluation of constant value failed }]>; fn main() {} From 1ca044da16c9f0b589acf41a21b5f18efcf1cf8f Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 13 Aug 2020 22:26:55 +0200 Subject: [PATCH 44/64] run wfcheck in parralel again, add test for 74950 --- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 19 +++++++- .../issues/issue-56445.min.stderr | 11 +---- .../ui/const-generics/issues/issue-56445.rs | 1 - .../issues/issue-74950.min.stderr | 47 +++++++++++++++++++ .../ui/const-generics/issues/issue-74950.rs | 25 ++++++++++ 6 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-74950.min.stderr create mode 100644 src/test/ui/const-generics/issues/issue-74950.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc4f181ec939b..824e81a974ca6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -729,8 +729,8 @@ impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> { } pub fn check_wf_new(tcx: TyCtxt<'_>) { - let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); - tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor()); + let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); + tcx.hir().krate().par_visit_all_item_likes(&visit); } fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 740f30f5224d0..cbf302ad71005 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -8,6 +8,7 @@ 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; @@ -1373,6 +1374,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>, } @@ -1383,6 +1385,20 @@ 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>; @@ -1413,8 +1429,7 @@ impl Visitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> { fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { check_param_wf(self.tcx, p); - // No need to walk further here, there is nothing interesting - // inside of generic params we don't already check in `check_param_wf`. + hir_visit::walk_generic_param(self, p); } } 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..e98f1d94a7240 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-74950.min.stderr @@ -0,0 +1,47 @@ +error: using `Inner` as const generic parameters is forbidden + --> $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: using `Inner` as const generic parameters is forbidden + --> $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: using `Inner` as const generic parameters is forbidden + --> $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: using `Inner` as const generic parameters is forbidden + --> $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: using `Inner` as const generic parameters is forbidden + --> $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..bfa0630a93629 --- /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]~^ using `Inner` as const generic parameters is forbidden +//[min]~| using `Inner` as const generic parameters is forbidden +//[min]~| using `Inner` as const generic parameters is forbidden +//[min]~| using `Inner` as const generic parameters is forbidden +//[min]~| using `Inner` as const generic parameters is forbidden + +fn main() {} From 6efe727abcddd5fcb535bd3f10c7da0fc1f0b7d4 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 18 Aug 2020 22:44:06 +0200 Subject: [PATCH 45/64] change const param ty warning message --- src/librustc_typeck/check/wfcheck.rs | 30 +++++++++++++------ ...ay-size-in-generic-struct-param.min.stderr | 2 +- .../array-size-in-generic-struct-param.rs | 2 +- .../const-param-elided-lifetime.min.stderr | 10 +++---- .../const-param-elided-lifetime.rs | 10 +++---- ...ram-type-depends-on-const-param.min.stderr | 4 +-- ...const-param-type-depends-on-const-param.rs | 4 +-- .../const-generics/different_byref.min.stderr | 2 +- src/test/ui/const-generics/different_byref.rs | 2 +- .../fn-const-param-call.min.stderr | 6 ---- .../fn-const-param-infer.min.stderr | 3 -- ...rbid-non-structural_match-types.min.stderr | 4 +-- .../forbid-non-structural_match-types.rs | 4 +-- ...96-impl-trait-for-str-const-arg.min.stderr | 2 +- ...ssue-66596-impl-trait-for-str-const-arg.rs | 2 +- .../issues/issue-74950.min.stderr | 10 +++---- .../ui/const-generics/issues/issue-74950.rs | 10 +++---- .../min_const_generics/complex-types.rs | 9 +++--- .../min_const_generics/complex-types.stderr | 12 ++++---- .../ui/const-generics/nested-type.full.stderr | 4 +-- .../ui/const-generics/nested-type.min.stderr | 8 ++--- src/test/ui/const-generics/nested-type.rs | 3 +- .../raw-ptr-const-param-deref.min.stderr | 6 ---- .../raw-ptr-const-param.min.stderr | 3 -- .../slice-const-param-mismatch.min.stderr | 4 +-- .../slice-const-param.min.stderr | 4 +-- .../ui/const-generics/slice-const-param.rs | 4 +-- 27 files changed, 78 insertions(+), 86 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index cbf302ad71005..810bf59ea6c35 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -289,12 +289,14 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { 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()) } @@ -307,19 +309,29 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { } }; 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`") + 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() - } else { - err.emit(); } }; + if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty) .is_some() { 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-74950.min.stderr b/src/test/ui/const-generics/issues/issue-74950.min.stderr index e98f1d94a7240..f093e6651bc28 100644 --- a/src/test/ui/const-generics/issues/issue-74950.min.stderr +++ b/src/test/ui/const-generics/issues/issue-74950.min.stderr @@ -1,4 +1,4 @@ -error: using `Inner` as const generic parameters is forbidden +error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:18:23 | LL | struct Outer; @@ -7,7 +7,7 @@ LL | struct Outer; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `Inner` as const generic parameters is forbidden +error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:18:23 | LL | struct Outer; @@ -16,7 +16,7 @@ LL | struct Outer; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `Inner` as const generic parameters is forbidden +error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:18:23 | LL | struct Outer; @@ -25,7 +25,7 @@ LL | struct Outer; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `Inner` as const generic parameters is forbidden +error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:18:23 | LL | struct Outer; @@ -34,7 +34,7 @@ LL | struct Outer; = note: the only supported types are integers, `bool` and `char` = note: more complex types are supported with `#[feature(const_generics)]` -error: using `Inner` as const generic parameters is forbidden +error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:18:23 | LL | struct Outer; diff --git a/src/test/ui/const-generics/issues/issue-74950.rs b/src/test/ui/const-generics/issues/issue-74950.rs index bfa0630a93629..39f91f2b83dfb 100644 --- a/src/test/ui/const-generics/issues/issue-74950.rs +++ b/src/test/ui/const-generics/issues/issue-74950.rs @@ -16,10 +16,10 @@ struct Inner; // - impl StructuralEq #[derive(PartialEq, Eq)] struct Outer; -//[min]~^ using `Inner` as const generic parameters is forbidden -//[min]~| using `Inner` as const generic parameters is forbidden -//[min]~| using `Inner` as const generic parameters is forbidden -//[min]~| using `Inner` as const generic parameters is forbidden -//[min]~| using `Inner` as const generic parameters is forbidden +//[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/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 a55d43d395c84..ded6f882caf42 100644 --- a/src/test/ui/const-generics/nested-type.full.stderr +++ b/src/test/ui/const-generics/nested-type.full.stderr @@ -1,11 +1,11 @@ error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/nested-type.rs:17:5 + --> $DIR/nested-type.rs:16:5 | LL | Foo::<17>::value() | ^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/nested-type.rs:17:5 + --> $DIR/nested-type.rs:16:5 | LL | Foo::<17>::value() | ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value` diff --git a/src/test/ui/const-generics/nested-type.min.stderr b/src/test/ui/const-generics/nested-type.min.stderr index 17e2eef7278a0..55f6fe7cc16e8 100644 --- a/src/test/ui/const-generics/nested-type.min.stderr +++ b/src/test/ui/const-generics/nested-type.min.stderr @@ -1,11 +1,11 @@ -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 | | impl Foo { ... | LL | | LL | | }]>; @@ -15,13 +15,13 @@ LL | | }]>; = note: more complex types are supported with `#[feature(const_generics)]` error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/nested-type.rs:17:5 + --> $DIR/nested-type.rs:16:5 | LL | Foo::<17>::value() | ^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/nested-type.rs:17:5 + --> $DIR/nested-type.rs:16:5 | LL | Foo::<17>::value() | ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value` diff --git a/src/test/ui/const-generics/nested-type.rs b/src/test/ui/const-generics/nested-type.rs index 70d6ac42e9ff2..8372551fb450b 100644 --- a/src/test/ui/const-generics/nested-type.rs +++ b/src/test/ui/const-generics/nested-type.rs @@ -4,8 +4,7 @@ #![cfg_attr(full, allow(incomplete_features))] #![cfg_attr(min, feature(min_const_generics))] -struct Foo; impl Foo { 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 } From d55dff7b6f9ffde357bd054b5bcc0db570448f68 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Aug 2020 10:44:53 +0200 Subject: [PATCH 46/64] mir building: fix some comments --- src/librustc_mir/transform/mod.rs | 3 ++- src/test/mir-opt/issue-41697.rs | 2 +- ...}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.32bit} | 2 +- ...}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.64bit} | 2 +- ...mir => loop_test.main.SimplifyCfg-promote-consts.after.mir} | 2 +- src/test/mir-opt/loop_test.rs | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) rename src/test/mir-opt/{issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.32bit => issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.32bit} (96%) rename src/test/mir-opt/{issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.64bit => issue_41697.{{impl}}-{{constant}}.SimplifyCfg-promote-consts.after.mir.64bit} (96%) rename src/test/mir-opt/{loop_test.main.SimplifyCfg-qualify-consts.after.mir => loop_test.main.SimplifyCfg-promote-consts.after.mir} (98%) 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/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) From 2d78f1470447a36d55fbf72d968c44f11b47c096 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 16 Aug 2020 11:38:46 -0400 Subject: [PATCH 47/64] Adjust installation place for compiler docs This avoids conflicts when installing with rustup; rustup does not currently support overlapping installations. --- src/bootstrap/dist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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); From d67557589d52abeada62b8080fa12dfafab01350 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Aug 2020 23:54:41 +0200 Subject: [PATCH 48/64] Make OnceCell transparent to dropck See the failed build in https://github.com/rust-lang/rust/pull/75555#issuecomment-675016718 for an example where we need this in real life --- library/core/tests/lazy.rs | 9 +++++++++ library/std/src/lazy.rs | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) 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/lazy.rs b/library/std/src/lazy.rs index 60eba96bcc015..c1d05213e1147 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() }; } } @@ -845,4 +846,13 @@ mod tests { assert_eq!(msg, MSG); } } + + #[test] + fn dropck() { + let cell = SyncOnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } + } } From 49d075ede153b672516d01c43555472104999daf Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:03:38 -0400 Subject: [PATCH 49/64] Refactor `impl_for_type` into a separate function --- src/librustdoc/clean/utils.rs | 63 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index a502a27948e29..65dfc7b2481ad 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, Ty}; +use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::mem; @@ -350,8 +350,39 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { +pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option { use self::PrimitiveType::*; + + 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, + } +} + +pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { let tcx = cx.tcx; for item in items { @@ -370,33 +401,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, - }; + let did = impl_for_type(tcx, primitive); if let Some(did) = did { if !did.is_local() { inline::build_impl(cx, did, None, ret); From a4589387ed97559142d33d112e78edba8b00bede Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:06:46 -0400 Subject: [PATCH 50/64] Say `tcx.lang_items()` less --- src/librustdoc/clean/utils.rs | 41 ++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 65dfc7b2481ad..7ab2196585fab 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -353,29 +353,30 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option { use self::PrimitiveType::*; + let lang_items = tcx.lang_items(); 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(), + Isize => lang_items.isize_impl(), + I8 => lang_items.i8_impl(), + I16 => lang_items.i16_impl(), + I32 => lang_items.i32_impl(), + I64 => lang_items.i64_impl(), + I128 => lang_items.i128_impl(), + Usize => lang_items.usize_impl(), + U8 => lang_items.u8_impl(), + U16 => lang_items.u16_impl(), + U32 => lang_items.u32_impl(), + U64 => lang_items.u64_impl(), + U128 => lang_items.u128_impl(), + F32 => lang_items.f32_impl(), + F64 => lang_items.f64_impl(), + Char => lang_items.char_impl(), + Bool => lang_items.bool_impl(), + Str => lang_items.str_impl(), + Slice => lang_items.slice_impl(), + Array => lang_items.array_impl(), Tuple => None, Unit => None, - RawPointer => tcx.lang_items().const_ptr_impl(), + RawPointer => lang_items.const_ptr_impl(), Reference => None, Fn => None, Never => None, From 526f571a0adb9babf4ed83178c5cda31454dc7ec Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:21:31 -0400 Subject: [PATCH 51/64] Return all impls, not just the primary one --- Cargo.lock | 1 + src/librustdoc/Cargo.toml | 1 + src/librustdoc/clean/utils.rs | 41 ++++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 985dbb046d0c6..fc4e72138e7a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4106,6 +4106,7 @@ dependencies = [ "rustc-rayon", "serde", "serde_json", + "smallvec 1.4.0", "tempfile", ] 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/utils.rs b/src/librustdoc/clean/utils.rs index 7ab2196585fab..969098122bfca 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -17,6 +17,7 @@ use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; +use smallvec::SmallVec; use std::mem; pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { @@ -350,11 +351,14 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option { +pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> SmallVec<[DefId; 4]> { use self::PrimitiveType::*; + let both = + |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + let lang_items = tcx.lang_items(); - match primitive { + let primary_impl = match primitive { Isize => lang_items.isize_impl(), I8 => lang_items.i8_impl(), I16 => lang_items.i16_impl(), @@ -367,20 +371,38 @@ pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> Option U32 => lang_items.u32_impl(), U64 => lang_items.u64_impl(), U128 => lang_items.u128_impl(), - F32 => lang_items.f32_impl(), - F64 => lang_items.f64_impl(), + F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), + F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), Char => lang_items.char_impl(), Bool => lang_items.bool_impl(), - Str => lang_items.str_impl(), - Slice => lang_items.slice_impl(), + Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), + Slice => { + return 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 => lang_items.array_impl(), Tuple => None, Unit => None, - RawPointer => lang_items.const_ptr_impl(), + RawPointer => { + return 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 => None, Fn => None, Never => None, - } + }; + + primary_impl.into_iter().collect() } pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { @@ -402,8 +424,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - let did = impl_for_type(tcx, primitive); - if let Some(did) = did { + for did in impl_for_type(tcx, primitive) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } From 13133bee0c1f776738341958c0814f5670e03680 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:26:10 -0400 Subject: [PATCH 52/64] impl_for_type -> PrimitiveType::impls --- src/librustdoc/clean/types.rs | 57 +++++++++++++++++++++++++++++++++ src/librustdoc/clean/utils.rs | 59 ++--------------------------------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 914dc2e1b8847..5b9f4830261e2 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -19,12 +19,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; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1264,6 +1266,61 @@ impl PrimitiveType { } } + pub fn impls(&self, tcx: TyCtxt<'_>) -> SmallVec<[DefId; 4]> { + use self::PrimitiveType::*; + + let both = + |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + + let lang_items = tcx.lang_items(); + let primary_impl = match self { + Isize => lang_items.isize_impl(), + I8 => lang_items.i8_impl(), + I16 => lang_items.i16_impl(), + I32 => lang_items.i32_impl(), + I64 => lang_items.i64_impl(), + I128 => lang_items.i128_impl(), + Usize => lang_items.usize_impl(), + U8 => lang_items.u8_impl(), + U16 => lang_items.u16_impl(), + U32 => lang_items.u32_impl(), + U64 => lang_items.u64_impl(), + U128 => lang_items.u128_impl(), + F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), + F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), + Char => lang_items.char_impl(), + Bool => lang_items.bool_impl(), + Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), + Slice => { + return 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 => lang_items.array_impl(), + Tuple => None, + Unit => None, + RawPointer => { + return 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 => None, + Fn => None, + Never => None, + }; + + primary_impl.into_iter().collect() + } + + 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 969098122bfca..b80ac0384fddb 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -15,9 +15,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, Ty}; use rustc_span::symbol::{kw, sym, Symbol}; -use smallvec::SmallVec; use std::mem; pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { @@ -351,60 +350,6 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String { s } -pub fn impl_for_type(tcx: TyCtxt<'_>, primitive: PrimitiveType) -> SmallVec<[DefId; 4]> { - use self::PrimitiveType::*; - - let both = - |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; - - let lang_items = tcx.lang_items(); - let primary_impl = match primitive { - Isize => lang_items.isize_impl(), - I8 => lang_items.i8_impl(), - I16 => lang_items.i16_impl(), - I32 => lang_items.i32_impl(), - I64 => lang_items.i64_impl(), - I128 => lang_items.i128_impl(), - Usize => lang_items.usize_impl(), - U8 => lang_items.u8_impl(), - U16 => lang_items.u16_impl(), - U32 => lang_items.u32_impl(), - U64 => lang_items.u64_impl(), - U128 => lang_items.u128_impl(), - F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), - F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), - Char => lang_items.char_impl(), - Bool => lang_items.bool_impl(), - Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), - Slice => { - return 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 => lang_items.array_impl(), - Tuple => None, - Unit => None, - RawPointer => { - return 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 => None, - Fn => None, - Never => None, - }; - - primary_impl.into_iter().collect() -} - pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { let tcx = cx.tcx; @@ -424,7 +369,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - for did in impl_for_type(tcx, primitive) { + for did in primitive.impls(tcx) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } From 6516ef5a4108b2581f2574e72c5f33cd400e500f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:45:18 -0400 Subject: [PATCH 53/64] Allow reusing the code in `collect_trait_impls` --- src/librustdoc/clean/types.rs | 129 +++++++++++-------- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/lib.rs | 1 + src/librustdoc/passes/collect_trait_impls.rs | 35 +---- 4 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5b9f4830261e2..62f71514fcf60 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -7,6 +7,7 @@ use std::num::NonZeroU32; use std::rc::Rc; use std::sync::Arc; use std::{slice, vec}; +use std::lazy::SyncOnceCell as OnceCell; use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; @@ -26,7 +27,7 @@ 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; +use smallvec::{SmallVec, smallvec}; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1266,61 +1267,85 @@ impl PrimitiveType { } } - pub fn impls(&self, tcx: TyCtxt<'_>) -> SmallVec<[DefId; 4]> { - use self::PrimitiveType::*; - - let both = - |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; - - let lang_items = tcx.lang_items(); - let primary_impl = match self { - Isize => lang_items.isize_impl(), - I8 => lang_items.i8_impl(), - I16 => lang_items.i16_impl(), - I32 => lang_items.i32_impl(), - I64 => lang_items.i64_impl(), - I128 => lang_items.i128_impl(), - Usize => lang_items.usize_impl(), - U8 => lang_items.u8_impl(), - U16 => lang_items.u16_impl(), - U32 => lang_items.u32_impl(), - U64 => lang_items.u64_impl(), - U128 => lang_items.u128_impl(), - F32 => return both(lang_items.f32_impl(), lang_items.f32_runtime_impl()), - F64 => return both(lang_items.f64_impl(), lang_items.f64_runtime_impl()), - Char => lang_items.char_impl(), - Bool => lang_items.bool_impl(), - Str => return both(lang_items.str_impl(), lang_items.str_alloc_impl()), - Slice => { - return 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(); + pub fn impls(&self, tcx: TyCtxt<'_>) -> &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 + }} } - Array => lang_items.array_impl(), - Tuple => None, - Unit => None, - RawPointer => { - return 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 => None, - Fn => None, - Never => None, - }; - primary_impl.into_iter().collect() + 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 b80ac0384fddb..75fdcd5ec1c9c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -369,7 +369,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V None => continue, }, }; - for did in primitive.impls(tcx) { + for &did in primitive.impls(tcx) { if !did.is_local() { inline::build_impl(cx, did, None, ret); } 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/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); From 0d44f6e83a7e9d2f0ba1d092000a52ad830462fe Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 18:54:29 -0400 Subject: [PATCH 54/64] Use `impls` for intra doc links as well --- Cargo.lock | 2 +- src/librustdoc/clean/types.rs | 2 +- .../passes/collect_intra_doc_links.rs | 52 +++++++------------ 3 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc4e72138e7a5..f8fa2971b49d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4106,7 +4106,7 @@ dependencies = [ "rustc-rayon", "serde", "serde_json", - "smallvec 1.4.0", + "smallvec 1.4.2", "tempfile", ] diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 62f71514fcf60..344d5603d7637 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1267,7 +1267,7 @@ impl PrimitiveType { } } - pub fn impls(&self, tcx: TyCtxt<'_>) -> &SmallVec<[DefId; 4]> { + pub fn impls(&self, tcx: TyCtxt<'_>) -> &'static SmallVec<[DefId; 4]> { Self::all_impls(tcx).get(self).expect("missing impl for primitive type") } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index edfe8c05c6db9..60b212c0243ec 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; @@ -270,18 +271,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .ok_or(ErrorKind::ResolutionFailure)?; if let Some((path, 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); + 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 @@ -1238,26 +1242,6 @@ fn is_primitive(path_str: &str, ns: Namespace) -> Option<(&'static str, Res)> { } } -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)) } From ab4c87c0975c35c6551d16fa035b1b756d1ba39f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 19:36:29 -0400 Subject: [PATCH 55/64] xpy fmt --- src/librustdoc/clean/types.rs | 9 +++++---- src/librustdoc/passes/collect_intra_doc_links.rs | 7 ++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 344d5603d7637..3eac5bbda0078 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -3,11 +3,11 @@ 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; use std::{slice, vec}; -use std::lazy::SyncOnceCell as OnceCell; use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; @@ -27,7 +27,7 @@ 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 smallvec::{smallvec, SmallVec}; use crate::clean::cfg::Cfg; use crate::clean::external_path; @@ -1296,8 +1296,9 @@ impl PrimitiveType { } let single = |a: Option| a.into_iter().collect(); - let both = - |a: Option, b: Option| -> SmallVec<_> { a.into_iter().chain(b).collect() }; + let both = |a: Option, b: Option| -> SmallVec<_> { + a.into_iter().chain(b).collect() + }; let lang_items = tcx.lang_items(); map! { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 60b212c0243ec..97b9fcce05b36 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -275,7 +275,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let link = cx .tcx .associated_items(impl_) - .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, 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, From fcc2f5021ae5af209de1e1dc6908c57d28dce81e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 17 Aug 2020 19:42:39 -0400 Subject: [PATCH 56/64] Add a test --- .../intra-link-primitive-non-default-impl.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/rustdoc/intra-link-primitive-non-default-impl.rs 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..427cd2124a926 --- /dev/null +++ b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs @@ -0,0 +1,14 @@ +#![deny(broken_intra_doc_links)] + +// ignore-tidy-linelength + +// @has intra_link_primitive_non_default_impl/fn.f.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 f() {} From 1ded165d20bb6cd4d4e67afbaf55f3e39329cb21 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 19 Aug 2020 10:35:56 -0400 Subject: [PATCH 57/64] Add test for f32 and f64 methods --- .../intra-link-primitive-non-default-impl.rs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc/intra-link-primitive-non-default-impl.rs b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs index 427cd2124a926..160b18a967b20 100644 --- a/src/test/rustdoc/intra-link-primitive-non-default-impl.rs +++ b/src/test/rustdoc/intra-link-primitive-non-default-impl.rs @@ -2,7 +2,7 @@ // ignore-tidy-linelength -// @has intra_link_primitive_non_default_impl/fn.f.html +// @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`] @@ -11,4 +11,22 @@ // @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 f() {} +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() {} From 277d327c5ba7f64585d28b56731bb24805b8f745 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Tue, 18 Aug 2020 19:36:52 +0200 Subject: [PATCH 58/64] Move to intra doc links for std::io --- library/std/src/io/buffered.rs | 50 ++++++++++----------- library/std/src/io/cursor.rs | 14 +++--- library/std/src/io/error.rs | 65 ++++++++++++++------------- library/std/src/io/mod.rs | 81 ++++++++++++++++++---------------- library/std/src/io/stdio.rs | 29 +++--------- library/std/src/io/util.rs | 33 +++++++------- 6 files changed, 126 insertions(+), 146 deletions(-) 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..f1ee3c6986062 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 @@ -479,11 +479,11 @@ where /// } /// ``` /// -/// [`read()`]: Read::read +/// [`read()`]: Self::read /// [`&str`]: str /// [`std::io`]: self /// [`File`]: crate::fs::File -/// [slice]: ../../std/primitive.slice.html +/// [slice]: crate::slice #[stable(feature = "rust1", since = "1.0.0")] #[doc(spotlight)] pub trait Read { @@ -633,7 +633,7 @@ pub trait Read { /// /// [`File`]s implement `Read`: /// - /// [`read()`]: Read::read + /// [`read()`]: Self::read /// [`Ok(0)`]: Ok /// [`File`]: crate::fs::File /// @@ -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`]: Self::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; @@ -746,7 +746,7 @@ pub trait Read { /// /// [`File`]s implement `Read`: /// - /// [`read`]: Read::read + /// [`read`]: Self::read /// [`File`]: crate::fs::File /// /// ```no_run @@ -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; @@ -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`]: Self::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`]: Self::write_vectored #[unstable(feature = "can_vector", issue = "69941")] fn is_write_vectored(&self) -> bool { false @@ -1399,16 +1404,15 @@ pub trait Write { /// /// # 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. /// /// # 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`]: Self::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 @@ -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 @@ -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 @@ -1976,7 +1979,7 @@ pub trait BufRead: Read { /// also yielded an error. /// /// [`io::Result`]: self::Result - /// [`Vec`]: crate::vec::Vec + /// [`Vec`]: Vec /// [`read_until`]: Self::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 From 6b70a4195ddffe5c33308cb4374605fd463cc631 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Wed, 19 Aug 2020 16:26:17 +0200 Subject: [PATCH 59/64] Fix nits in intra-doc links for std io --- library/std/src/io/mod.rs | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index f1ee3c6986062..3245629483828 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -479,11 +479,11 @@ where /// } /// ``` /// -/// [`read()`]: Self::read +/// [`read()`]: Read::read /// [`&str`]: str /// [`std::io`]: self /// [`File`]: crate::fs::File -/// [slice]: crate::slice +/// [slice]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] #[doc(spotlight)] pub trait Read { @@ -633,7 +633,7 @@ pub trait Read { /// /// [`File`]s implement `Read`: /// - /// [`read()`]: Self::read + /// [`read()`]: Read::read /// [`Ok(0)`]: Ok /// [`File`]: crate::fs::File /// @@ -673,7 +673,7 @@ pub trait Read { /// /// See [`read_to_end`] for other error semantics. /// - /// [`read_to_end`]: Self::read_to_end + /// [`read_to_end`]: Read::read_to_end /// /// # Examples /// @@ -746,7 +746,7 @@ pub trait Read { /// /// [`File`]s implement `Read`: /// - /// [`read`]: Self::read + /// [`read`]: Read::read /// [`File`]: crate::fs::File /// /// ```no_run @@ -1209,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 @@ -1236,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 { @@ -1296,7 +1296,7 @@ pub trait Write { /// The default implementation calls [`write`] with either the first nonempty /// buffer provided, or an empty one if none exists. /// - /// [`write`]: Self::write + /// [`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) @@ -1311,7 +1311,7 @@ pub trait Write { /// /// The default implementation returns `false`. /// - /// [`write_vectored`]: Self::write_vectored + /// [`write_vectored`]: Write::write_vectored #[unstable(feature = "can_vector", issue = "69941")] fn is_write_vectored(&self) -> bool { false @@ -1359,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 /// @@ -1400,8 +1400,6 @@ pub trait Write { /// /// If the buffer contains no data, this will never call [`write_vectored`]. /// - /// [`write_vectored`]: Self::write_vectored - /// /// # Notes /// /// Unlike [`write_vectored`], this takes a *mutable* reference to @@ -1415,6 +1413,8 @@ pub trait Write { /// [`IoSlice`]s point (but not the [`IoSlice`]s themselves), are unchanged and /// can be reused. /// + /// [`write_vectored`]: Write::write_vectored + /// /// # Examples /// /// ``` @@ -1467,7 +1467,7 @@ pub trait Write { /// are received. This also means that partial writes are not indicated in /// this signature. /// - /// [`write_all`]: Self::write_all + /// [`write_all`]: Write::write_all /// /// # Errors /// @@ -1758,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}; @@ -1789,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. /// @@ -1839,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); @@ -1863,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 /// @@ -1927,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 /// @@ -1980,7 +1980,7 @@ pub trait BufRead: Read { /// /// [`io::Result`]: self::Result /// [`Vec`]: Vec - /// [`read_until`]: Self::read_until + /// [`read_until`]: BufRead::read_until /// /// # Examples /// @@ -2011,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 /// From 9c78a1fc08d7bda65f0e3c79231fea46dccec8c9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Aug 2020 10:28:22 +0200 Subject: [PATCH 60/64] Remove `#[cfg(miri)]` from OnceCell tests They were carried over from once_cell crate, but they are not entirely correct (as miri now supports more things), and we don't run miri tests for std, so let's just remove them. Maybe one day we'll run miri in std, but then we can just re-install these attributes. --- library/std/src/lazy.rs | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs index c1d05213e1147..f0548582d2f5d 100644 --- a/library/std/src/lazy.rs +++ b/library/std/src/lazy.rs @@ -517,6 +517,7 @@ mod tests { mpsc::channel, Mutex, }, + thread, }; #[test] @@ -553,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] @@ -735,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(); @@ -753,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(); @@ -812,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(); @@ -824,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(); @@ -836,7 +816,7 @@ mod tests { }); } for _ in 0..n_writers { - spawn(move || { + thread::spawn(move || { let _ = ONCE_CELL.set(MSG.to_owned()); }); } From 1fc75d1a1d95a4e66942bf69ee9a8b28b6828103 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 15 Aug 2020 19:12:27 -0400 Subject: [PATCH 61/64] Add tagged pointer impl to data structures --- src/librustc_data_structures/lib.rs | 4 + src/librustc_data_structures/tagged_ptr.rs | 157 +++++++++++++++ .../tagged_ptr/copy.rs | 183 ++++++++++++++++++ .../tagged_ptr/drop.rs | 142 ++++++++++++++ 4 files changed, 486 insertions(+) create mode 100644 src/librustc_data_structures/tagged_ptr.rs create mode 100644 src/librustc_data_structures/tagged_ptr/copy.rs create mode 100644 src/librustc_data_structures/tagged_ptr/drop.rs 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); + } +} From dba162a47f38b2b3d20afefcfdf299db05459c14 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 16 Aug 2020 11:08:55 -0400 Subject: [PATCH 62/64] Use CopyTaggedPtr for ParamEnv --- src/librustc_middle/ty/list.rs | 15 ++++++ src/librustc_middle/ty/mod.rs | 92 ++++++++++++---------------------- 2 files changed, 47 insertions(+), 60 deletions(-) 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; } From 71e09784e4e730dfa57049e4d2a2a9a9a3b64885 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Thu, 30 Apr 2020 00:11:04 +0200 Subject: [PATCH 63/64] change offset from u32 to u64 --- src/librustc_middle/mir/mod.rs | 6 +++--- src/librustc_mir/borrow_check/mod.rs | 4 ++-- src/librustc_mir/borrow_check/type_check/mod.rs | 2 +- src/librustc_mir/util/aggregate.rs | 3 +-- src/librustc_mir/util/elaborate_drops.rs | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 1faed87f8ff17..6983d954db43a 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. 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/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index 1a22eee3a0371..eed100c7f6d46 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -53,13 +53,12 @@ pub fn expand_aggregate<'tcx>( .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..ea01fe2228b15 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -744,7 +744,7 @@ where let tcx = self.tcx(); if let Some(size) = opt_size { - let size: u32 = size.try_into().unwrap_or_else(|_| { + let size: u64 = size.try_into().unwrap_or_else(|_| { bug!("move out check isn't implemented for array sizes bigger than u32::MAX"); }); let fields: Vec<(Place<'tcx>, Option)> = (0..size) From ce316ea3bafda96a01d7d03fae0e4f6358b9d4b9 Mon Sep 17 00:00:00 2001 From: DPC Date: Tue, 28 Jul 2020 01:14:52 +0200 Subject: [PATCH 64/64] just a rebase, things will still fail --- src/librustc_middle/mir/mod.rs | 6 +- src/librustc_mir/transform/elaborate_drops.rs | 65 +++++----- src/librustc_mir/util/aggregate.rs | 1 - src/librustc_mir/util/elaborate_drops.rs | 116 +++--------------- 4 files changed, 53 insertions(+), 135 deletions(-) diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 6983d954db43a..53e2c3cca0023 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -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_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/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index eed100c7f6d46..e867e8b40850f 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -52,7 +52,6 @@ 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 u64; assert_eq!(offset as usize, i); tcx.mk_place_elem( diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index ea01fe2228b15..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(), }, @@ -745,7 +676,7 @@ where if let Some(size) = opt_size { let size: u64 = size.try_into().unwrap_or_else(|_| { - bug!("move out check isn't implemented for array sizes bigger than u32::MAX"); + 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,