diff options
| author | pawanbisht62 <36775517+pawanbisht62@users.noreply.github.com> | 2020-08-06 17:00:51 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-06 17:00:51 +0530 |
| commit | bac939edcf2137f625cfd7b56dfa4aa7b814868f (patch) | |
| tree | bbeab2a9f6869b0be809a8e7029a62a77c8e22da | |
| parent | fdfbd89946ca34d12eec658d111ce9a85cd23df0 (diff) | |
| parent | 3cfc7fe78eccc754b16981704a098d7bd520e2fd (diff) | |
| download | rust-bac939edcf2137f625cfd7b56dfa4aa7b814868f.tar.gz rust-bac939edcf2137f625cfd7b56dfa4aa7b814868f.zip | |
Merge branch 'master' into feature/incorporate-tracing
313 files changed, 4630 insertions, 3878 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 565c916db5b..a19cca9071f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -575,8 +575,14 @@ jobs: CACHE_DOMAIN: ci-caches-gha.rust-lang.org if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" strategy: + fail-fast: false matrix: include: + - name: aarch64-gnu + os: + - self-hosted + - ARM64 + - linux - name: dist-x86_64-apple env: SCRIPT: "./x.py dist" diff --git a/Cargo.lock b/Cargo.lock index 7e90b7e6fba..d4f4ec7f6f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,19 +37,20 @@ version = "0.0.0" dependencies = [ "compiler_builtins", "core", - "rand 0.7.3", - "rand_xorshift 0.2.0", + "rand", + "rand_xorshift", ] [[package]] name = "ammonia" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e266e1f4be5ffa05309f650e2586fe1d3ae6034eb24025a7ae1dfecc330823a" +checksum = "89eac85170f4b3fb3dc5e442c1cfb036cb8eecf9dbbd431a161ffad15d90ea3b" dependencies = [ "html5ever", "lazy_static", "maplit", + "markup5ever_rcdom", "matches", "tendril", "url 2.1.0", @@ -343,7 +344,7 @@ dependencies = [ "termcolor", "toml", "unicode-width", - "unicode-xid 0.2.0", + "unicode-xid", "url 2.1.0", "walkdir", "winapi 0.3.8", @@ -444,9 +445,9 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d463e01905d607e181de72e8608721d3269f29176c9a14ce037011316ae7131d" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", "synstructure", ] @@ -547,12 +548,12 @@ dependencies = [ "lazy_static", "pulldown-cmark", "quine-mc_cluskey", - "quote 1.0.2", + "quote", "regex-syntax", "semver 0.9.0", "serde", "smallvec 1.4.0", - "syn 1.0.11", + "syn", "toml", "unicode-normalization", "url 2.1.0", @@ -667,7 +668,7 @@ checksum = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" name = "core" version = "0.0.0" dependencies = [ - "rand 0.7.3", + "rand", ] [[package]] @@ -788,8 +789,8 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1" dependencies = [ - "quote 1.0.2", - "syn 1.0.11", + "quote", + "syn", ] [[package]] @@ -835,9 +836,9 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -846,9 +847,9 @@ version = "0.99.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -923,9 +924,9 @@ checksum = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" [[package]] name = "elasticlunr-rs" -version = "2.3.4" +version = "2.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455" +checksum = "35622eb004c8f0c5e7e2032815f3314a93df0db30a1ce5c94e62c1ecc81e22b9" dependencies = [ "lazy_static", "regex", @@ -1003,9 +1004,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", "synstructure", ] @@ -1298,16 +1299,16 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.24.1" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025483b0a1e4577bb28578318c886ee5f817dda6eb62473269349044406644cb" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" dependencies = [ "log", "mac", "markup5ever", - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1515,9 +1516,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1586,9 +1587,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" +checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" dependencies = [ "rustc-std-workspace-core", ] @@ -1735,9 +1736,9 @@ checksum = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" [[package]] name = "markup5ever" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65381d9d47506b8592b97c4efd936afcf673b09b059f2bef39c7211ee78b9d03" +checksum = "aae38d669396ca9b707bfc3db254bc382ddb94f57cc5c235f34623a669a01dab" dependencies = [ "log", "phf", @@ -1751,6 +1752,18 @@ dependencies = [ ] [[package]] +name = "markup5ever_rcdom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f015da43bcd8d4f144559a3423f4591d69b8ce0652c905374da7205df336ae2b" +dependencies = [ + "html5ever", + "markup5ever", + "tendril", + "xml5ever", +] + +[[package]] name = "matchers" version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1937,7 +1950,7 @@ dependencies = [ "hex 0.4.0", "libc", "log", - "rand 0.7.3", + "rand", "rustc-workspace-hack", "rustc_version", "shell-escape", @@ -2131,7 +2144,7 @@ dependencies = [ "log", "mio-named-pipes", "miow 0.3.3", - "rand 0.7.3", + "rand", "tokio", "tokio-named-pipes", "tokio-uds", @@ -2233,9 +2246,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2261,18 +2274,18 @@ dependencies = [ [[package]] name = "phf" -version = "0.7.24" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ "phf_shared", ] [[package]] name = "phf_codegen" -version = "0.7.24" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" dependencies = [ "phf_generator", "phf_shared", @@ -2280,19 +2293,19 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.7.24" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ "phf_shared", - "rand 0.6.1", + "rand", ] [[package]] name = "phf_shared" -version = "0.7.24" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" dependencies = [ "siphasher", ] @@ -2363,18 +2376,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", -] - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2383,7 +2387,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" dependencies = [ - "unicode-xid 0.2.0", + "unicode-xid", ] [[package]] @@ -2443,20 +2447,11 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" -dependencies = [ - "proc-macro2 0.4.30", -] - -[[package]] -name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" dependencies = [ - "proc-macro2 1.0.3", + "proc-macro2", ] [[package]] @@ -2484,44 +2479,16 @@ dependencies = [ [[package]] name = "rand" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" -dependencies = [ - "cloudabi", - "fuchsia-zircon", - "libc", - "rand_chacha 0.1.0", - "rand_core 0.3.0", - "rand_hc 0.1.0", - "rand_isaac", - "rand_pcg", - "rand_xorshift 0.1.0", - "rustc_version", - "winapi 0.3.8", -] - -[[package]] -name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", - "rand_chacha 0.2.2", + "rand_chacha", "rand_core 0.5.1", - "rand_hc 0.2.0", -] - -[[package]] -name = "rand_chacha" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" -dependencies = [ - "rand_core 0.3.0", - "rustc_version", + "rand_hc", + "rand_pcg", ] [[package]] @@ -2557,15 +2524,6 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.0", -] - -[[package]] -name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" @@ -2574,15 +2532,6 @@ dependencies = [ ] [[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.0", -] - -[[package]] name = "rand_os" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2598,21 +2547,11 @@ dependencies = [ [[package]] name = "rand_pcg" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" -dependencies = [ - "rand_core 0.3.0", - "rustc_version", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.3.0", + "rand_core 0.5.1", ] [[package]] @@ -2752,7 +2691,7 @@ dependencies = [ "num_cpus", "ordslice", "racer", - "rand 0.7.3", + "rand", "rayon", "regex", "rls-analysis", @@ -2824,7 +2763,7 @@ dependencies = [ "env_logger 0.7.1", "futures", "log", - "rand 0.7.3", + "rand", "rls-data", "rls-ipc", "serde", @@ -3051,7 +2990,7 @@ version = "669.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456af5f09c006cf6c22c1a433ee0232c4bb74bdc6c647a010166a47c94ed2a63" dependencies = [ - "unicode-xid 0.2.0", + "unicode-xid", ] [[package]] @@ -3060,9 +2999,9 @@ version = "669.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64f6acd192f313047759a346b892998b626466b93fe04f415da5f38906bb3b4c" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", "synstructure", ] @@ -3224,13 +3163,13 @@ name = "rustc-workspace-hack" version = "1.0.0" dependencies = [ "crossbeam-utils 0.7.2", - "proc-macro2 1.0.3", - "quote 1.0.2", + "proc-macro2", + "quote", "serde", "serde_json", "smallvec 0.6.10", "smallvec 1.4.0", - "syn 1.0.11", + "syn", "url 2.1.0", "winapi 0.3.8", ] @@ -3555,7 +3494,7 @@ dependencies = [ name = "rustc_incremental" version = "0.0.0" dependencies = [ - "rand 0.7.3", + "rand", "rustc_ast", "rustc_data_structures", "rustc_fs_util", @@ -3644,7 +3583,7 @@ dependencies = [ name = "rustc_lexer" version = "0.1.0" dependencies = [ - "unicode-xid 0.2.0", + "unicode-xid", ] [[package]] @@ -3681,9 +3620,9 @@ dependencies = [ name = "rustc_macros" version = "0.1.0" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", "synstructure", ] @@ -3738,7 +3677,6 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "scoped-tls", "smallvec 1.4.0", "tracing", ] @@ -3808,6 +3746,7 @@ dependencies = [ "rustc_lexer", "rustc_session", "rustc_span", + "smallvec 1.4.0", "tracing", "unicode-normalization", ] @@ -4134,10 +4073,10 @@ dependencies = [ name = "rustfmt-config_proc_macro" version = "0.2.0" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", + "proc-macro2", + "quote", "serde", - "syn 1.0.11", + "syn", ] [[package]] @@ -4264,9 +4203,9 @@ version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4295,9 +4234,9 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4345,9 +4284,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.2.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" +checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" [[package]] name = "sized-chunks" @@ -4427,7 +4366,7 @@ dependencies = [ "panic_abort", "panic_unwind", "profiler_builtins", - "rand 0.7.3", + "rand", "rustc-demangle", "unwind", "wasi", @@ -4435,39 +4374,30 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" +checksum = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a" dependencies = [ "lazy_static", "new_debug_unreachable", "phf_shared", "precomputed-hash", "serde", - "string_cache_codegen", - "string_cache_shared", ] [[package]] name = "string_cache_codegen" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" dependencies = [ "phf_generator", "phf_shared", - "proc-macro2 0.4.30", - "quote 0.6.12", - "string_cache_shared", + "proc-macro2", + "quote", ] [[package]] -name = "string_cache_shared" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" - -[[package]] name = "strip-ansi-escapes" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4500,38 +4430,27 @@ checksum = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "strum" -version = "0.11.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e" +checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" [[package]] name = "strum_macros" -version = "0.11.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136" +checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ "heck", - "proc-macro2 0.4.30", - "quote 0.6.12", - "syn 0.15.35", -] - -[[package]] -name = "syn" -version = "0.15.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.12", - "unicode-xid 0.1.0", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4540,9 +4459,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "unicode-xid 0.2.0", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] @@ -4551,10 +4470,10 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", - "unicode-xid 0.2.0", + "proc-macro2", + "quote", + "syn", + "unicode-xid", ] [[package]] @@ -4577,7 +4496,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ "cfg-if", "libc", - "rand 0.7.3", + "rand", "redox_syscall", "remove_dir_all", "winapi 0.3.8", @@ -4682,9 +4601,9 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24069c0ba08aab54289d6a25f5036d94afc61e1538bbc42ae5501df141c9027d" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4983,9 +4902,9 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b" dependencies = [ - "proc-macro2 1.0.3", - "quote 1.0.2", - "syn 1.0.11", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -5104,12 +5023,6 @@ dependencies = [ [[package]] name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - -[[package]] -name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" @@ -5296,6 +5209,18 @@ dependencies = [ ] [[package]] +name = "xml5ever" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b1b52e6e8614d4a58b8e70cf51ec0cc21b256ad8206708bcff8139b5bbd6a59" +dependencies = [ + "log", + "mac", + "markup5ever", + "time", +] + +[[package]] name = "xz2" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/config.toml.example b/config.toml.example index 8ecd8d88d48..a9835ad12ad 100644 --- a/config.toml.example +++ b/config.toml.example @@ -433,7 +433,7 @@ # # LLD will not be used if we're cross linking or running tests. # -# Explicitly setting the linker for a target will override this option. +# Explicitly setting the linker for a target will override this option when targeting MSVC. #use-lld = false # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the @@ -503,7 +503,7 @@ # Linker to be used to link Rust code. Note that the # default value is platform specific, and if not specified it may also depend on # what platform is crossing to what platform. -# Setting this will override the `use-lld` option for Rust code. +# Setting this will override the `use-lld` option for Rust code when targeting MSVC. #linker = "cc" # Path to the `llvm-config` binary of the installation of a custom LLVM to link diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs index 38d19c59ad1..7c2e5694a62 100644 --- a/library/alloc/benches/btree/map.rs +++ b/library/alloc/benches/btree/map.rs @@ -282,3 +282,305 @@ pub fn iter_10k(b: &mut Bencher) { pub fn iter_1m(b: &mut Bencher) { bench_iter(b, 1_000, 1_000_000); } + +const FAT: usize = 256; + +// The returned map has small keys and values. +// Benchmarks on it have a counterpart in set.rs with the same keys and no values at all. +fn slim_map(n: usize) -> BTreeMap<usize, usize> { + (0..n).map(|i| (i, i)).collect::<BTreeMap<_, _>>() +} + +// The returned map has small keys and large values. +fn fat_val_map(n: usize) -> BTreeMap<usize, [usize; FAT]> { + (0..n).map(|i| (i, [i; FAT])).collect::<BTreeMap<_, _>>() +} + +// The returned map has large keys and values. +fn fat_map(n: usize) -> BTreeMap<[usize; FAT], [usize; FAT]> { + (0..n).map(|i| ([i; FAT], [i; FAT])).collect::<BTreeMap<_, _>>() +} + +#[bench] +pub fn clone_slim_100(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| src.clone()) +} + +#[bench] +pub fn clone_slim_100_and_clear(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| src.clone().clear()) +} + +#[bench] +pub fn clone_slim_100_and_drain_all(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| src.clone().drain_filter(|_, _| true).count()) +} + +#[bench] +pub fn clone_slim_100_and_drain_half(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| { + let mut map = src.clone(); + assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 100 / 2); + assert_eq!(map.len(), 100 / 2); + }) +} + +#[bench] +pub fn clone_slim_100_and_into_iter(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| src.clone().into_iter().count()) +} + +#[bench] +pub fn clone_slim_100_and_pop_all(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| { + let mut map = src.clone(); + while map.pop_first().is_some() {} + map + }); +} + +#[bench] +pub fn clone_slim_100_and_remove_all(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| { + let mut map = src.clone(); + while let Some(elt) = map.iter().map(|(&i, _)| i).next() { + let v = map.remove(&elt); + debug_assert!(v.is_some()); + } + map + }); +} + +#[bench] +pub fn clone_slim_100_and_remove_half(b: &mut Bencher) { + let src = slim_map(100); + b.iter(|| { + let mut map = src.clone(); + for i in (0..100).step_by(2) { + let v = map.remove(&i); + debug_assert!(v.is_some()); + } + assert_eq!(map.len(), 100 / 2); + map + }) +} + +#[bench] +pub fn clone_slim_10k(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| src.clone()) +} + +#[bench] +pub fn clone_slim_10k_and_clear(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| src.clone().clear()) +} + +#[bench] +pub fn clone_slim_10k_and_drain_all(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| src.clone().drain_filter(|_, _| true).count()) +} + +#[bench] +pub fn clone_slim_10k_and_drain_half(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| { + let mut map = src.clone(); + assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 10_000 / 2); + assert_eq!(map.len(), 10_000 / 2); + }) +} + +#[bench] +pub fn clone_slim_10k_and_into_iter(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| src.clone().into_iter().count()) +} + +#[bench] +pub fn clone_slim_10k_and_pop_all(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| { + let mut map = src.clone(); + while map.pop_first().is_some() {} + map + }); +} + +#[bench] +pub fn clone_slim_10k_and_remove_all(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| { + let mut map = src.clone(); + while let Some(elt) = map.iter().map(|(&i, _)| i).next() { + let v = map.remove(&elt); + debug_assert!(v.is_some()); + } + map + }); +} + +#[bench] +pub fn clone_slim_10k_and_remove_half(b: &mut Bencher) { + let src = slim_map(10_000); + b.iter(|| { + let mut map = src.clone(); + for i in (0..10_000).step_by(2) { + let v = map.remove(&i); + debug_assert!(v.is_some()); + } + assert_eq!(map.len(), 10_000 / 2); + map + }) +} + +#[bench] +pub fn clone_fat_val_100(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| src.clone()) +} + +#[bench] +pub fn clone_fat_val_100_and_clear(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| src.clone().clear()) +} + +#[bench] +pub fn clone_fat_val_100_and_drain_all(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| src.clone().drain_filter(|_, _| true).count()) +} + +#[bench] +pub fn clone_fat_val_100_and_drain_half(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| { + let mut map = src.clone(); + assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 100 / 2); + assert_eq!(map.len(), 100 / 2); + }) +} + +#[bench] +pub fn clone_fat_val_100_and_into_iter(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| src.clone().into_iter().count()) +} + +#[bench] +pub fn clone_fat_val_100_and_pop_all(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| { + let mut map = src.clone(); + while map.pop_first().is_some() {} + map + }); +} + +#[bench] +pub fn clone_fat_val_100_and_remove_all(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| { + let mut map = src.clone(); + while let Some(elt) = map.iter().map(|(&i, _)| i).next() { + let v = map.remove(&elt); + debug_assert!(v.is_some()); + } + map + }); +} + +#[bench] +pub fn clone_fat_val_100_and_remove_half(b: &mut Bencher) { + let src = fat_val_map(100); + b.iter(|| { + let mut map = src.clone(); + for i in (0..100).step_by(2) { + let v = map.remove(&i); + debug_assert!(v.is_some()); + } + assert_eq!(map.len(), 100 / 2); + map + }) +} + +#[bench] +pub fn clone_fat_100(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| src.clone()) +} + +#[bench] +pub fn clone_fat_100_and_clear(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| src.clone().clear()) +} + +#[bench] +pub fn clone_fat_100_and_drain_all(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| src.clone().drain_filter(|_, _| true).count()) +} + +#[bench] +pub fn clone_fat_100_and_drain_half(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| { + let mut map = src.clone(); + assert_eq!(map.drain_filter(|i, _| i[0] % 2 == 0).count(), 100 / 2); + assert_eq!(map.len(), 100 / 2); + }) +} + +#[bench] +pub fn clone_fat_100_and_into_iter(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| src.clone().into_iter().count()) +} + +#[bench] +pub fn clone_fat_100_and_pop_all(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| { + let mut map = src.clone(); + while map.pop_first().is_some() {} + map + }); +} + +#[bench] +pub fn clone_fat_100_and_remove_all(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| { + let mut map = src.clone(); + while let Some(elt) = map.iter().map(|(&i, _)| i).next() { + let v = map.remove(&elt); + debug_assert!(v.is_some()); + } + map + }); +} + +#[bench] +pub fn clone_fat_100_and_remove_half(b: &mut Bencher) { + let src = fat_map(100); + b.iter(|| { + let mut map = src.clone(); + for i in (0..100).step_by(2) { + let v = map.remove(&[i; FAT]); + debug_assert!(v.is_some()); + } + assert_eq!(map.len(), 100 / 2); + map + }) +} diff --git a/library/alloc/benches/btree/set.rs b/library/alloc/benches/btree/set.rs index 2518506b9b5..07bf5093727 100644 --- a/library/alloc/benches/btree/set.rs +++ b/library/alloc/benches/btree/set.rs @@ -50,27 +50,31 @@ macro_rules! set_bench { }; } +fn slim_set(n: usize) -> BTreeSet<usize> { + (0..n).collect::<BTreeSet<_>>() +} + #[bench] pub fn clone_100(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| src.clone()) } #[bench] pub fn clone_100_and_clear(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| src.clone().clear()) } #[bench] pub fn clone_100_and_drain_all(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| src.clone().drain_filter(|_| true).count()) } #[bench] pub fn clone_100_and_drain_half(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| { let mut set = src.clone(); assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 100 / 2); @@ -80,13 +84,13 @@ pub fn clone_100_and_drain_half(b: &mut Bencher) { #[bench] pub fn clone_100_and_into_iter(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| src.clone().into_iter().count()) } #[bench] pub fn clone_100_and_pop_all(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| { let mut set = src.clone(); while set.pop_first().is_some() {} @@ -96,11 +100,12 @@ pub fn clone_100_and_pop_all(b: &mut Bencher) { #[bench] pub fn clone_100_and_remove_all(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| { let mut set = src.clone(); while let Some(elt) = set.iter().copied().next() { - set.remove(&elt); + let ok = set.remove(&elt); + debug_assert!(ok); } set }); @@ -108,11 +113,12 @@ pub fn clone_100_and_remove_all(b: &mut Bencher) { #[bench] pub fn clone_100_and_remove_half(b: &mut Bencher) { - let src = pos(100); + let src = slim_set(100); b.iter(|| { let mut set = src.clone(); - for i in (2..=100 as i32).step_by(2) { - set.remove(&i); + for i in (0..100).step_by(2) { + let ok = set.remove(&i); + debug_assert!(ok); } assert_eq!(set.len(), 100 / 2); set @@ -121,25 +127,25 @@ pub fn clone_100_and_remove_half(b: &mut Bencher) { #[bench] pub fn clone_10k(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| src.clone()) } #[bench] pub fn clone_10k_and_clear(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| src.clone().clear()) } #[bench] pub fn clone_10k_and_drain_all(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| src.clone().drain_filter(|_| true).count()) } #[bench] pub fn clone_10k_and_drain_half(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| { let mut set = src.clone(); assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 10_000 / 2); @@ -149,13 +155,13 @@ pub fn clone_10k_and_drain_half(b: &mut Bencher) { #[bench] pub fn clone_10k_and_into_iter(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| src.clone().into_iter().count()) } #[bench] pub fn clone_10k_and_pop_all(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| { let mut set = src.clone(); while set.pop_first().is_some() {} @@ -165,11 +171,12 @@ pub fn clone_10k_and_pop_all(b: &mut Bencher) { #[bench] pub fn clone_10k_and_remove_all(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| { let mut set = src.clone(); while let Some(elt) = set.iter().copied().next() { - set.remove(&elt); + let ok = set.remove(&elt); + debug_assert!(ok); } set }); @@ -177,11 +184,12 @@ pub fn clone_10k_and_remove_all(b: &mut Bencher) { #[bench] pub fn clone_10k_and_remove_half(b: &mut Bencher) { - let src = pos(10_000); + let src = slim_set(10_000); b.iter(|| { let mut set = src.clone(); - for i in (2..=10_000 as i32).step_by(2) { - set.remove(&i); + for i in (0..10_000).step_by(2) { + let ok = set.remove(&i); + debug_assert!(ok); } assert_eq!(set.len(), 10_000 / 2); set diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 98c7ac3f2ef..518ac11b5a0 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -164,25 +164,34 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl AllocRef for Global { #[inline] - fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> { - unsafe { - let size = layout.size(); - if size == 0 { - Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) - } else { - let raw_ptr = match init { - AllocInit::Uninitialized => alloc(layout), - AllocInit::Zeroed => alloc_zeroed(layout), - }; - let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; - Ok(MemoryBlock { ptr, size }) - } - } + fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + let ptr = if size == 0 { + layout.dangling() + } else { + // SAFETY: `layout` is non-zero in size, + unsafe { NonNull::new(alloc(layout)).ok_or(AllocErr)? } + }; + Ok(NonNull::slice_from_raw_parts(ptr, size)) + } + + #[inline] + fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + let ptr = if size == 0 { + layout.dangling() + } else { + // SAFETY: `layout` is non-zero in size, + unsafe { NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr)? } + }; + Ok(NonNull::slice_from_raw_parts(ptr, size)) } #[inline] unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) { if layout.size() != 0 { + // SAFETY: `layout` is non-zero in size, + // other conditions must be upheld by the caller unsafe { dealloc(ptr.as_ptr(), layout) } } } @@ -193,38 +202,59 @@ unsafe impl AllocRef for Global { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - init: AllocInit, - ) -> Result<MemoryBlock, AllocErr> { - let size = layout.size(); + ) -> Result<NonNull<[u8]>, AllocErr> { debug_assert!( - new_size >= size, - "`new_size` must be greater than or equal to `memory.size()`" + new_size >= layout.size(), + "`new_size` must be greater than or equal to `layout.size()`" ); - if size == new_size { - return Ok(MemoryBlock { ptr, size }); + // SAFETY: `new_size` must be non-zero, which is checked in the match expression. + // Other conditions must be upheld by the caller + unsafe { + match layout.size() { + old_size if old_size == new_size => { + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } + 0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())), + old_size => { + // `realloc` probably checks for `new_size > size` or something similar. + intrinsics::assume(new_size > old_size); + let raw_ptr = realloc(ptr.as_ptr(), layout, new_size); + let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } + } } + } - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove if layout.size() == 0 => { - let new_layout = - unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; - self.alloc(new_layout, init) - } - ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size > size` or something similar. - let ptr = unsafe { - intrinsics::assume(new_size > size); - realloc(ptr.as_ptr(), layout, new_size) - }; - let memory = - MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }; - unsafe { - init.init_offset(memory, size); + #[inline] + unsafe fn grow_zeroed( + &mut self, + ptr: NonNull<u8>, + layout: Layout, + new_size: usize, + ) -> Result<NonNull<[u8]>, AllocErr> { + debug_assert!( + new_size >= layout.size(), + "`new_size` must be greater than or equal to `layout.size()`" + ); + + // SAFETY: `new_size` must be non-zero, which is checked in the match expression. + // Other conditions must be upheld by the caller + unsafe { + match layout.size() { + old_size if old_size == new_size => { + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } + 0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())), + old_size => { + // `realloc` probably checks for `new_size > size` or something similar. + intrinsics::assume(new_size > old_size); + let raw_ptr = realloc(ptr.as_ptr(), layout, new_size); + raw_ptr.add(old_size).write_bytes(0, new_size - old_size); + let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) } - Ok(memory) } } } @@ -235,35 +265,34 @@ unsafe impl AllocRef for Global { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - ) -> Result<MemoryBlock, AllocErr> { - let size = layout.size(); + ) -> Result<NonNull<[u8]>, AllocErr> { + let old_size = layout.size(); debug_assert!( - new_size <= size, - "`new_size` must be smaller than or equal to `memory.size()`" + new_size <= old_size, + "`new_size` must be smaller than or equal to `layout.size()`" ); - if size == new_size { - return Ok(MemoryBlock { ptr, size }); - } - - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove if new_size == 0 => { - unsafe { - self.dealloc(ptr, layout); - } - Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) - } - ReallocPlacement::MayMove => { - // `realloc` probably checks for `new_size < size` or something similar. - let ptr = unsafe { - intrinsics::assume(new_size < size); - realloc(ptr.as_ptr(), layout, new_size) - }; - Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }) + let ptr = if new_size == old_size { + ptr + } else if new_size == 0 { + // SAFETY: `layout` is non-zero in size as `old_size` != `new_size` + // Other conditions must be upheld by the caller + unsafe { + self.dealloc(ptr, layout); } - } + layout.dangling() + } else { + // SAFETY: new_size is not zero, + // Other conditions must be upheld by the caller + let raw_ptr = unsafe { + // `realloc` probably checks for `new_size < old_size` or something similar. + intrinsics::assume(new_size < old_size); + realloc(ptr.as_ptr(), layout, new_size) + }; + NonNull::new(raw_ptr).ok_or(AllocErr)? + }; + + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) } } @@ -274,8 +303,8 @@ unsafe impl AllocRef for Global { #[inline] unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; - match Global.alloc(layout, AllocInit::Uninitialized) { - Ok(memory) => memory.ptr.as_ptr(), + match Global.alloc(layout) { + Ok(ptr) => ptr.as_non_null_ptr().as_ptr(), Err(_) => handle_alloc_error(layout), } } diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs index 1c003983df9..f7463d0daac 100644 --- a/library/alloc/src/alloc/tests.rs +++ b/library/alloc/src/alloc/tests.rs @@ -8,17 +8,16 @@ use test::Bencher; fn allocate_zeroed() { unsafe { let layout = Layout::from_size_align(1024, 1).unwrap(); - let memory = Global - .alloc(layout.clone(), AllocInit::Zeroed) - .unwrap_or_else(|_| handle_alloc_error(layout)); + let ptr = + Global.alloc_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout)); - let mut i = memory.ptr.cast::<u8>().as_ptr(); + let mut i = ptr.as_non_null_ptr().as_ptr(); let end = i.add(layout.size()); while i < end { assert_eq!(*i, 0); i = i.offset(1); } - Global.dealloc(memory.ptr, layout); + Global.dealloc(ptr.as_non_null_ptr(), layout); } } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 65e0c984fe8..5e304beff78 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -146,7 +146,7 @@ use core::pin::Pin; use core::ptr::{self, Unique}; use core::task::{Context, Poll}; -use crate::alloc::{self, AllocInit, AllocRef, Global}; +use crate::alloc::{self, AllocRef, Global}; use crate::borrow::Cow; use crate::raw_vec::RawVec; use crate::str::from_boxed_utf8_unchecked; @@ -197,11 +197,7 @@ impl<T> Box<T> { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit() -> Box<mem::MaybeUninit<T>> { let layout = alloc::Layout::new::<mem::MaybeUninit<T>>(); - let ptr = Global - .alloc(layout, AllocInit::Uninitialized) - .unwrap_or_else(|_| alloc::handle_alloc_error(layout)) - .ptr - .cast(); + let ptr = Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast(); unsafe { Box::from_raw(ptr.as_ptr()) } } @@ -227,9 +223,8 @@ impl<T> Box<T> { pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> { let layout = alloc::Layout::new::<mem::MaybeUninit<T>>(); let ptr = Global - .alloc(layout, AllocInit::Zeroed) + .alloc_zeroed(layout) .unwrap_or_else(|_| alloc::handle_alloc_error(layout)) - .ptr .cast(); unsafe { Box::from_raw(ptr.as_ptr()) } } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 24d1f61fa68..1db629c3bdf 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -174,7 +174,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> { { let out_root = BTreeMap::ensure_is_owned(&mut out_tree.root); - let mut out_node = out_root.push_level(); + let mut out_node = out_root.push_internal_level(); let mut in_edge = internal.first_edge(); while let Ok(kv) = in_edge.right_kv() { let (k, v) = kv.into_kv(); @@ -1080,9 +1080,9 @@ impl<K: Ord, V> BTreeMap<K, V> { test_node = parent.forget_type(); } } - Err(node) => { + Err(_) => { // We are at the top, create a new root node and push there. - open_node = node.into_root_mut().push_level(); + open_node = root.push_internal_level(); break; } } @@ -1092,7 +1092,7 @@ impl<K: Ord, V> BTreeMap<K, V> { let tree_height = open_node.height() - 1; let mut right_tree = node::Root::new_leaf(); for _ in 0..tree_height { - right_tree.push_level(); + right_tree.push_internal_level(); } open_node.push(key, value, right_tree); @@ -1171,7 +1171,7 @@ impl<K: Ord, V> BTreeMap<K, V> { let mut right = Self::new(); let right_root = Self::ensure_is_owned(&mut right.root); for _ in 0..left_root.height() { - right_root.push_level(); + right_root.push_internal_level(); } { @@ -1255,7 +1255,11 @@ impl<K: Ord, V> BTreeMap<K, V> { } pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> { let front = self.root.as_mut().map(|r| r.as_mut().first_leaf_edge()); - DrainFilterInner { length: &mut self.length, cur_leaf_edge: front } + DrainFilterInner { + length: &mut self.length, + cur_leaf_edge: front, + emptied_internal_root: false, + } } /// Calculates the number of elements if it is incorrect. @@ -1625,6 +1629,7 @@ where pub(super) struct DrainFilterInner<'a, K: 'a, V: 'a> { length: &'a mut usize, cur_leaf_edge: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>, + emptied_internal_root: bool, } #[unstable(feature = "btree_drain_filter", issue = "70530")] @@ -1665,6 +1670,17 @@ where } } +impl<K, V> Drop for DrainFilterInner<'_, K, V> { + fn drop(&mut self) { + if self.emptied_internal_root { + if let Some(handle) = self.cur_leaf_edge.take() { + let root = handle.into_node().into_root_mut(); + root.pop_internal_level(); + } + } + } +} + impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> { /// Allow Debug implementations to predict the next element. pub(super) fn peek(&self) -> Option<(&K, &V)> { @@ -1681,9 +1697,10 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> { let (k, v) = kv.kv_mut(); if pred(k, v) { *self.length -= 1; - let (k, v, leaf_edge_location) = kv.remove_kv_tracking(); - self.cur_leaf_edge = Some(leaf_edge_location); - return Some((k, v)); + let RemoveResult { old_kv, pos, emptied_internal_root } = kv.remove_kv_tracking(); + self.cur_leaf_edge = Some(pos); + self.emptied_internal_root |= emptied_internal_root; + return Some(old_kv); } self.cur_leaf_edge = Some(kv.next_leaf_edge()); } @@ -2448,40 +2465,17 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> { pub fn insert(self, value: V) -> &'a mut V { *self.length += 1; - let out_ptr; - - let mut ins_k; - let mut ins_v; - let mut ins_edge; - - let mut cur_parent = match self.handle.insert(self.key, value) { - (Fit(handle), _) => return handle.into_kv_mut().1, - (Split(left, k, v, right), ptr) => { - ins_k = k; - ins_v = v; - ins_edge = right; - out_ptr = ptr; - left.ascend().map_err(|n| n.into_root_mut()) + let out_ptr = match self.handle.insert_recursing(self.key, value) { + (Fit(_), val_ptr) => val_ptr, + (Split(ins), val_ptr) => { + let root = ins.left.into_root_mut(); + root.push_internal_level().push(ins.k, ins.v, ins.right); + val_ptr } }; - - loop { - match cur_parent { - Ok(parent) => match parent.insert(ins_k, ins_v, ins_edge) { - Fit(_) => return unsafe { &mut *out_ptr }, - Split(left, k, v, right) => { - ins_k = k; - ins_v = v; - ins_edge = right; - cur_parent = left.ascend().map_err(|n| n.into_root_mut()); - } - }, - Err(root) => { - root.push_level().push(ins_k, ins_v, ins_edge); - return unsafe { &mut *out_ptr }; - } - } - } + // Now that we have finished growing the tree using borrowed references, + // dereference the pointer to a part of it, that we picked up along the way. + unsafe { &mut *out_ptr } } } @@ -2647,20 +2641,35 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { self.remove_kv().1 } + // Body of `remove_entry`, separate to keep the above implementations short. fn remove_kv(self) -> (K, V) { *self.length -= 1; - let (old_key, old_val, _) = self.handle.remove_kv_tracking(); - (old_key, old_val) + let RemoveResult { old_kv, pos, emptied_internal_root } = self.handle.remove_kv_tracking(); + let root = pos.into_node().into_root_mut(); + if emptied_internal_root { + root.pop_internal_level(); + } + old_kv } } +struct RemoveResult<'a, K, V> { + // Key and value removed. + old_kv: (K, V), + // Unique location at the leaf level that the removed KV lopgically collapsed into. + pos: Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>, + // Whether the remove left behind and empty internal root node, that should be removed + // using `pop_internal_level`. + emptied_internal_root: bool, +} + impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> { - /// Removes a key/value-pair from the map, and returns that pair, as well as - /// the leaf edge corresponding to that former pair. - fn remove_kv_tracking( - self, - ) -> (K, V, Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) { + /// Removes a key/value-pair from the tree, and returns that pair, as well as + /// the leaf edge corresponding to that former pair. It's possible this leaves + /// an empty internal root node, which the caller should subsequently pop from + /// the map holding the tree. The caller should also decrement the map's length. + fn remove_kv_tracking(self) -> RemoveResult<'a, K, V> { let (mut pos, old_key, old_val, was_internal) = match self.force() { Leaf(leaf) => { let (hole, old_key, old_val) = leaf.remove(); @@ -2689,6 +2698,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter }; // Handle underflow + let mut emptied_internal_root = false; let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() }; let mut at_leaf = true; while cur_node.len() < node::MIN_LEN { @@ -2709,8 +2719,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter let parent = edge.into_node(); if parent.len() == 0 { - // We must be at the root - parent.into_root_mut().pop_level(); + // This empty parent must be the root, and should be popped off the tree. + emptied_internal_root = true; break; } else { cur_node = parent.forget_type(); @@ -2737,7 +2747,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() }; } - (old_key, old_val, pos) + RemoveResult { old_kv: (old_key, old_val), pos, emptied_internal_root } } } @@ -2745,7 +2755,7 @@ impl<K, V> node::Root<K, V> { /// Removes empty levels on the top, but keep an empty leaf if the entire tree is empty. fn fix_top(&mut self) { while self.height() > 0 && self.as_ref().len() == 0 { - self.pop_level(); + self.pop_internal_level(); } } @@ -2817,8 +2827,16 @@ fn handle_underfull_node<K, V>( let (is_left, mut handle) = match parent.left_kv() { Ok(left) => (true, left), Err(parent) => { - let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) }; - (false, right) + match parent.right_kv() { + Ok(right) => (false, right), + Err(_) => { + // The underfull node has an empty parent, so it is the only child + // of an empty root. It is destined to become the new root, thus + // allowed to be underfull. The empty parent should be removed later + // by `pop_internal_level`. + return AtRoot; + } + } } }; diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index 44f0e25bbd7..0dcb5930964 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -19,7 +19,7 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::E Ok(internal_kv) => return Ok(internal_kv), Err(last_edge) => match last_edge.into_node().ascend() { Ok(parent_edge) => parent_edge.forget_node_type(), - Err(root) => return Err(root.forget_type()), + Err(root) => return Err(root), }, } } @@ -40,7 +40,7 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::E Ok(internal_kv) => return Ok(internal_kv), Err(last_edge) => match last_edge.into_node().ascend() { Ok(parent_edge) => parent_edge.forget_node_type(), - Err(root) => return Err(root.forget_type()), + Err(root) => return Err(root), }, } } diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index f7bd64608d6..6a4c495ea14 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -191,8 +191,9 @@ impl<K, V> Root<K, V> { } /// Adds a new internal node with a single edge, pointing to the previous root, and make that - /// new node the root. This increases the height by 1 and is the opposite of `pop_level`. - pub fn push_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> { + /// new node the root. This increases the height by 1 and is the opposite of + /// `pop_internal_level`. + pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> { let mut new_node = Box::new(unsafe { InternalNode::new() }); new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); @@ -213,11 +214,12 @@ impl<K, V> Root<K, V> { ret } - /// Removes the root node, using its first child as the new root. This cannot be called when - /// the tree consists only of a leaf node. As it is intended only to be called when the root - /// has only one edge, no cleanup is done on any of the other children of the root. - /// This decreases the height by 1 and is the opposite of `push_level`. - pub fn pop_level(&mut self) { + /// Removes the internal root node, using its first child as the new root. + /// As it is intended only to be called when the root has only one child, + /// no cleanup is done on any of the other children of the root. + /// This decreases the height by 1 and is the opposite of `push_internal_level`. + /// Panics if there is no internal level, i.e. if the root is a leaf. + pub fn pop_internal_level(&mut self) { assert!(self.height > 0); let top = self.node.ptr; @@ -305,12 +307,6 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { self.height } - /// Removes any static information about whether this node is a `Leaf` or an - /// `Internal` node. - pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { - NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } - } - /// Temporarily takes out another, immutable reference to the same node. fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> { NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } @@ -466,12 +462,6 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { fn into_val_slice(self) -> &'a [V] { unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) } } - - fn into_slices(self) -> (&'a [K], &'a [V]) { - // SAFETY: equivalent to reborrow() except not requiring Type: 'a - let k = unsafe { ptr::read(&self) }; - (k.into_key_slice(), self.into_val_slice()) - } } impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { @@ -829,13 +819,13 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar } } -impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> { +impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> { + /// Helps implementations of `insert_fit` for a particular `NodeType`, + /// by taking care of leaf data. /// Inserts a new key/value pair between the key/value pairs to the right and left of /// this edge. This method assumes that there is enough space in the node for the new /// pair to fit. - /// - /// The returned pointer points to the inserted value. - fn insert_fit(&mut self, key: K, val: V) -> *mut V { + fn leafy_insert_fit(&mut self, key: K, val: V) { // Necessary for correctness, but in a private module debug_assert!(self.node.len() < CAPACITY); @@ -844,16 +834,28 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge slice_insert(self.node.vals_mut(), self.idx, val); (*self.node.as_leaf_mut()).len += 1; - - self.node.vals_mut().get_unchecked_mut(self.idx) } } +} +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> { + /// Inserts a new key/value pair between the key/value pairs to the right and left of + /// this edge. This method assumes that there is enough space in the node for the new + /// pair to fit. + /// + /// The returned pointer points to the inserted value. + fn insert_fit(&mut self, key: K, val: V) -> *mut V { + self.leafy_insert_fit(key, val); + unsafe { self.node.vals_mut().get_unchecked_mut(self.idx) } + } +} + +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> { /// Inserts a new key/value pair between the key/value pairs to the right and left of /// this edge. This method splits the node if there isn't enough room. /// /// The returned pointer points to the inserted value. - pub fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) { + fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) { if self.node.len() < CAPACITY { let ptr = self.insert_fit(key, val); let kv = unsafe { Handle::new_kv(self.node, self.idx) }; @@ -872,7 +874,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge .insert_fit(key, val) } }; - (InsertResult::Split(left, k, v, right), ptr) + (InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), ptr) } } } @@ -890,14 +892,6 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker:: } } - /// Unsafely asserts to the compiler some static information about whether the underlying - /// node of this handle is a `Leaf` or an `Internal`. - unsafe fn cast_unchecked<NewType>( - &mut self, - ) -> Handle<NodeRef<marker::Mut<'_>, K, V, NewType>, marker::Edge> { - unsafe { Handle::new_edge(self.node.cast_unchecked(), self.idx) } - } - /// Inserts a new key/value pair and an edge that will go to the right of that new pair /// between this edge and the key/value pair to the right of this edge. This method assumes /// that there is enough space in the node for the new pair to fit. @@ -907,8 +901,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker:: debug_assert!(edge.height == self.node.height - 1); unsafe { - // This cast is a lie, but it allows us to reuse the key/value insertion logic. - self.cast_unchecked::<marker::Leaf>().insert_fit(key, val); + self.leafy_insert_fit(key, val); slice_insert( slice::from_raw_parts_mut( @@ -928,7 +921,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker:: /// Inserts a new key/value pair and an edge that will go to the right of that new pair /// between this edge and the key/value pair to the right of this edge. This method splits /// the node if there isn't enough room. - pub fn insert( + fn insert( mut self, key: K, val: V, @@ -956,7 +949,43 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker:: .insert_fit(key, val, edge); } } - InsertResult::Split(left, k, v, right) + InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }) + } + } +} + +impl<'a, K: 'a, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> { + /// Inserts a new key/value pair between the key/value pairs to the right and left of + /// this edge. This method splits the node if there isn't enough room, and tries to + /// insert the split off portion into the parent node recursively, until the root is reached. + /// + /// If the returned result is a `Fit`, its handle's node can be this edge's node or an ancestor. + /// If the returned result is a `Split`, the `left` field will be the root node. + /// The returned pointer points to the inserted value. + pub fn insert_recursing( + self, + key: K, + value: V, + ) -> (InsertResult<'a, K, V, marker::LeafOrInternal>, *mut V) { + let (mut split, val_ptr) = match self.insert(key, value) { + (InsertResult::Fit(handle), ptr) => { + return (InsertResult::Fit(handle.forget_node_type()), ptr); + } + (InsertResult::Split(split), val_ptr) => (split, val_ptr), + }; + + loop { + split = match split.left.ascend() { + Ok(parent) => match parent.insert(split.k, split.v, split.right) { + InsertResult::Fit(handle) => { + return (InsertResult::Fit(handle.forget_node_type()), val_ptr); + } + InsertResult::Split(split) => split, + }, + Err(root) => { + return (InsertResult::Split(SplitResult { left: root, ..split }), val_ptr); + } + }; } } } @@ -980,10 +1009,9 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marke impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Immut<'a>, K, V, NodeType>, marker::KV> { pub fn into_kv(self) -> (&'a K, &'a V) { - unsafe { - let (keys, vals) = self.node.into_slices(); - (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx)) - } + let keys = self.node.into_key_slice(); + let vals = self.node.into_val_slice(); + unsafe { (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx)) } } } @@ -1005,18 +1033,11 @@ impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker } } -impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> { - /// Splits the underlying node into three parts: - /// - /// - The node is truncated to only contain the key/value pairs to the right of - /// this handle. - /// - The key and value pointed to by this handle and extracted. - /// - All the key/value pairs to the right of this handle are put into a newly - /// allocated node. - pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) { +impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> { + /// Helps implementations of `split` for a particular `NodeType`, + /// by taking care of leaf data. + fn leafy_split(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V, usize) { unsafe { - let mut new_node = Box::new(LeafNode::new()); - let k = ptr::read(self.node.keys().get_unchecked(self.idx)); let v = ptr::read(self.node.vals().get_unchecked(self.idx)); @@ -1035,6 +1056,24 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> (*self.node.as_leaf_mut()).len = self.idx as u16; new_node.len = new_len as u16; + (k, v, new_len) + } + } +} + +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> { + /// Splits the underlying node into three parts: + /// + /// - The node is truncated to only contain the key/value pairs to the right of + /// this handle. + /// - The key and value pointed to by this handle and extracted. + /// - All the key/value pairs to the right of this handle are put into a newly + /// allocated node. + pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) { + unsafe { + let mut new_node = Box::new(LeafNode::new()); + + let (k, v, _) = self.leafy_split(&mut new_node); (self.node, k, v, Root { node: BoxedNode::from_leaf(new_node), height: 0 }) } @@ -1066,31 +1105,15 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker:: unsafe { let mut new_node = Box::new(InternalNode::new()); - let k = ptr::read(self.node.keys().get_unchecked(self.idx)); - let v = ptr::read(self.node.vals().get_unchecked(self.idx)); - + let (k, v, new_len) = self.leafy_split(&mut new_node.data); let height = self.node.height; - let new_len = self.node.len() - self.idx - 1; ptr::copy_nonoverlapping( - self.node.keys().as_ptr().add(self.idx + 1), - new_node.data.keys.as_mut_ptr() as *mut K, - new_len, - ); - ptr::copy_nonoverlapping( - self.node.vals().as_ptr().add(self.idx + 1), - new_node.data.vals.as_mut_ptr() as *mut V, - new_len, - ); - ptr::copy_nonoverlapping( self.node.as_internal().edges.as_ptr().add(self.idx + 1), new_node.edges.as_mut_ptr(), new_len + 1, ); - (*self.node.as_leaf_mut()).len = self.idx as u16; - new_node.data.len = new_len as u16; - let mut new_root = Root { node: BoxedNode::from_internal(new_node), height }; for i in 0..(new_len + 1) { @@ -1362,6 +1385,20 @@ unsafe fn move_edges<K, V>( } } +impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Leaf> { + /// Removes any static information asserting that this node is a `Leaf` node. + pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { + NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } + } +} + +impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> { + /// Removes any static information asserting that this node is an `Internal` node. + pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { + NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } + } +} + impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> { pub fn forget_node_type( self, @@ -1386,6 +1423,14 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::K } } +impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::KV> { + pub fn forget_node_type( + self, + ) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV> { + unsafe { Handle::new_kv(self.node.forget_type(), self.idx) } + } +} + impl<BorrowType, K, V, HandleType> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, HandleType> { @@ -1452,9 +1497,21 @@ pub enum ForceResult<Leaf, Internal> { Internal(Internal), } +/// Result of insertion, when a node needed to expand beyond its capacity. +/// Does not distinguish between `Leaf` and `Internal` because `Root` doesn't. +pub struct SplitResult<'a, K, V> { + // Altered node in existing tree with elements and edges that belong to the left of `k`. + pub left: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, + // Some key and value split off, to be inserted elsewhere. + pub k: K, + pub v: V, + // Owned, unattached, new node with elements and edges that belong to the right of `k`. + pub right: Root<K, V>, +} + pub enum InsertResult<'a, K, V, Type> { Fit(Handle<NodeRef<marker::Mut<'a>, K, V, Type>, marker::KV>), - Split(NodeRef<marker::Mut<'a>, K, V, Type>, K, V, Root<K, V>), + Split(SplitResult<'a, K, V>), } pub mod marker { diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index e5edfe02a52..d74f91c752c 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -107,7 +107,8 @@ fn test_insert() { let cap = tester.capacity(); // len is the length *after* insertion - for len in 1..cap { + let minlen = if cfg!(miri) { cap - 1 } else { 1 }; // Miri is too slow + for len in minlen..cap { // 0, 1, 2, .., len - 1 let expected = (0..).take(len).collect::<VecDeque<_>>(); for tail_pos in 0..cap { @@ -221,7 +222,8 @@ fn test_remove() { let cap = tester.capacity(); // len is the length *after* removal - for len in 0..cap - 1 { + let minlen = if cfg!(miri) { cap - 2 } else { 0 }; // Miri is too slow + for len in minlen..cap - 1 { // 0, 1, 2, .., len - 1 let expected = (0..).take(len).collect::<VecDeque<_>>(); for tail_pos in 0..cap { @@ -251,7 +253,8 @@ fn test_range() { let mut tester: VecDeque<usize> = VecDeque::with_capacity(7); let cap = tester.capacity(); - for len in 0..=cap { + let minlen = if cfg!(miri) { cap - 1 } else { 0 }; // Miri is too slow + for len in minlen..=cap { for tail in 0..=cap { for start in 0..=len { for end in start..=len { @@ -384,7 +387,8 @@ fn test_split_off() { let cap = tester.capacity(); // len is the length *before* splitting - for len in 0..cap { + let minlen = if cfg!(miri) { cap - 1 } else { 0 }; // Miri is too slow + for len in minlen..cap { // index to split at for at in 0..=len { // 0, 1, 2, .., at - 1 (may be empty) @@ -495,8 +499,9 @@ fn test_vec_from_vecdeque() { fn test_clone_from() { let m = vec![1; 8]; let n = vec![2; 12]; - for pfv in 0..8 { - for pfu in 0..8 { + let limit = if cfg!(miri) { 4 } else { 8 }; // Miri is too slow + for pfv in 0..limit { + for pfu in 0..limit { for longer in 0..2 { let (vr, ur) = if longer == 0 { (&m, &n) } else { (&n, &m) }; let mut v = VecDeque::from(vr.clone()); diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 097db30d634..9ac23886d4e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -104,6 +104,7 @@ #![feature(negative_impls)] #![feature(new_uninit)] #![feature(nll)] +#![feature(nonnull_slice_from_raw_parts)] #![feature(optin_builtin_traits)] #![feature(or_patterns)] #![feature(pattern)] @@ -113,6 +114,8 @@ #![feature(rustc_attrs)] #![feature(receiver_trait)] #![feature(min_specialization)] +#![feature(slice_ptr_get)] +#![feature(slice_ptr_len)] #![feature(staged_api)] #![feature(std_internals)] #![feature(str_internals)] diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index ed81ce71ddf..2abd7231711 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -1,25 +1,27 @@ #![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "none")] #![doc(hidden)] -use core::alloc::{LayoutErr, MemoryBlock}; +use core::alloc::LayoutErr; use core::cmp; use core::mem::{self, ManuallyDrop, MaybeUninit}; use core::ops::Drop; use core::ptr::{NonNull, Unique}; use core::slice; -use crate::alloc::{ - handle_alloc_error, - AllocInit::{self, *}, - AllocRef, Global, Layout, - ReallocPlacement::{self, *}, -}; +use crate::alloc::{handle_alloc_error, AllocRef, Global, Layout}; use crate::boxed::Box; use crate::collections::TryReserveError::{self, *}; #[cfg(test)] mod tests; +enum AllocInit { + /// The contents of the new memory are uninitialized. + Uninitialized, + /// The new memory is guaranteed to be zeroed. + Zeroed, +} + /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases /// involved. This type is excellent for building your own data structures like Vec and VecDeque. @@ -156,14 +158,14 @@ impl<T, A: AllocRef> RawVec<T, A> { /// allocator for the returned `RawVec`. #[inline] pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { - Self::allocate_in(capacity, Uninitialized, alloc) + Self::allocate_in(capacity, AllocInit::Uninitialized, alloc) } /// Like `with_capacity_zeroed`, but parameterized over the choice /// of allocator for the returned `RawVec`. #[inline] pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self { - Self::allocate_in(capacity, Zeroed, alloc) + Self::allocate_in(capacity, AllocInit::Zeroed, alloc) } fn allocate_in(capacity: usize, init: AllocInit, mut alloc: A) -> Self { @@ -180,14 +182,18 @@ impl<T, A: AllocRef> RawVec<T, A> { Ok(_) => {} Err(_) => capacity_overflow(), } - let memory = match alloc.alloc(layout, init) { - Ok(memory) => memory, + let result = match init { + AllocInit::Uninitialized => alloc.alloc(layout), + AllocInit::Zeroed => alloc.alloc_zeroed(layout), + }; + let ptr = match result { + Ok(ptr) => ptr, Err(_) => handle_alloc_error(layout), }; Self { - ptr: unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) }, - cap: Self::capacity_from_bytes(memory.size), + ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }, + cap: Self::capacity_from_bytes(ptr.len()), alloc, } } @@ -358,7 +364,7 @@ impl<T, A: AllocRef> RawVec<T, A> { /// /// Aborts on OOM. pub fn shrink_to_fit(&mut self, amount: usize) { - match self.shrink(amount, MayMove) { + match self.shrink(amount) { Err(CapacityOverflow) => capacity_overflow(), Err(AllocError { layout, .. }) => handle_alloc_error(layout), Ok(()) => { /* yay */ } @@ -378,9 +384,9 @@ impl<T, A: AllocRef> RawVec<T, A> { excess / mem::size_of::<T>() } - fn set_memory(&mut self, memory: MemoryBlock) { - self.ptr = unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) }; - self.cap = Self::capacity_from_bytes(memory.size); + fn set_ptr(&mut self, ptr: NonNull<[u8]>) { + self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }; + self.cap = Self::capacity_from_bytes(ptr.len()); } // This method is usually instantiated many times. So we want it to be as @@ -426,8 +432,8 @@ impl<T, A: AllocRef> RawVec<T, A> { let new_layout = Layout::array::<T>(cap); // `finish_grow` is non-generic over `T`. - let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; - self.set_memory(memory); + let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; + self.set_ptr(ptr); Ok(()) } @@ -445,30 +451,24 @@ impl<T, A: AllocRef> RawVec<T, A> { let new_layout = Layout::array::<T>(cap); // `finish_grow` is non-generic over `T`. - let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; - self.set_memory(memory); + let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?; + self.set_ptr(ptr); Ok(()) } - fn shrink( - &mut self, - amount: usize, - placement: ReallocPlacement, - ) -> Result<(), TryReserveError> { + fn shrink(&mut self, amount: usize) -> Result<(), TryReserveError> { assert!(amount <= self.capacity(), "Tried to shrink to a larger capacity"); let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) }; let new_size = amount * mem::size_of::<T>(); - let memory = unsafe { - self.alloc.shrink(ptr, layout, new_size, placement).map_err(|_| { - TryReserveError::AllocError { - layout: Layout::from_size_align_unchecked(new_size, layout.align()), - non_exhaustive: (), - } + let ptr = unsafe { + self.alloc.shrink(ptr, layout, new_size).map_err(|_| TryReserveError::AllocError { + layout: Layout::from_size_align_unchecked(new_size, layout.align()), + non_exhaustive: (), })? }; - self.set_memory(memory); + self.set_ptr(ptr); Ok(()) } } @@ -481,7 +481,7 @@ fn finish_grow<A>( new_layout: Result<Layout, LayoutErr>, current_memory: Option<(NonNull<u8>, Layout)>, alloc: &mut A, -) -> Result<MemoryBlock, TryReserveError> +) -> Result<NonNull<[u8]>, TryReserveError> where A: AllocRef, { @@ -492,9 +492,9 @@ where let memory = if let Some((ptr, old_layout)) = current_memory { debug_assert_eq!(old_layout.align(), new_layout.align()); - unsafe { alloc.grow(ptr, old_layout, new_layout.size(), MayMove, Uninitialized) } + unsafe { alloc.grow(ptr, old_layout, new_layout.size()) } } else { - alloc.alloc(new_layout, Uninitialized) + alloc.alloc(new_layout) } .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?; diff --git a/library/alloc/src/raw_vec/tests.rs b/library/alloc/src/raw_vec/tests.rs index 5408faa079c..cadd913aa6b 100644 --- a/library/alloc/src/raw_vec/tests.rs +++ b/library/alloc/src/raw_vec/tests.rs @@ -20,12 +20,12 @@ fn allocator_param() { fuel: usize, } unsafe impl AllocRef for BoundedAlloc { - fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> { + fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { let size = layout.size(); if size > self.fuel { return Err(AllocErr); } - match Global.alloc(layout, init) { + match Global.alloc(layout) { ok @ Ok(_) => { self.fuel -= size; ok diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 116df63f94b..d0a47ccea0a 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -250,7 +250,7 @@ use core::pin::Pin; use core::ptr::{self, NonNull}; use core::slice::from_raw_parts_mut; -use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout}; +use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout}; use crate::borrow::{Cow, ToOwned}; use crate::string::String; use crate::vec::Vec; @@ -928,12 +928,10 @@ impl<T: ?Sized> Rc<T> { let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align(); // Allocate for the layout. - let mem = Global - .alloc(layout, AllocInit::Uninitialized) - .unwrap_or_else(|_| handle_alloc_error(layout)); + let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the RcBox - let inner = mem_to_rcbox(mem.ptr.as_ptr()); + let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr()); unsafe { debug_assert_eq!(Layout::for_value(&*inner), layout); @@ -2101,7 +2099,7 @@ impl<T: ?Sized> Unpin for Rc<T> {} /// /// - This function is safe for any argument if `T` is sized, and /// - if `T` is unsized, the pointer must have appropriate pointer metadata -/// aquired from the real instance that you are getting this offset for. +/// acquired from the real instance that you are getting this offset for. unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize { // Align the unsized value to the end of the `RcBox`. // Because it is ?Sized, it will always be the last field in memory. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 58cab9c5c63..b3763303137 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -23,7 +23,7 @@ use core::slice::from_raw_parts_mut; use core::sync::atomic; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; -use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout}; +use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout}; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; use crate::rc::is_dangling; @@ -883,12 +883,10 @@ impl<T: ?Sized> Arc<T> { // reference (see #54908). let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align(); - let mem = Global - .alloc(layout, AllocInit::Uninitialized) - .unwrap_or_else(|_| handle_alloc_error(layout)); + let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the ArcInner - let inner = mem_to_arcinner(mem.ptr.as_ptr()); + let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr()); debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout); unsafe { @@ -988,7 +986,7 @@ impl<T> Arc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem.cast(), self.layout); + Global.dealloc(self.mem, self.layout); } } } @@ -2255,7 +2253,7 @@ impl<T: ?Sized> Unpin for Arc<T> {} /// /// - This function is safe for any argument if `T` is sized, and /// - if `T` is unsized, the pointer must have appropriate pointer metadata -/// aquired from the real instance that you are getting this offset for. +/// acquired from the real instance that you are getting this offset for. unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize { // Align the unsized value to the end of the `ArcInner`. // Because it is `?Sized`, it will always be the last field in memory. diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index 5377485da8f..851ca17a365 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -37,7 +37,7 @@ fn box_clone_and_clone_from_equivalence() { /// This test might give a false positive in case the box realocates, but the alocator keeps the /// original pointer. /// -/// On the other hand it won't give a false negative, if it fails than the memory was definitly not +/// On the other hand it won't give a false negative, if it fails than the memory was definitely not /// reused #[test] fn box_clone_from_ptr_stability() { diff --git a/library/alloc/tests/heap.rs b/library/alloc/tests/heap.rs index 62f062b83d7..cbde2a7e28e 100644 --- a/library/alloc/tests/heap.rs +++ b/library/alloc/tests/heap.rs @@ -1,4 +1,4 @@ -use std::alloc::{AllocInit, AllocRef, Global, Layout, System}; +use std::alloc::{AllocRef, Global, Layout, System}; /// Issue #45955 and #62251. #[test] @@ -20,18 +20,12 @@ fn check_overalign_requests<T: AllocRef>(mut allocator: T) { unsafe { let pointers: Vec<_> = (0..iterations) .map(|_| { - allocator - .alloc( - Layout::from_size_align(size, align).unwrap(), - AllocInit::Uninitialized, - ) - .unwrap() - .ptr + allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() }) .collect(); for &ptr in &pointers { assert_eq!( - (ptr.as_ptr() as usize) % align, + (ptr.as_non_null_ptr().as_ptr() as usize) % align, 0, "Got a pointer less aligned than requested" ) @@ -39,7 +33,10 @@ fn check_overalign_requests<T: AllocRef>(mut allocator: T) { // Clean up for &ptr in &pointers { - allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) + allocator.dealloc( + ptr.as_non_null_ptr(), + Layout::from_size_align(size, align).unwrap(), + ) } } } diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index fa20a466715..c680a3fc25b 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -13,6 +13,7 @@ #![feature(associated_type_bounds)] #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_drain_sorted)] +#![feature(slice_ptr_get)] #![feature(split_inclusive)] #![feature(binary_heap_retain)] diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs index 75b76bb73ed..147f7f7d0c7 100644 --- a/library/alloc/tests/slice.rs +++ b/library/alloc/tests/slice.rs @@ -1721,8 +1721,8 @@ fn panic_safe() { let mut rng = thread_rng(); - // Miri is too slow - let lens = if cfg!(miri) { (1..10).chain(20..21) } else { (1..20).chain(70..MAX_LEN) }; + // Miri is too slow (but still need to `chain` to make the types match) + let lens = if cfg!(miri) { (1..10).chain(0..0) } else { (1..20).chain(70..MAX_LEN) }; let moduli: &[u32] = if cfg!(miri) { &[5] } else { &[5, 20, 50] }; for len in lens { diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index be4e051b1ca..2833768f213 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -29,92 +29,6 @@ impl fmt::Display for AllocErr { } } -/// A desired initial state for allocated memory. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[unstable(feature = "allocator_api", issue = "32838")] -pub enum AllocInit { - /// The contents of the new memory are uninitialized. - Uninitialized, - /// The new memory is guaranteed to be zeroed. - Zeroed, -} - -impl AllocInit { - /// Initialize the specified memory block. - /// - /// This behaves like calling [`AllocInit::init_offset(memory, 0)`][off]. - /// - /// [off]: AllocInit::init_offset - /// - /// # Safety - /// - /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes. - /// - /// [valid]: ../../core/ptr/index.html#safety - #[inline] - #[unstable(feature = "allocator_api", issue = "32838")] - pub unsafe fn init(self, memory: MemoryBlock) { - // SAFETY: the safety contract for `init_offset` must be - // upheld by the caller. - unsafe { self.init_offset(memory, 0) } - } - - /// Initialize the memory block like specified by `init` at the specified `offset`. - /// - /// This is a no-op for [`AllocInit::Uninitialized`][] and writes zeroes for - /// [`AllocInit::Zeroed`][] at `ptr + offset` until `ptr + layout.size()`. - /// - /// # Safety - /// - /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes. - /// * `offset` must be smaller than or equal to `memory.size` - /// - /// [valid]: ../../core/ptr/index.html#safety - #[inline] - #[unstable(feature = "allocator_api", issue = "32838")] - pub unsafe fn init_offset(self, memory: MemoryBlock, offset: usize) { - debug_assert!( - offset <= memory.size, - "`offset` must be smaller than or equal to `memory.size`" - ); - match self { - AllocInit::Uninitialized => (), - AllocInit::Zeroed => { - // SAFETY: the caller must guarantee that `offset` is smaller than or equal to `memory.size`, - // so the memory from `memory.ptr + offset` of length `memory.size - offset` - // is guaranteed to be contaned in `memory` and thus valid for writes. - unsafe { memory.ptr.as_ptr().add(offset).write_bytes(0, memory.size - offset) } - } - } - } -} - -/// Represents a block of allocated memory returned by an allocator. -#[derive(Debug, Copy, Clone)] -#[unstable(feature = "allocator_api", issue = "32838")] -pub struct MemoryBlock { - pub ptr: NonNull<u8>, - pub size: usize, -} - -/// A placement constraint when growing or shrinking an existing allocation. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[unstable(feature = "allocator_api", issue = "32838")] -pub enum ReallocPlacement { - /// The allocator is allowed to move the allocation to a different memory address. - // FIXME(wg-allocators#46): Add a section to the module documentation "What is a legal - // allocator" and link it at "valid location". - /// - /// If the allocation _does_ move, it's the responsibility of the allocator - /// to also move the data from the previous location to the new location. - MayMove, - /// The address of the new memory must not change. - /// - /// If the allocation would have to be moved to a new location to fit, the - /// reallocation request will fail. - InPlace, -} - /// An implementation of `AllocRef` can allocate, grow, shrink, and deallocate arbitrary blocks of /// data described via [`Layout`][]. /// @@ -175,12 +89,12 @@ pub enum ReallocPlacement { pub unsafe trait AllocRef { /// Attempts to allocate a block of memory. /// - /// On success, returns a [`MemoryBlock`][] meeting the size and alignment guarantees of `layout`. + /// On success, returns a [`NonNull<[u8]>`] meeting the size and alignment guarantees of `layout`. /// - /// The returned block may have a larger size than specified by `layout.size()` and is - /// initialized as specified by [`init`], all the way up to the returned size of the block. + /// The returned block may have a larger size than specified by `layout.size()`, and may or may + /// not have its contents initialized. /// - /// [`init`]: AllocInit + /// [`NonNull<[u8]>`]: NonNull /// /// # Errors /// @@ -195,7 +109,29 @@ pub unsafe trait AllocRef { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr>; + fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr>; + + /// Behaves like `alloc`, but also ensures that the returned memory is zero-initialized. + /// + /// # Errors + /// + /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet + /// allocator's size or alignment constraints. + /// + /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or + /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement + /// this trait atop an underlying native allocation library that aborts on memory exhaustion.) + /// + /// Clients wishing to abort computation in response to an allocation error are encouraged to + /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. + /// + /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html + fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + let ptr = self.alloc(layout)?; + // SAFETY: `alloc` returns a valid memory block + unsafe { ptr.as_non_null_ptr().as_ptr().write_bytes(0, ptr.len()) } + Ok(ptr) + } /// Deallocates the memory referenced by `ptr`. /// @@ -210,44 +146,100 @@ pub unsafe trait AllocRef { /// Attempts to extend the memory block. /// - /// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated + /// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s /// alignment and a size given by `new_size`. To accomplish this, the allocator may extend the - /// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is - /// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`. - /// - /// If [`MayMove`] is used then ownership of the memory block referenced by `ptr` - /// is transferred to this allocator. The memory may or may not be freed, and should be - /// considered unusable (unless of course it is transferred back to the caller again via the - /// return value of this method). + /// allocation referenced by `ptr` to fit the new layout. /// /// If this method returns `Err`, then ownership of the memory block has not been transferred to /// this allocator, and the contents of the memory block are unaltered. /// - /// The memory block will contain the following contents after a successful call to `grow`: + /// [`NonNull<[u8]>`]: NonNull + /// + /// # Safety + /// + /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator, + /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), + /// * `new_size` must be greater than or equal to `layout.size()`, and + /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow + /// (i.e., the rounded value must be less than or equal to `usize::MAX`). + // Note: We can't require that `new_size` is strictly greater than `layout.size()` because of ZSTs. + // alternative: `new_size` must be strictly greater than `layout.size()` or both are zero + /// + /// [*currently allocated*]: #currently-allocated-memory + /// [*fit*]: #memory-fitting + /// + /// # Errors + /// + /// Returns `Err` if the new layout does not meet the allocator's size and alignment + /// constraints of the allocator, or if growing otherwise fails. + /// + /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or + /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement + /// this trait atop an underlying native allocation library that aborts on memory exhaustion.) + /// + /// Clients wishing to abort computation in response to an allocation error are encouraged to + /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. + /// + /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html + unsafe fn grow( + &mut self, + ptr: NonNull<u8>, + layout: Layout, + new_size: usize, + ) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + debug_assert!( + new_size >= size, + "`new_size` must be greater than or equal to `layout.size()`" + ); + + if size == new_size { + return Ok(NonNull::slice_from_raw_parts(ptr, size)); + } + + let new_layout = + // SAFETY: the caller must ensure that the `new_size` does not overflow. + // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout. + // The caller must ensure that `new_size` is greater than or equal to zero. If it's equal + // to zero, it's catched beforehand. + unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + let new_ptr = self.alloc(new_layout)?; + + // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new + // memory allocation are valid for reads and writes for `size` bytes. Also, because the old + // allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to + // `copy_nonoverlapping` is safe. + // The safety contract for `dealloc` must be upheld by the caller. + unsafe { + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_non_null_ptr().as_ptr(), size); + self.dealloc(ptr, layout); + Ok(new_ptr) + } + } + + /// Behaves like `grow`, but also ensures that the new contents are set to zero before being + /// returned. + /// + /// The memory block will contain the following contents after a successful call to + /// `grow_zeroed`: /// * Bytes `0..layout.size()` are preserved from the original allocation. - /// * Bytes `layout.size()..old_size` will either be preserved or initialized according to - /// [`init`], depending on the allocator implementation. `old_size` refers to the size of - /// the `MemoryBlock` prior to the `grow` call, which may be larger than the size + /// * Bytes `layout.size()..old_size` will either be preserved or zeroed, + /// depending on the allocator implementation. `old_size` refers to the size of + /// the `MemoryBlock` prior to the `grow_zeroed` call, which may be larger than the size /// that was originally requested when it was allocated. - /// * Bytes `old_size..new_size` are initialized according to [`init`]. `new_size` refers to + /// * Bytes `old_size..new_size` are zeroed. `new_size` refers to /// the size of the `MemoryBlock` returned by the `grow` call. /// - /// [`InPlace`]: ReallocPlacement::InPlace - /// [`MayMove`]: ReallocPlacement::MayMove - /// [`placement`]: ReallocPlacement - /// [`init`]: AllocInit - /// /// # Safety /// /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator, /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), - // We can't require that `new_size` is strictly greater than `memory.size` because of ZSTs. - // An alternative would be - // * `new_size must be strictly greater than `memory.size` or both are zero /// * `new_size` must be greater than or equal to `layout.size()`, and /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow /// (i.e., the rounded value must be less than or equal to `usize::MAX`). + // Note: We can't require that `new_size` is strictly greater than `layout.size()` because of ZSTs. + // alternative: `new_size` must be strictly greater than `layout.size()` or both are zero /// /// [*currently allocated*]: #currently-allocated-memory /// [*fit*]: #memory-fitting @@ -265,55 +257,48 @@ pub unsafe trait AllocRef { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - unsafe fn grow( + unsafe fn grow_zeroed( &mut self, ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - init: AllocInit, - ) -> Result<MemoryBlock, AllocErr> { - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove => { - let size = layout.size(); - debug_assert!( - new_size >= size, - "`new_size` must be greater than or equal to `layout.size()`" - ); + ) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + debug_assert!( + new_size >= size, + "`new_size` must be greater than or equal to `layout.size()`" + ); - if new_size == size { - return Ok(MemoryBlock { ptr, size }); - } + if size == new_size { + return Ok(NonNull::slice_from_raw_parts(ptr, size)); + } - let new_layout = - // SAFETY: the caller must ensure that the `new_size` does not overflow. - // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout. - // The caller must ensure that `new_size` is greater than zero. - unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; - let new_memory = self.alloc(new_layout, init)?; + let new_layout = + // SAFETY: the caller must ensure that the `new_size` does not overflow. + // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout. + // The caller must ensure that `new_size` is greater than or equal to zero. If it's equal + // to zero, it's caught beforehand. + unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + let new_ptr = self.alloc_zeroed(new_layout)?; - // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new - // memory allocation are valid for reads and writes for `size` bytes. Also, because the old - // allocation wasn't yet deallocated, it cannot overlap `new_memory`. Thus, the call to - // `copy_nonoverlapping` is safe. - // The safety contract for `dealloc` must be upheld by the caller. - unsafe { - ptr::copy_nonoverlapping(ptr.as_ptr(), new_memory.ptr.as_ptr(), size); - self.dealloc(ptr, layout); - Ok(new_memory) - } - } + // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new + // memory allocation are valid for reads and writes for `size` bytes. Also, because the old + // allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to + // `copy_nonoverlapping` is safe. + // The safety contract for `dealloc` must be upheld by the caller. + unsafe { + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_non_null_ptr().as_ptr(), size); + self.dealloc(ptr, layout); + Ok(new_ptr) } } /// Attempts to shrink the memory block. /// - /// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated + /// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s /// alignment and a size given by `new_size`. To accomplish this, the allocator may shrink the - /// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is - /// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`. + /// allocation referenced by `ptr` to fit the new layout. /// /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been /// transferred to this allocator. The memory may or may not have been freed, and should be @@ -323,19 +308,15 @@ pub unsafe trait AllocRef { /// If this method returns `Err`, then ownership of the memory block has not been transferred to /// this allocator, and the contents of the memory block are unaltered. /// - /// The behavior of how the allocator tries to shrink the memory is specified by [`placement`]. - /// - /// [`InPlace`]: ReallocPlacement::InPlace - /// [`placement`]: ReallocPlacement + /// [`NonNull<[u8]>`]: NonNull /// /// # Safety /// /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator, /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), and - // We can't require that `new_size` is strictly smaller than `memory.size` because of ZSTs. - // An alternative would be - // * `new_size must be strictly smaller than `memory.size` or both are zero /// * `new_size` must be smaller than or equal to `layout.size()`. + // Note: We can't require that `new_size` is strictly smaller than `layout.size()` because of ZSTs. + // alternative: `new_size` must be smaller than `layout.size()` or both are zero /// /// [*currently allocated*]: #currently-allocated-memory /// [*fit*]: #memory-fitting @@ -358,39 +339,33 @@ pub unsafe trait AllocRef { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - ) -> Result<MemoryBlock, AllocErr> { - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove => { - let size = layout.size(); - debug_assert!( - new_size <= size, - "`new_size` must be smaller than or equal to `layout.size()`" - ); + ) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + debug_assert!( + new_size <= size, + "`new_size` must be smaller than or equal to `layout.size()`" + ); - if new_size == size { - return Ok(MemoryBlock { ptr, size }); - } + if size == new_size { + return Ok(NonNull::slice_from_raw_parts(ptr, size)); + } - let new_layout = - // SAFETY: the caller must ensure that the `new_size` does not overflow. - // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout. - // The caller must ensure that `new_size` is greater than zero. - unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; - let new_memory = self.alloc(new_layout, AllocInit::Uninitialized)?; + let new_layout = + // SAFETY: the caller must ensure that the `new_size` does not overflow. + // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout. + // The caller must ensure that `new_size` is greater than zero. + unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + let new_ptr = self.alloc(new_layout)?; - // SAFETY: because `new_size` must be lower than or equal to `size`, both the old and new - // memory allocation are valid for reads and writes for `new_size` bytes. Also, because the - // old allocation wasn't yet deallocated, it cannot overlap `new_memory`. Thus, the call to - // `copy_nonoverlapping` is safe. - // The safety contract for `dealloc` must be upheld by the caller. - unsafe { - ptr::copy_nonoverlapping(ptr.as_ptr(), new_memory.ptr.as_ptr(), new_size); - self.dealloc(ptr, layout); - Ok(new_memory) - } - } + // SAFETY: because `new_size` must be lower than or equal to `size`, both the old and new + // memory allocation are valid for reads and writes for `new_size` bytes. Also, because the + // old allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to + // `copy_nonoverlapping` is safe. + // The safety contract for `dealloc` must be upheld by the caller. + unsafe { + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_non_null_ptr().as_ptr(), size); + self.dealloc(ptr, layout); + Ok(new_ptr) } } @@ -409,8 +384,13 @@ where A: AllocRef + ?Sized, { #[inline] - fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> { - (**self).alloc(layout, init) + fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + (**self).alloc(layout) + } + + #[inline] + fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + (**self).alloc_zeroed(layout) } #[inline] @@ -425,11 +405,20 @@ where ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - init: AllocInit, - ) -> Result<MemoryBlock, AllocErr> { + ) -> Result<NonNull<[u8]>, AllocErr> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow(ptr, layout, new_size) } + } + + #[inline] + unsafe fn grow_zeroed( + &mut self, + ptr: NonNull<u8>, + layout: Layout, + new_size: usize, + ) -> Result<NonNull<[u8]>, AllocErr> { // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).grow(ptr, layout, new_size, placement, init) } + unsafe { (**self).grow_zeroed(ptr, layout, new_size) } } #[inline] @@ -438,9 +427,8 @@ where ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - ) -> Result<MemoryBlock, AllocErr> { + ) -> Result<NonNull<[u8]>, AllocErr> { // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).shrink(ptr, layout, new_size, placement) } + unsafe { (**self).shrink(ptr, layout, new_size) } } } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 51d9695687f..cbbfcb46113 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -788,6 +788,7 @@ impl<T: ?Sized> RefCell<T> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[track_caller] pub fn borrow(&self) -> Ref<'_, T> { self.try_borrow().expect("already mutably borrowed") } @@ -863,6 +864,7 @@ impl<T: ?Sized> RefCell<T> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[track_caller] pub fn borrow_mut(&self) -> RefMut<'_, T> { self.try_borrow_mut().expect("already borrowed") } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 44b86438f2a..3a28bc79eff 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1950,15 +1950,20 @@ extern "rust-intrinsic" { pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize; /// Internal placeholder for injecting code coverage counters when the "instrument-coverage" - /// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code - /// generation. + /// option is enabled. The source code region information is extracted prior to code generation, + /// and added to the "coverage map", which is injected into the generated code as additional + /// data. This intrinsic then triggers the generation of LLVM intrinsic call + /// `instrprof.increment`, using the remaining args (`function_source_hash` and `index`). #[cfg(not(bootstrap))] #[lang = "count_code_region"] pub fn count_code_region( function_source_hash: u64, index: u32, - start_byte_pos: u32, - end_byte_pos: u32, + file_name: &'static str, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, ); /// Internal marker for code coverage expressions, injected into the MIR when the @@ -1973,8 +1978,11 @@ extern "rust-intrinsic" { index: u32, left_index: u32, right_index: u32, - start_byte_pos: u32, - end_byte_pos: u32, + file_name: &'static str, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, ); /// This marker identifies a code region and two other counters or counter expressions @@ -1986,14 +1994,24 @@ extern "rust-intrinsic" { index: u32, left_index: u32, right_index: u32, - start_byte_pos: u32, - end_byte_pos: u32, + file_name: &'static str, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, ); /// This marker identifies a code region to be added to the "coverage map" to indicate source /// code that can never be reached. /// (See `coverage_counter_add` for more information.) - pub fn coverage_unreachable(start_byte_pos: u32, end_byte_pos: u32); + #[cfg(not(bootstrap))] + pub fn coverage_unreachable( + file_name: &'static str, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ); /// See documentation of `<*const T>::guaranteed_eq` for details. #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 048c9c5ddaa..eb50dc28b9f 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1602,6 +1602,29 @@ $EndFeature, " } doc_comment! { + concat!("Computes the absolute value of `self` without any wrapping +or panicking. + + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(unsigned_abs)] +assert_eq!(100", stringify!($SelfT), ".unsigned_abs(), 100", stringify!($UnsignedT), "); +assert_eq!((-100", stringify!($SelfT), ").unsigned_abs(), 100", stringify!($UnsignedT), "); +assert_eq!((-128i8).unsigned_abs(), 128u8);", +$EndFeature, " +```"), + #[unstable(feature = "unsigned_abs", issue = "74913")] + #[inline] + pub const fn unsigned_abs(self) -> $UnsignedT { + self.wrapping_abs() as $UnsignedT + } + } + + doc_comment! { concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`, wrapping around at the boundary of the type. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 0c0e6d291bb..e68dbf5215f 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1145,7 +1145,6 @@ impl<T, E: Into<!>> Result<T, E> { } } -#[unstable(feature = "inner_deref", issue = "50264")] impl<T: Deref, E> Result<T, E> { /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&<T as Deref>::Target, &E>`. /// @@ -1155,7 +1154,6 @@ impl<T: Deref, E> Result<T, E> { /// # Examples /// /// ``` - /// #![feature(inner_deref)] /// let x: Result<String, u32> = Ok("hello".to_string()); /// let y: Result<&str, &u32> = Ok("hello"); /// assert_eq!(x.as_deref(), y); @@ -1164,23 +1162,12 @@ impl<T: Deref, E> Result<T, E> { /// let y: Result<&str, &u32> = Err(&42); /// assert_eq!(x.as_deref(), y); /// ``` + #[stable(feature = "inner_deref", since = "1.47.0")] pub fn as_deref(&self) -> Result<&T::Target, &E> { self.as_ref().map(|t| t.deref()) } } -#[unstable(feature = "inner_deref", issue = "50264")] -impl<T, E: Deref> Result<T, E> { - /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &<E as Deref>::Target>`. - /// - /// Coerces the [`Err`] variant of the original [`Result`] via [`Deref`](crate::ops::Deref) - /// and returns the new [`Result`]. - pub fn as_deref_err(&self) -> Result<&T, &E::Target> { - self.as_ref().map_err(|e| e.deref()) - } -} - -#[unstable(feature = "inner_deref", issue = "50264")] impl<T: DerefMut, E> Result<T, E> { /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut <T as DerefMut>::Target, &mut E>`. /// @@ -1190,7 +1177,6 @@ impl<T: DerefMut, E> Result<T, E> { /// # Examples /// /// ``` - /// #![feature(inner_deref)] /// let mut s = "HELLO".to_string(); /// let mut x: Result<String, u32> = Ok("hello".to_string()); /// let y: Result<&mut str, &mut u32> = Ok(&mut s); @@ -1201,22 +1187,12 @@ impl<T: DerefMut, E> Result<T, E> { /// let y: Result<&mut str, &mut u32> = Err(&mut i); /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); /// ``` + #[stable(feature = "inner_deref", since = "1.47.0")] pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> { self.as_mut().map(|t| t.deref_mut()) } } -#[unstable(feature = "inner_deref", issue = "50264")] -impl<T, E: DerefMut> Result<T, E> { - /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut <E as DerefMut>::Target>`. - /// - /// Coerces the [`Err`] variant of the original [`Result`] via [`DerefMut`](crate::ops::DerefMut) - /// and returns the new [`Result`]. - pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> { - self.as_mut().map_err(|e| e.deref_mut()) - } -} - impl<T, E> Result<Option<T>, E> { /// Transposes a `Result` of an `Option` into an `Option` of a `Result`. /// diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 6b28a815f03..b4c299d3905 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -27,7 +27,6 @@ #![feature(test)] #![feature(trusted_len)] #![feature(try_trait)] -#![feature(inner_deref)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] #![feature(int_error_matching)] diff --git a/library/core/tests/num/flt2dec/random.rs b/library/core/tests/num/flt2dec/random.rs index 0ebc0881f52..e5656eb204c 100644 --- a/library/core/tests/num/flt2dec/random.rs +++ b/library/core/tests/num/flt2dec/random.rs @@ -188,7 +188,7 @@ fn exact_f32_random_equivalence_test() { fn exact_f64_random_equivalence_test() { use core::num::flt2dec::strategy::dragon::format_exact as fallback; // Miri is too slow - let n = if cfg!(miri) { 3 } else { 1_000 }; + let n = if cfg!(miri) { 2 } else { 1_000 }; for k in 1..21 { f64_random_equivalence_test( diff --git a/library/core/tests/num/flt2dec/strategy/grisu.rs b/library/core/tests/num/flt2dec/strategy/grisu.rs index ff8373c6455..7e6c8add333 100644 --- a/library/core/tests/num/flt2dec/strategy/grisu.rs +++ b/library/core/tests/num/flt2dec/strategy/grisu.rs @@ -2,6 +2,7 @@ use super::super::*; use core::num::flt2dec::strategy::grisu::*; #[test] +#[cfg_attr(miri, ignore)] // Miri is too slow fn test_cached_power() { assert_eq!(CACHED_POW10.first().unwrap().1, CACHED_POW10_FIRST_E); assert_eq!(CACHED_POW10.last().unwrap().1, CACHED_POW10_LAST_E); diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs index c835313aae7..caa2d916cd7 100644 --- a/library/core/tests/result.rs +++ b/library/core/tests/result.rs @@ -250,24 +250,11 @@ fn test_result_as_deref() { let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); assert_eq!(ref_ok.as_deref(), expected_result); - // &Result<T, E: Deref>::Err(T).as_deref_err() -> - // Result<&T, &E::Deref::Target>::Err(&*E) - let ref_err = &Result::Err::<u8, &i32>(&41); - let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.as_deref_err(), expected_result); - - let ref_err = &Result::Err::<u32, String>(String::from("an error")); - let expected_result = Result::Err::<&u32, &str>("an error"); - assert_eq!(ref_err.as_deref_err(), expected_result); - - let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice()); - assert_eq!(ref_err.as_deref_err(), expected_result); - - // &Result<T: Deref, E: Deref>::Err(T).as_deref_err() -> - // Result<&T, &E::Deref::Target>::Err(&*E) - let ref_err = &Result::Err::<&u8, &i32>(&41); - let expected_result = Result::Err::<&u8, &&i32>(&&41); + // &Result<T: Deref, E>::Err(T).as_deref() -> + // Result<&T::Deref::Target, &E>::Err(&*E) + let val = 41; + let ref_err = &Result::Err::<&u8, i32>(val); + let expected_result = Result::Err::<&u8, &i32>(&val); assert_eq!(ref_err.as_deref(), expected_result); let s = String::from("an error"); @@ -279,46 +266,12 @@ fn test_result_as_deref() { let ref_err = &Result::Err::<&u32, Vec<i32>>(v.clone()); let expected_result = Result::Err::<&u32, &Vec<i32>>(&v); assert_eq!(ref_err.as_deref(), expected_result); - - // The following cases test calling `as_deref_*` with the wrong variant (i.e. - // `as_deref()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`. - // While uncommon, these cases are supported to ensure that an `as_deref_*` - // call can still be made even when one of the Result types does not implement - // `Deref` (for example, std::io::Error). - - // &Result<T, E: Deref>::Ok(T).as_deref_err() -> - // Result<&T, &E::Deref::Target>::Ok(&T) - let ref_ok = &Result::Ok::<i32, &u8>(42); - let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.as_deref_err(), expected_result); - - let ref_ok = &Result::Ok::<&str, &u32>("a result"); - let expected_result = Result::Ok::<&&str, &u32>(&"a result"); - assert_eq!(ref_ok.as_deref_err(), expected_result); - - let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]); - let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]); - assert_eq!(ref_ok.as_deref_err(), expected_result); - - // &Result<T: Deref, E>::Err(E).as_deref() -> - // Result<&T::Deref::Target, &E>::Err(&E) - let ref_err = &Result::Err::<&u8, i32>(41); - let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.as_deref(), expected_result); - - let ref_err = &Result::Err::<&u32, &str>("an error"); - let expected_result = Result::Err::<&u32, &&str>(&"an error"); - assert_eq!(ref_err.as_deref(), expected_result); - - let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]); - assert_eq!(ref_err.as_deref(), expected_result); } #[test] fn test_result_as_deref_mut() { - // &mut Result<T: Deref, E>::Ok(T).as_deref_mut() -> - // Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T) + // &mut Result<T: DerefMut, E>::Ok(T).as_deref_mut() -> + // Result<&mut T::DerefMut::Target, &mut E>::Ok(&mut *T) let mut val = 42; let mut expected_val = 42; let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val); @@ -335,26 +288,8 @@ fn test_result_as_deref_mut() { let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); assert_eq!(mut_ok.as_deref_mut(), expected_result); - // &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() -> - // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) - let mut val = 41; - let mut expected_val = 41; - let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val); - let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); - assert_eq!(mut_err.as_deref_mut_err(), expected_result); - - let mut expected_string = String::from("an error"); - let mut_err = &mut Result::Err::<u32, String>(expected_string.clone()); - let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut()); - assert_eq!(mut_err.as_deref_mut_err(), expected_result); - - let mut expected_vec = vec![5, 4, 3, 2, 1]; - let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone()); - let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice()); - assert_eq!(mut_err.as_deref_mut_err(), expected_result); - - // &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() -> - // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) + // &mut Result<T: DerefMut, E>::Err(T).as_deref_mut() -> + // Result<&mut T, &mut E>::Err(&mut *E) let mut val = 41; let mut_err = &mut Result::Err::<&mut u8, i32>(val); let expected_result = Result::Err::<&mut u8, &mut i32>(&mut val); @@ -369,48 +304,4 @@ fn test_result_as_deref_mut() { let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone()); let expected_result = Result::Err::<&mut u32, &mut Vec<i32>>(&mut expected_vec); assert_eq!(mut_err.as_deref_mut(), expected_result); - - // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e. - // `as_deref_mut()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`. - // While uncommon, these cases are supported to ensure that an `as_deref_mut_*` - // call can still be made even when one of the Result types does not implement - // `Deref` (for example, std::io::Error). - - // &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() -> - // Result<&mut T, &mut E::Deref::Target>::Ok(&mut T) - let mut expected_val = 42; - let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone()); - let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); - assert_eq!(mut_ok.as_deref_mut_err(), expected_result); - - let string = String::from("a result"); - let expected_string = string.clone(); - let mut ref_str = expected_string.as_ref(); - let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str()); - let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str); - assert_eq!(mut_ok.as_deref_mut_err(), expected_result); - - let mut expected_arr = [1, 2, 3, 4, 5]; - let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone()); - let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr); - assert_eq!(mut_ok.as_deref_mut_err(), expected_result); - - // &mut Result<T: Deref, E>::Err(E).as_deref_mut() -> - // Result<&mut T::Deref::Target, &mut E>::Err(&mut E) - let mut expected_val = 41; - let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone()); - let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); - assert_eq!(mut_err.as_deref_mut(), expected_result); - - let string = String::from("an error"); - let expected_string = string.clone(); - let mut ref_str = expected_string.as_ref(); - let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str()); - let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str); - assert_eq!(mut_err.as_deref_mut(), expected_result); - - let mut expected_arr = [5, 4, 3, 2, 1]; - let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone()); - let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr); - assert_eq!(mut_err.as_deref_mut(), expected_result); } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 27cc7fce1da..42b483f33ba 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1358,15 +1358,15 @@ fn sort_unstable() { use core::slice::heapsort; use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng}; - // Miri is too slow - let large_range = if cfg!(miri) { 0..0 } else { 500..510 }; + // Miri is too slow (but still need to `chain` to make the types match) + let lens = if cfg!(miri) { (2..20).chain(0..0) } else { (2..25).chain(500..510) }; let rounds = if cfg!(miri) { 1 } else { 100 }; let mut v = [0; 600]; let mut tmp = [0; 600]; let mut rng = StdRng::from_entropy(); - for len in (2..25).chain(large_range) { + for len in lens { let v = &mut v[0..len]; let tmp = &mut tmp[0..len]; diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index c050a3c591c..de3866d92fc 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -24,7 +24,6 @@ #![feature(decl_macro)] #![feature(extern_types)] #![feature(in_band_lifetimes)] -#![feature(inner_deref)] #![feature(negative_impls)] #![feature(optin_builtin_traits)] #![feature(restricted_std)] @@ -849,7 +848,7 @@ impl Ident { /// Creates a new `Ident` with the given `string` as well as the specified /// `span`. /// The `string` argument must be a valid identifier permitted by the - /// language, otherwise the function will panic. + /// language (including keywords, e.g. `self` or `fn`). Otherwise, the function will panic. /// /// Note that `span`, currently in rustc, configures the hygiene information /// for this identifier. @@ -871,7 +870,10 @@ impl Ident { } /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). - #[unstable(feature = "proc_macro_raw_ident", issue = "54723")] + /// The `string` argument be a valid identifier permitted by the language + /// (including keywords, e.g. `fn`). Keywords which are usable in path segments + /// (e.g. `self`, `super`) are not supported, and will cause a panic. + #[stable(feature = "proc_macro_raw_ident", since = "1.47.0")] pub fn new_raw(string: &str, span: Span) -> Ident { Ident(bridge::client::Ident::new(string, span.0, true)) } diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index ecfaaeace51..4712cc95b4a 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -140,28 +140,35 @@ pub struct System; #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl AllocRef for System { #[inline] - fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> { - unsafe { - let size = layout.size(); - if size == 0 { - Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) - } else { - let raw_ptr = match init { - AllocInit::Uninitialized => GlobalAlloc::alloc(self, layout), - AllocInit::Zeroed => GlobalAlloc::alloc_zeroed(self, layout), - }; - let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; - Ok(MemoryBlock { ptr, size }) - } - } + fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + let ptr = if size == 0 { + layout.dangling() + } else { + // SAFETY: `layout` is non-zero in size, + unsafe { NonNull::new(GlobalAlloc::alloc(&System, layout)).ok_or(AllocErr)? } + }; + Ok(NonNull::slice_from_raw_parts(ptr, size)) + } + + #[inline] + fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> { + let size = layout.size(); + let ptr = if size == 0 { + layout.dangling() + } else { + // SAFETY: `layout` is non-zero in size, + unsafe { NonNull::new(GlobalAlloc::alloc_zeroed(&System, layout)).ok_or(AllocErr)? } + }; + Ok(NonNull::slice_from_raw_parts(ptr, size)) } #[inline] unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) { if layout.size() != 0 { - // SAFETY: The safety guarantees are explained in the documentation - // for the `GlobalAlloc` trait and its `dealloc` method. - unsafe { GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) } + // SAFETY: `layout` is non-zero in size, + // other conditions must be upheld by the caller + unsafe { GlobalAlloc::dealloc(&System, ptr.as_ptr(), layout) } } } @@ -171,53 +178,59 @@ unsafe impl AllocRef for System { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - init: AllocInit, - ) -> Result<MemoryBlock, AllocErr> { - let size = layout.size(); + ) -> Result<NonNull<[u8]>, AllocErr> { debug_assert!( - new_size >= size, - "`new_size` must be greater than or equal to `memory.size()`" + new_size >= layout.size(), + "`new_size` must be greater than or equal to `layout.size()`" ); - if size == new_size { - return Ok(MemoryBlock { ptr, size }); + // SAFETY: `new_size` must be non-zero, which is checked in the match expression. + // Other conditions must be upheld by the caller + unsafe { + match layout.size() { + old_size if old_size == new_size => { + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } + 0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())), + old_size => { + // `realloc` probably checks for `new_size > size` or something similar. + intrinsics::assume(new_size > old_size); + let raw_ptr = GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size); + let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } + } } + } - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove if layout.size() == 0 => { - let new_layout = - // SAFETY: The new size and layout alignement guarantees - // are transfered to the caller (they come from parameters). - // - // See the preconditions for `Layout::from_size_align` to - // see what must be checked. - unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; - self.alloc(new_layout, init) - } - ReallocPlacement::MayMove => { - // SAFETY: - // - // The safety guarantees are explained in the documentation - // for the `GlobalAlloc` trait and its `dealloc` method. - // - // `realloc` probably checks for `new_size > size` or something - // similar. - // - // For the guarantees about `init_offset`, see its documentation: - // `ptr` is assumed valid (and checked for non-NUL) and - // `memory.size` is set to `new_size` so the offset being `size` - // is valid. - let memory = unsafe { - intrinsics::assume(new_size > size); - let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size); - let memory = - MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }; - init.init_offset(memory, size); - memory - }; - Ok(memory) + #[inline] + unsafe fn grow_zeroed( + &mut self, + ptr: NonNull<u8>, + layout: Layout, + new_size: usize, + ) -> Result<NonNull<[u8]>, AllocErr> { + debug_assert!( + new_size >= layout.size(), + "`new_size` must be greater than or equal to `layout.size()`" + ); + + // SAFETY: `new_size` must be non-zero, which is checked in the match expression. + // Other conditions must be upheld by the caller + unsafe { + match layout.size() { + old_size if old_size == new_size => { + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } + 0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())), + old_size => { + // `realloc` probably checks for `new_size > size` or something similar. + intrinsics::assume(new_size > old_size); + let raw_ptr = GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size); + raw_ptr.add(old_size).write_bytes(0, new_size - old_size); + let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + } } } } @@ -228,45 +241,34 @@ unsafe impl AllocRef for System { ptr: NonNull<u8>, layout: Layout, new_size: usize, - placement: ReallocPlacement, - ) -> Result<MemoryBlock, AllocErr> { - let size = layout.size(); + ) -> Result<NonNull<[u8]>, AllocErr> { + let old_size = layout.size(); debug_assert!( - new_size <= size, - "`new_size` must be smaller than or equal to `memory.size()`" + new_size <= old_size, + "`new_size` must be smaller than or equal to `layout.size()`" ); - if size == new_size { - return Ok(MemoryBlock { ptr, size }); - } - - match placement { - ReallocPlacement::InPlace => Err(AllocErr), - ReallocPlacement::MayMove if new_size == 0 => { - // SAFETY: see `GlobalAlloc::dealloc` for the guarantees that - // must be respected. `ptr` and `layout` are parameters and so - // those guarantees must be checked by the caller. - unsafe { self.dealloc(ptr, layout) }; - Ok(MemoryBlock { ptr: layout.dangling(), size: 0 }) + let ptr = if new_size == old_size { + ptr + } else if new_size == 0 { + // SAFETY: `layout` is non-zero in size as `old_size` != `new_size` + // Other conditions must be upheld by the caller + unsafe { + self.dealloc(ptr, layout); } - ReallocPlacement::MayMove => { - // SAFETY: - // - // See `GlobalAlloc::realloc` for more informations about the - // guarantees expected by this method. `ptr`, `layout` and - // `new_size` are parameters and the responsability for their - // correctness is left to the caller. - // - // `realloc` probably checks for `new_size < size` or something - // similar. - let memory = unsafe { - intrinsics::assume(new_size < size); - let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size); - MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size } - }; - Ok(memory) - } - } + layout.dangling() + } else { + // SAFETY: new_size is not zero, + // Other conditions must be upheld by the caller + let raw_ptr = unsafe { + // `realloc` probably checks for `new_size < old_size` or something similar. + intrinsics::assume(new_size < old_size); + GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size) + }; + NonNull::new(raw_ptr).ok_or(AllocErr)? + }; + + Ok(NonNull::slice_from_raw_parts(ptr, new_size)) } } static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 1fa438747c1..c98008688ab 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1363,7 +1363,7 @@ mod self_upper_keyword {} /// /// let r1 = &FOO as *const _; /// let r2 = &FOO as *const _; -/// // With a strictly read-only static, references will have the same adress +/// // With a strictly read-only static, references will have the same address /// assert_eq!(r1, r2); /// // A static item can be used just like a variable in many cases /// println!("{:?}", FOO); diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c81b949af65..0569e46241a 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -291,6 +291,7 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(nll)] +#![feature(nonnull_slice_from_raw_parts)] #![feature(once_cell)] #![feature(optin_builtin_traits)] #![feature(or_patterns)] @@ -308,6 +309,8 @@ #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] +#![feature(slice_ptr_get)] +#![feature(slice_ptr_len)] #![feature(slice_strip)] #![feature(staged_api)] #![feature(std_internals)] diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 64260990824..714ec3e8786 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -81,7 +81,7 @@ // see the changes to drop the `Waiter` struct correctly. // * There is one place where the two atomics `Once.state_and_queue` and // `Waiter.signaled` come together, and might be reordered by the compiler or -// processor. Because both use Aquire ordering such a reordering is not +// processor. Because both use Acquire ordering such a reordering is not // allowed, so no need for SeqCst. use crate::cell::Cell; diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 84c4d662161..e36a53084ba 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -3,6 +3,8 @@ use crate::cmp; use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read}; use crate::mem; +#[cfg(not(any(target_os = "redox", target_env = "newlib")))] +use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::cvt; use crate::sys_common::AsInner; @@ -26,6 +28,27 @@ const READ_LIMIT: usize = c_int::MAX as usize - 1; #[cfg(not(target_os = "macos"))] const READ_LIMIT: usize = libc::ssize_t::MAX as usize; +#[cfg(not(any(target_os = "redox", target_env = "newlib")))] +fn max_iov() -> usize { + static LIM: AtomicUsize = AtomicUsize::new(0); + + let mut lim = LIM.load(Ordering::Relaxed); + if lim == 0 { + let ret = unsafe { libc::sysconf(libc::_SC_IOV_MAX) }; + + // 16 is the minimum value required by POSIX. + lim = if ret > 0 { ret as usize } else { 16 }; + LIM.store(lim, Ordering::Relaxed); + } + + lim +} + +#[cfg(any(target_os = "redox", target_env = "newlib"))] +fn max_iov() -> usize { + 16 // The minimum value required by POSIX. +} + impl FileDesc { pub fn new(fd: c_int) -> FileDesc { FileDesc { fd } @@ -54,7 +77,7 @@ impl FileDesc { libc::readv( self.fd, bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::MAX as usize) as c_int, + cmp::min(bufs.len(), max_iov()) as c_int, ) })?; Ok(ret as usize) @@ -111,7 +134,7 @@ impl FileDesc { libc::writev( self.fd, bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::MAX as usize) as c_int, + cmp::min(bufs.len(), max_iov()) as c_int, ) })?; Ok(ret as usize) @@ -256,3 +279,16 @@ impl Drop for FileDesc { let _ = unsafe { libc::close(self.fd) }; } } + +#[cfg(test)] +mod tests { + use super::{FileDesc, IoSlice}; + + #[test] + fn limit_vector_count() { + let stdout = FileDesc { fd: 1 }; + let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>(); + + assert!(stdout.write_vectored(&bufs).is_ok()); + } +} diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 2eed9e436a9..6782d845bb0 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -331,6 +331,7 @@ impl OpenOptions { // FIXME: some of these should probably be read-only or write-only... base |= wasi::RIGHTS_FD_ADVISE; base |= wasi::RIGHTS_FD_FDSTAT_SET_FLAGS; + base |= wasi::RIGHTS_FD_FILESTAT_GET; base |= wasi::RIGHTS_FD_FILESTAT_SET_TIMES; base |= wasi::RIGHTS_FD_SEEK; base |= wasi::RIGHTS_FD_SYNC; diff --git a/library/stdarch b/library/stdarch -Subproject 311d56cd91609c1c1c0370cbd2ece8e3048653a +Subproject 78891cdf292c23278ca8723bd54310024915960 diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index d6649d0521c..4dd71ebade1 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -171,7 +171,9 @@ fn main() { // note: everything below here is unreachable. do not put code that // should run on success, after this block. } - println!("\nDid not run successfully: {}\n{:?}\n-------------", status, cmd); + if verbose > 0 { + println!("\nDid not run successfully: {}\n{:?}\n-------------", status, cmd); + } if let Some(mut on_fail) = on_fail { on_fail.status().expect("Could not run the on_fail command"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 144e146685f..e13a5f24653 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1037,7 +1037,7 @@ impl<'a> Builder<'a> { } } - // FIXME: Don't use LLD if we're compiling libtest, since it fails to link it. + // FIXME: Don't use LLD with MSVC if we're compiling libtest, since it fails to link it. // See https://github.com/rust-lang/rust/issues/68647. let can_use_lld = mode != Mode::Std; @@ -1049,6 +1049,11 @@ impl<'a> Builder<'a> { let target = crate::envify(&target.triple); cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker); } + + if self.config.use_lld && !target.contains("msvc") { + rustflags.arg("-Clink-args=-fuse-ld=lld"); + } + if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc { cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler)); } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a4a1d5193b9..98b6be29c07 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1355,7 +1355,7 @@ pub struct RustAnalyzer { } impl Step for RustAnalyzer { - type Output = PathBuf; + type Output = Option<PathBuf>; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -1373,11 +1373,17 @@ impl Step for RustAnalyzer { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Option<PathBuf> { let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); + if target.contains("riscv64") { + // riscv64 currently has an LLVM bug that makes rust-analyzer unable + // to build. See #74813 for details. + return None; + } + let src = builder.src.join("src/tools/rust-analyzer"); let release_num = builder.release_num("rust-analyzer/crates/rust-analyzer"); let name = pkgname(builder, "rust-analyzer"); @@ -1431,7 +1437,7 @@ impl Step for RustAnalyzer { builder.info(&format!("Dist rust-analyzer stage{} ({})", compiler.stage, target)); let _time = timeit(builder); builder.run(&mut cmd); - distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)) + Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) } } @@ -1789,7 +1795,7 @@ impl Step for Extended { tarballs.push(rustc_installer); tarballs.push(cargo_installer); tarballs.extend(rls_installer.clone()); - tarballs.push(rust_analyzer_installer.clone()); + tarballs.extend(rust_analyzer_installer.clone()); tarballs.push(clippy_installer); tarballs.extend(miri_installer.clone()); tarballs.extend(rustfmt_installer.clone()); @@ -1867,7 +1873,9 @@ impl Step for Extended { if rls_installer.is_none() { contents = filter(&contents, "rls"); } - contents = filter(&contents, "rust-analyzer"); + if rust_analyzer_installer.is_none() { + contents = filter(&contents, "rust-analyzer"); + } if miri_installer.is_none() { contents = filter(&contents, "miri"); } @@ -1914,7 +1922,9 @@ impl Step for Extended { if rls_installer.is_some() { prepare("rls"); } - prepare("rust-analyzer"); + if rust_analyzer_installer.is_some() { + prepare("rust-analyzer"); + } if miri_installer.is_some() { prepare("miri"); } @@ -1976,7 +1986,9 @@ impl Step for Extended { if rls_installer.is_some() { prepare("rls"); } - prepare("rust-analyzer"); + if rust_analyzer_installer.is_some() { + prepare("rust-analyzer"); + } if miri_installer.is_some() { prepare("miri"); } @@ -2076,23 +2088,25 @@ impl Step for Extended { .arg(etc.join("msi/remove-duplicates.xsl")), ); } - builder.run( - Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-analyzer") - .args(&heat_flags) - .arg("-cg") - .arg("RustAnalyzerGroup") - .arg("-dr") - .arg("RustAnalyzer") - .arg("-var") - .arg("var.RustAnalyzerDir") - .arg("-out") - .arg(exe.join("RustAnalyzerGroup.wxs")) - .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); + if rust_analyzer_installer.is_some() { + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-analyzer") + .args(&heat_flags) + .arg("-cg") + .arg("RustAnalyzerGroup") + .arg("-dr") + .arg("RustAnalyzer") + .arg("-var") + .arg("var.RustAnalyzerDir") + .arg("-out") + .arg(exe.join("RustAnalyzerGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); + } builder.run( Command::new(&heat) .current_dir(&exe) @@ -2186,7 +2200,9 @@ impl Step for Extended { if rls_installer.is_some() { cmd.arg("-dRlsDir=rls"); } - cmd.arg("-dRustAnalyzerDir=rust-analyzer"); + if rust_analyzer_installer.is_some() { + cmd.arg("-dRustAnalyzerDir=rust-analyzer"); + } if miri_installer.is_some() { cmd.arg("-dMiriDir=miri"); } @@ -2206,7 +2222,9 @@ impl Step for Extended { if rls_installer.is_some() { candle("RlsGroup.wxs".as_ref()); } - candle("RustAnalyzerGroup.wxs".as_ref()); + if rust_analyzer_installer.is_some() { + candle("RustAnalyzerGroup.wxs".as_ref()); + } if miri_installer.is_some() { candle("MiriGroup.wxs".as_ref()); } @@ -2244,7 +2262,9 @@ impl Step for Extended { if rls_installer.is_some() { cmd.arg("RlsGroup.wixobj"); } - cmd.arg("RustAnalyzerGroup.wixobj"); + if rust_analyzer_installer.is_some() { + cmd.arg("RustAnalyzerGroup.wixobj"); + } if miri_installer.is_some() { cmd.arg("MiriGroup.wixobj"); } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2ead5d0a37f..bb5b9296c0a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1158,13 +1158,19 @@ impl Step for Compiletest { cmd.arg("--quiet"); } + let mut llvm_components_passed = false; + let mut copts_passed = false; if builder.config.llvm_enabled() { let llvm_config = builder.ensure(native::Llvm { target: builder.config.build }); if !builder.config.dry_run { let llvm_version = output(Command::new(&llvm_config).arg("--version")); + let llvm_components = output(Command::new(&llvm_config).arg("--components")); // Remove trailing newline from llvm-config output. - let llvm_version = llvm_version.trim_end(); - cmd.arg("--llvm-version").arg(llvm_version); + cmd.arg("--llvm-version") + .arg(llvm_version.trim()) + .arg("--llvm-components") + .arg(llvm_components.trim()); + llvm_components_passed = true; } if !builder.is_rust_llvm(target) { cmd.arg("--system-llvm"); @@ -1182,15 +1188,13 @@ impl Step for Compiletest { // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run && suite == "run-make-fulldeps" { - let llvm_components = output(Command::new(&llvm_config).arg("--components")); cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") .arg(builder.cxx(target).unwrap()) .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc).join(" ")) - .arg("--llvm-components") - .arg(llvm_components.trim()); + .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); + copts_passed = true; if let Some(ar) = builder.ar(target) { cmd.arg("--ar").arg(ar); } @@ -1220,15 +1224,11 @@ impl Step for Compiletest { } } - if suite != "run-make-fulldeps" { - cmd.arg("--cc") - .arg("") - .arg("--cxx") - .arg("") - .arg("--cflags") - .arg("") - .arg("--llvm-components") - .arg(""); + if !llvm_components_passed { + cmd.arg("--llvm-components").arg(""); + } + if !copts_passed { + cmd.arg("--cc").arg("").arg("--cxx").arg("").arg("--cflags").arg(""); } if builder.remote_tested(target) { diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index a7c1987e8b1..0ff77de003d 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -84,6 +84,9 @@ x--expand-yaml-anchors--remove: os: windows-latest-xl <<: *base-job + - &job-aarch64-linux + os: [self-hosted, ARM64, linux] + - &step if: success() && !env.SKIP_JOB @@ -584,8 +587,16 @@ jobs: <<: [*shared-ci-variables, *dummy-variables] if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' strategy: + fail-fast: false matrix: include: + ############################# + # Linux/Docker builders # + ############################# + + - name: aarch64-gnu + <<: *job-aarch64-linux + #################### # macOS Builders # #################### diff --git a/src/ci/scripts/symlink-build-dir.sh b/src/ci/scripts/symlink-build-dir.sh index 50178b9c33e..28d8aa3b6e7 100755 --- a/src/ci/scripts/symlink-build-dir.sh +++ b/src/ci/scripts/symlink-build-dir.sh @@ -12,7 +12,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isWindows && isAzurePipelines; then cmd //c "mkdir c:\\MORE_SPACE" cmd //c "mklink /J build c:\\MORE_SPACE" -elif isLinux && isGitHubActions; then +elif isLinux && isGitHubActions && ! isSelfHostedGitHubActions; then sudo mkdir -p /mnt/more-space sudo chown -R "$(whoami):" /mnt/more-space diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 206065d7072..8222758ed6d 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -38,6 +38,11 @@ function isGitHubActions { [[ "${GITHUB_ACTIONS-false}" = "true" ]] } + +function isSelfHostedGitHubActions { + [[ "${RUST_GHA_SELF_HOSTED-false}" = "true" ]] +} + function isMacOS { [[ "${OSTYPE}" = "darwin"* ]] } diff --git a/src/doc/book b/src/doc/book -Subproject a914f2c7e5cdb771fa465de142381a51c53b580 +Subproject 363293c1c5ce9e84ea3935a5e29ce8624801208 diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject 94d9ea8460bcbbbfef1877b47cb930260b5849a +Subproject b5256448a2a4c1bec68b93c0847066f92f2ff5a diff --git a/src/doc/reference b/src/doc/reference -Subproject b329ce37424874ad4db94f829a55807c6e21d2c +Subproject c9b2736a059469043177e1e4ed41a55d7c63ac2 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject 229c6945a26a53a751ffa4f9cb418388c00029d +Subproject 2e9271981adc32613365810f3428334c0709521 diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs index 9d4b6dbed98..809fda86542 100644 --- a/src/librustc_ast/attr/mod.rs +++ b/src/librustc_ast/attr/mod.rs @@ -100,8 +100,8 @@ impl NestedMetaItem { } /// Returns `true` if this list item is a MetaItem with a name of `name`. - pub fn check_name(&self, name: Symbol) -> bool { - self.meta_item().map_or(false, |meta_item| meta_item.check_name(name)) + pub fn has_name(&self, name: Symbol) -> bool { + self.meta_item().map_or(false, |meta_item| meta_item.has_name(name)) } /// For a single-segment meta item, returns its name; otherwise, returns `None`. @@ -173,8 +173,13 @@ impl Attribute { } } - /// Returns `true` if the attribute's path matches the argument. If it matches, then the - /// attribute is marked as used. + /// Returns `true` if the attribute's path matches the argument. + /// If it matches, then the attribute is marked as used. + /// Should only be used by rustc, other tools can use `has_name` instead, + /// because only rustc is supposed to report the `unused_attributes` lint. + /// `MetaItem` and `NestedMetaItem` are produced by "lowering" an `Attribute` + /// and don't have identity, so they only has the `has_name` method, + /// and you need to mark the original `Attribute` as used when necessary. pub fn check_name(&self, name: Symbol) -> bool { let matches = self.has_name(name); if matches { @@ -278,7 +283,7 @@ impl MetaItem { } } - pub fn check_name(&self, name: Symbol) -> bool { + pub fn has_name(&self, name: Symbol) -> bool { self.path == name } @@ -405,7 +410,7 @@ pub fn mk_doc_comment(style: AttrStyle, comment: Symbol, span: Span) -> Attribut } pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { - items.iter().any(|item| item.check_name(name)) + items.iter().any(|item| item.has_name(name)) } pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs index 173ea5e48d6..e1c94ddf782 100644 --- a/src/librustc_ast/token.rs +++ b/src/librustc_ast/token.rs @@ -673,62 +673,6 @@ impl Token { Some(Token::new(kind, self.span.to(joint.span))) } - - // See comments in `Nonterminal::to_tokenstream` for why we care about - // *probably* equal here rather than actual equality - crate fn probably_equal_for_proc_macro(&self, other: &Token) -> bool { - if mem::discriminant(&self.kind) != mem::discriminant(&other.kind) { - return false; - } - match (&self.kind, &other.kind) { - (&Eq, &Eq) - | (&Lt, &Lt) - | (&Le, &Le) - | (&EqEq, &EqEq) - | (&Ne, &Ne) - | (&Ge, &Ge) - | (&Gt, &Gt) - | (&AndAnd, &AndAnd) - | (&OrOr, &OrOr) - | (&Not, &Not) - | (&Tilde, &Tilde) - | (&At, &At) - | (&Dot, &Dot) - | (&DotDot, &DotDot) - | (&DotDotDot, &DotDotDot) - | (&DotDotEq, &DotDotEq) - | (&Comma, &Comma) - | (&Semi, &Semi) - | (&Colon, &Colon) - | (&ModSep, &ModSep) - | (&RArrow, &RArrow) - | (&LArrow, &LArrow) - | (&FatArrow, &FatArrow) - | (&Pound, &Pound) - | (&Dollar, &Dollar) - | (&Question, &Question) - | (&Whitespace, &Whitespace) - | (&Comment, &Comment) - | (&Eof, &Eof) => true, - - (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, - - (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b, - - (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b, - - (&Literal(a), &Literal(b)) => a == b, - - (&Lifetime(a), &Lifetime(b)) => a == b, - (&Ident(a, b), &Ident(c, d)) => { - b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate) - } - - (&Interpolated(..), &Interpolated(..)) => false, - - _ => panic!("forgot to add a token?"), - } - } } impl PartialEq<TokenKind> for Token { @@ -760,6 +704,67 @@ pub enum Nonterminal { #[cfg(target_arch = "x86_64")] rustc_data_structures::static_assert_size!(Nonterminal, 40); +#[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] +pub enum NonterminalKind { + Item, + Block, + Stmt, + Pat, + Expr, + Ty, + Ident, + Lifetime, + Literal, + Meta, + Path, + Vis, + TT, +} + +impl NonterminalKind { + pub fn from_symbol(symbol: Symbol) -> Option<NonterminalKind> { + Some(match symbol { + sym::item => NonterminalKind::Item, + sym::block => NonterminalKind::Block, + sym::stmt => NonterminalKind::Stmt, + sym::pat => NonterminalKind::Pat, + sym::expr => NonterminalKind::Expr, + sym::ty => NonterminalKind::Ty, + sym::ident => NonterminalKind::Ident, + sym::lifetime => NonterminalKind::Lifetime, + sym::literal => NonterminalKind::Literal, + sym::meta => NonterminalKind::Meta, + sym::path => NonterminalKind::Path, + sym::vis => NonterminalKind::Vis, + sym::tt => NonterminalKind::TT, + _ => return None, + }) + } + fn symbol(self) -> Symbol { + match self { + NonterminalKind::Item => sym::item, + NonterminalKind::Block => sym::block, + NonterminalKind::Stmt => sym::stmt, + NonterminalKind::Pat => sym::pat, + NonterminalKind::Expr => sym::expr, + NonterminalKind::Ty => sym::ty, + NonterminalKind::Ident => sym::ident, + NonterminalKind::Lifetime => sym::lifetime, + NonterminalKind::Literal => sym::literal, + NonterminalKind::Meta => sym::meta, + NonterminalKind::Path => sym::path, + NonterminalKind::Vis => sym::vis, + NonterminalKind::TT => sym::tt, + } + } +} + +impl fmt::Display for NonterminalKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.symbol()) + } +} + impl Nonterminal { fn span(&self) -> Span { match self { diff --git a/src/librustc_ast/tokenstream.rs b/src/librustc_ast/tokenstream.rs index 15ae12ebf10..9d0199078fa 100644 --- a/src/librustc_ast/tokenstream.rs +++ b/src/librustc_ast/tokenstream.rs @@ -21,8 +21,6 @@ use rustc_macros::HashStable_Generic; use rustc_span::{Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; -use log::debug; - use std::{iter, mem}; /// When the main rust parser encounters a syntax-extension invocation, it @@ -68,23 +66,6 @@ impl TokenTree { } } - // See comments in `Nonterminal::to_tokenstream` for why we care about - // *probably* equal here rather than actual equality - // - // This is otherwise the same as `eq_unspanned`, only recursing with a - // different method. - pub fn probably_equal_for_proc_macro(&self, other: &TokenTree) -> bool { - match (self, other) { - (TokenTree::Token(token), TokenTree::Token(token2)) => { - token.probably_equal_for_proc_macro(token2) - } - (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => { - delim == delim2 && tts.probably_equal_for_proc_macro(&tts2) - } - _ => false, - } - } - /// Retrieves the TokenTree's span. pub fn span(&self) -> Span { match self { @@ -307,112 +288,6 @@ impl TokenStream { t1.next().is_none() && t2.next().is_none() } - // See comments in `Nonterminal::to_tokenstream` for why we care about - // *probably* equal here rather than actual equality - // - // This is otherwise the same as `eq_unspanned`, only recursing with a - // different method. - pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool { - // When checking for `probably_eq`, we ignore certain tokens that aren't - // preserved in the AST. Because they are not preserved, the pretty - // printer arbitrarily adds or removes them when printing as token - // streams, making a comparison between a token stream generated from an - // AST and a token stream which was parsed into an AST more reliable. - fn semantic_tree(tree: &TokenTree) -> bool { - if let TokenTree::Token(token) = tree { - if let - // The pretty printer tends to add trailing commas to - // everything, and in particular, after struct fields. - | token::Comma - // The pretty printer emits `NoDelim` as whitespace. - | token::OpenDelim(DelimToken::NoDelim) - | token::CloseDelim(DelimToken::NoDelim) - // The pretty printer collapses many semicolons into one. - | token::Semi - // The pretty printer collapses whitespace arbitrarily and can - // introduce whitespace from `NoDelim`. - | token::Whitespace - // The pretty printer can turn `$crate` into `::crate_name` - | token::ModSep = token.kind { - return false; - } - } - true - } - - // When comparing two `TokenStream`s, we ignore the `IsJoint` information. - // - // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will - // use `Token.glue` on adjacent tokens with the proper `IsJoint`. - // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`) - // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent - // when determining if two `TokenStream`s are 'probably equal'. - // - // Therefore, we use `break_two_token_op` to convert all tokens - // to the 'unglued' form (if it exists). This ensures that two - // `TokenStream`s which differ only in how their tokens are glued - // will be considered 'probably equal', which allows us to keep spans. - // - // This is important when the original `TokenStream` contained - // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces - // will be omitted when we pretty-print, which can cause the original - // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`, - // leading to some tokens being 'glued' together in one stream but not - // the other. See #68489 for more details. - fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> { - // In almost all cases, we should have either zero or one levels - // of 'unglueing'. However, in some unusual cases, we may need - // to iterate breaking tokens mutliple times. For example: - // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]' - let mut token_trees: SmallVec<[_; 2]>; - if let TokenTree::Token(token) = &tree { - let mut out = SmallVec::<[_; 2]>::new(); - out.push(token.clone()); - // Iterate to fixpoint: - // * We start off with 'out' containing our initial token, and `temp` empty - // * If we are able to break any tokens in `out`, then `out` will have - // at least one more element than 'temp', so we will try to break tokens - // again. - // * If we cannot break any tokens in 'out', we are done - loop { - let mut temp = SmallVec::<[_; 2]>::new(); - let mut changed = false; - - for token in out.into_iter() { - if let Some((first, second)) = token.kind.break_two_token_op() { - temp.push(Token::new(first, DUMMY_SP)); - temp.push(Token::new(second, DUMMY_SP)); - changed = true; - } else { - temp.push(token); - } - } - out = temp; - if !changed { - break; - } - } - token_trees = out.into_iter().map(TokenTree::Token).collect(); - if token_trees.len() != 1 { - debug!("break_tokens: broke {:?} to {:?}", tree, token_trees); - } - } else { - token_trees = SmallVec::new(); - token_trees.push(tree); - } - token_trees.into_iter() - } - - let mut t1 = self.trees().filter(semantic_tree).flat_map(break_tokens); - let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens); - for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { - if !t1.probably_equal_for_proc_macro(&t2) { - return false; - } - } - t1.next().is_none() && t2.next().is_none() - } - pub fn map_enumerated<F: FnMut(usize, TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream { TokenStream(Lrc::new( self.0 diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml index 51f34a1b78e..bf7e69a31ab 100644 --- a/src/librustc_ast_lowering/Cargo.toml +++ b/src/librustc_ast_lowering/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_arena = { path = "../librustc_arena" } -log = { package = "tracing", version = "0.1" } +tracing = "0.1" rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index dd5e658102f..5414e584290 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -17,9 +17,9 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; -use log::debug; use smallvec::{smallvec, SmallVec}; use std::collections::BTreeSet; +use tracing::debug; pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 1c70eef3bf5..9df7ad2a9ac 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -64,10 +64,10 @@ use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use log::{debug, trace}; use smallvec::{smallvec, SmallVec}; use std::collections::BTreeMap; use std::mem; +use tracing::{debug, trace}; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ({ diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs index 55c1f802663..171856e7e63 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/src/librustc_ast_lowering/pat.rs @@ -112,7 +112,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Found a sub-tuple pattern `$binding_mode $ident @ ..`. // This is not allowed as a sub-tuple pattern PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => { - rest = Some((idx, pat.span)); let sp = pat.span; self.diagnostic() .struct_span_err( @@ -128,7 +127,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Applicability::MaybeIncorrect, ) .emit(); - break; } _ => {} } diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index e5ce51f8d2d..2541d6824fe 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -12,8 +12,8 @@ use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::symbol::Ident; use rustc_span::Span; -use log::debug; use smallvec::smallvec; +use tracing::debug; impl<'a, 'hir> LoweringContext<'a, 'hir> { crate fn lower_qpath( diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index c53089a4afc..6db9bce3164 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" [dependencies] itertools = "0.8" -log = { package = "tracing", version = "0.1" } +tracing = "0.1" rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index b424c8afb34..22eaca4f071 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -10,7 +10,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; -use log::debug; +use tracing::debug; macro_rules! gate_feature_fn { ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{ @@ -243,7 +243,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if attr.check_name(sym::doc) { for nested_meta in attr.meta_item_list().unwrap_or_default() { macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => { - $(if nested_meta.check_name(sym::$name) { + $(if nested_meta.has_name(sym::$name) { let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental"); gate_feature_post!(self, $feature, attr.span, msg); })* @@ -314,7 +314,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::Struct(..) => { for attr in attr::filter_by_name(&i.attrs[..], sym::repr) { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(sym::simd) { + if item.has_name(sym::simd) { gate_feature_post!( &self, repr_simd, diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml index 4035346d354..d26205c791d 100644 --- a/src/librustc_ast_pretty/Cargo.toml +++ b/src/librustc_ast_pretty/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" doctest = false [dependencies] -log = { package = "tracing", version = "0.1" } +tracing = "0.1" rustc_span = { path = "../librustc_span" } rustc_ast = { path = "../librustc_ast" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_ast_pretty/pp.rs b/src/librustc_ast_pretty/pp.rs index 4bb806a923e..ca7f127ced6 100644 --- a/src/librustc_ast_pretty/pp.rs +++ b/src/librustc_ast_pretty/pp.rs @@ -132,10 +132,10 @@ //! methods called `Printer::scan_*`, and the 'PRINT' process is the //! method called `Printer::print`. -use log::debug; use std::borrow::Cow; use std::collections::VecDeque; use std::fmt; +use tracing::debug; /// How to break. Described in more detail in the module docs. #[derive(Clone, Copy, PartialEq)] diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index b0edb1ca41d..4b228629ad7 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -450,7 +450,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_comment(&mut self, cmnt: &comments::Comment) { match cmnt.style { comments::Mixed => { - self.zerobreak(); + if !self.is_beginning_of_line() { + self.zerobreak(); + } if let Some((last, lines)) = cmnt.lines.split_last() { self.ibox(0); diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs index 1e088b52dcc..983202aafab 100644 --- a/src/librustc_attr/builtin.rs +++ b/src/librustc_attr/builtin.rs @@ -92,9 +92,9 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op if let Some(meta) = attr.meta() { if let MetaItemKind::List(items) = meta.kind { if items.len() == 1 { - if items[0].check_name(sym::allowed) { + if items[0].has_name(sym::allowed) { return Some(UnwindAttr::Allowed); - } else if items[0].check_name(sym::aborts) { + } else if items[0].has_name(sym::aborts) { return Some(UnwindAttr::Aborts); } } @@ -168,7 +168,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool item.check_name(sym::feature) && item .meta_item_list() - .map(|list| list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name))) + .map(|list| list.iter().any(|mi| mi.is_word() && mi.has_name(feature_name))) .unwrap_or(false) }) } @@ -505,7 +505,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat } fn try_gate_cfg(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) { - let gate = find_gated_cfg(|sym| cfg.check_name(sym)); + let gate = find_gated_cfg(|sym| cfg.has_name(sym)); if let (Some(feats), Some(gated_cfg)) = (features, gate) { gate_cfg(&gated_cfg, cfg.span, sess, feats); } @@ -898,7 +898,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> { } } else { if let Some(meta_item) = item.meta_item() { - if meta_item.check_name(sym::align) { + if meta_item.has_name(sym::align) { if let MetaItemKind::NameValue(ref value) = meta_item.kind { recognised = true; let mut err = struct_span_err!( diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs index 173a823dc7d..87be6d1743a 100644 --- a/src/librustc_builtin_macros/lib.rs +++ b/src/librustc_builtin_macros/lib.rs @@ -5,7 +5,6 @@ #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] #![feature(decl_macro)] -#![feature(inner_deref)] #![feature(nll)] #![feature(or_patterns)] #![feature(proc_macro_internals)] diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index f044ce41e87..763bdca35eb 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -143,7 +143,7 @@ impl<'a> CollectProcMacros<'a> { let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { - if !attr.check_name(sym::attributes) { + if !attr.has_name(sym::attributes) { self.handler.span_err(attr.span(), "second argument must be `attributes`") } attr.meta_item_list() diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 26d627e6b30..de8f81bdadf 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -336,7 +336,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { Some(list) => { let msg = list .iter() - .find(|mi| mi.check_name(sym::expected)) + .find(|mi| mi.has_name(sym::expected)) .and_then(|mi| mi.meta_item()) .and_then(|mi| mi.value_str()); if list.len() != 1 || msg.is_none() { diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index f1e06cd8ebf..1d0b810165a 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -703,11 +703,67 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { None } + fn fptosui_may_trap(&self, val: &'ll Value, dest_ty: &'ll Type) -> bool { + // Most of the time we'll be generating the `fptosi` or `fptoui` + // instruction for floating-point-to-integer conversions. These + // instructions by definition in LLVM do not trap. For the WebAssembly + // target, however, we'll lower in some cases to intrinsic calls instead + // which may trap. If we detect that this is a situation where we'll be + // using the intrinsics then we report that the call map trap, which + // callers might need to handle. + if !self.wasm_and_missing_nontrapping_fptoint() { + return false; + } + let src_ty = self.cx.val_ty(val); + let float_width = self.cx.float_width(src_ty); + let int_width = self.cx.int_width(dest_ty); + match (int_width, float_width) { + (32, 32) | (32, 64) | (64, 32) | (64, 64) => true, + _ => false, + } + } + fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + // When we can, use the native wasm intrinsics which have tighter + // codegen. Note that this has a semantic difference in that the + // intrinsic can trap whereas `fptoui` never traps. That difference, + // however, is handled by `fptosui_may_trap` above. + if self.wasm_and_missing_nontrapping_fptoint() { + let src_ty = self.cx.val_ty(val); + let float_width = self.cx.float_width(src_ty); + let int_width = self.cx.int_width(dest_ty); + let name = match (int_width, float_width) { + (32, 32) => Some("llvm.wasm.trunc.unsigned.i32.f32"), + (32, 64) => Some("llvm.wasm.trunc.unsigned.i32.f64"), + (64, 32) => Some("llvm.wasm.trunc.unsigned.i64.f32"), + (64, 64) => Some("llvm.wasm.trunc.unsigned.i64.f64"), + _ => None, + }; + if let Some(name) = name { + let intrinsic = self.get_intrinsic(name); + return self.call(intrinsic, &[val], None); + } + } unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) } } fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + if self.wasm_and_missing_nontrapping_fptoint() { + let src_ty = self.cx.val_ty(val); + let float_width = self.cx.float_width(src_ty); + let int_width = self.cx.int_width(dest_ty); + let name = match (int_width, float_width) { + (32, 32) => Some("llvm.wasm.trunc.signed.i32.f32"), + (32, 64) => Some("llvm.wasm.trunc.signed.i32.f64"), + (64, 32) => Some("llvm.wasm.trunc.signed.i64.f32"), + (64, 64) => Some("llvm.wasm.trunc.signed.i64.f64"), + _ => None, + }; + if let Some(name) = name { + let intrinsic = self.get_intrinsic(name); + return self.call(intrinsic, &[val], None); + } + } unsafe { llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty, UNNAMED) } } @@ -1349,4 +1405,9 @@ impl Builder<'a, 'll, 'tcx> { llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint); } } + + fn wasm_and_missing_nontrapping_fptoint(&self) -> bool { + self.sess().target.target.arch == "wasm32" + && !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint) + } } diff --git a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs index c2984607184..5d1bfd810b2 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs +++ b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs @@ -92,7 +92,7 @@ impl CoverageMapGenerator { fn write_coverage_mappings( &mut self, expressions: Vec<CounterExpression>, - counter_regions: impl Iterator<Item = (Counter, &'a Region)>, + counter_regions: impl Iterator<Item = (Counter, &'tcx Region<'tcx>)>, coverage_mappings_buffer: &RustString, ) { let mut counter_regions = counter_regions.collect::<Vec<_>>(); @@ -102,7 +102,7 @@ impl CoverageMapGenerator { let mut virtual_file_mapping = Vec::new(); let mut mapping_regions = Vec::new(); - let mut current_file_path = None; + let mut current_file_name = None; let mut current_file_id = 0; // Convert the list of (Counter, Region) pairs to an array of `CounterMappingRegion`, sorted @@ -112,22 +112,22 @@ impl CoverageMapGenerator { // `filenames` array. counter_regions.sort_unstable_by_key(|(_counter, region)| *region); for (counter, region) in counter_regions { - let (file_path, start_line, start_col, end_line, end_col) = region.file_start_and_end(); - let same_file = current_file_path.as_ref().map_or(false, |p| p == file_path); + let Region { file_name, start_line, start_col, end_line, end_col } = *region; + let same_file = current_file_name.as_ref().map_or(false, |p| p == file_name); if !same_file { - if current_file_path.is_some() { + if current_file_name.is_some() { current_file_id += 1; } - current_file_path = Some(file_path.clone()); - let filename = CString::new(file_path.to_string_lossy().to_string()) - .expect("null error converting filename to C string"); - debug!(" file_id: {} = '{:?}'", current_file_id, filename); - let filenames_index = match self.filename_to_index.get(&filename) { + current_file_name = Some(file_name.to_string()); + let c_filename = + CString::new(file_name).expect("null error converting filename to C string"); + debug!(" file_id: {} = '{:?}'", current_file_id, c_filename); + let filenames_index = match self.filename_to_index.get(&c_filename) { Some(index) => *index, None => { let index = self.filenames.len() as u32; - self.filenames.push(filename.clone()); - self.filename_to_index.insert(filename.clone(), index); + self.filenames.push(c_filename.clone()); + self.filename_to_index.insert(c_filename.clone(), index); index } }; diff --git a/src/librustc_codegen_llvm/coverageinfo/mod.rs b/src/librustc_codegen_llvm/coverageinfo/mod.rs index 0073e83dedb..4d51f8b0591 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mod.rs +++ b/src/librustc_codegen_llvm/coverageinfo/mod.rs @@ -5,7 +5,7 @@ use crate::common::CodegenCx; use libc::c_uint; use llvm::coverageinfo::CounterMappingRegion; -use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage}; +use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage, Region}; use rustc_codegen_ssa::traits::{ BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, StaticMethods, }; @@ -49,19 +49,18 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { instance: Instance<'tcx>, function_source_hash: u64, id: u32, - start_byte_pos: u32, - end_byte_pos: u32, + region: Region<'tcx>, ) { debug!( "adding counter to coverage_regions: instance={:?}, function_source_hash={}, id={}, \ - byte range {}..{}", - instance, function_source_hash, id, start_byte_pos, end_byte_pos, + at {:?}", + instance, function_source_hash, id, region, ); let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut(); coverage_regions .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) - .add_counter(function_source_hash, id, start_byte_pos, end_byte_pos); + .add_counter(function_source_hash, id, region); } fn add_counter_expression_region( @@ -71,43 +70,30 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { lhs: u32, op: ExprKind, rhs: u32, - start_byte_pos: u32, - end_byte_pos: u32, + region: Region<'tcx>, ) { debug!( "adding counter expression to coverage_regions: instance={:?}, id={}, {} {:?} {}, \ - byte range {}..{}", - instance, id_descending_from_max, lhs, op, rhs, start_byte_pos, end_byte_pos, + at {:?}", + instance, id_descending_from_max, lhs, op, rhs, region, ); let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut(); coverage_regions .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) - .add_counter_expression( - id_descending_from_max, - lhs, - op, - rhs, - start_byte_pos, - end_byte_pos, - ); + .add_counter_expression(id_descending_from_max, lhs, op, rhs, region); } - fn add_unreachable_region( - &mut self, - instance: Instance<'tcx>, - start_byte_pos: u32, - end_byte_pos: u32, - ) { + fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: Region<'tcx>) { debug!( - "adding unreachable code to coverage_regions: instance={:?}, byte range {}..{}", - instance, start_byte_pos, end_byte_pos, + "adding unreachable code to coverage_regions: instance={:?}, at {:?}", + instance, region, ); let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut(); coverage_regions .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) - .add_unreachable_region(start_byte_pos, end_byte_pos); + .add_unreachable_region(region); } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 0b54284f594..8d6b3f9ccb6 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -13,7 +13,7 @@ use rustc_ast::ast; use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; -use rustc_codegen_ssa::coverageinfo::ExprKind; +use rustc_codegen_ssa::coverageinfo; use rustc_codegen_ssa::glue; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -93,64 +93,64 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let mut is_codegen_intrinsic = true; // Set `is_codegen_intrinsic` to `false` to bypass `codegen_intrinsic_call()`. - if self.tcx.sess.opts.debugging_opts.instrument_coverage { - // If the intrinsic is from the local MIR, add the coverage information to the Codegen - // context, to be encoded into the local crate's coverage map. - if caller_instance.def_id().is_local() { - // FIXME(richkadel): Make sure to add coverage analysis tests on a crate with - // external crate dependencies, where: - // 1. Both binary and dependent crates are compiled with `-Zinstrument-coverage` - // 2. Only binary is compiled with `-Zinstrument-coverage` - // 3. Only dependent crates are compiled with `-Zinstrument-coverage` - match intrinsic { - sym::count_code_region => { - use coverage::count_code_region_args::*; - self.add_counter_region( - caller_instance, - op_to_u64(&args[FUNCTION_SOURCE_HASH]), - op_to_u32(&args[COUNTER_ID]), - op_to_u32(&args[START_BYTE_POS]), - op_to_u32(&args[END_BYTE_POS]), - ); - } - sym::coverage_counter_add | sym::coverage_counter_subtract => { - use coverage::coverage_counter_expression_args::*; - self.add_counter_expression_region( - caller_instance, - op_to_u32(&args[EXPRESSION_ID]), - op_to_u32(&args[LEFT_ID]), - if intrinsic == sym::coverage_counter_add { - ExprKind::Add - } else { - ExprKind::Subtract - }, - op_to_u32(&args[RIGHT_ID]), - op_to_u32(&args[START_BYTE_POS]), - op_to_u32(&args[END_BYTE_POS]), - ); - } - sym::coverage_unreachable => { - use coverage::coverage_unreachable_args::*; - self.add_unreachable_region( - caller_instance, - op_to_u32(&args[START_BYTE_POS]), - op_to_u32(&args[END_BYTE_POS]), - ); - } - _ => {} - } + // FIXME(richkadel): Make sure to add coverage analysis tests on a crate with + // external crate dependencies, where: + // 1. Both binary and dependent crates are compiled with `-Zinstrument-coverage` + // 2. Only binary is compiled with `-Zinstrument-coverage` + // 3. Only dependent crates are compiled with `-Zinstrument-coverage` + match intrinsic { + sym::count_code_region => { + use coverage::count_code_region_args::*; + self.add_counter_region( + caller_instance, + op_to_u64(&args[FUNCTION_SOURCE_HASH]), + op_to_u32(&args[COUNTER_ID]), + coverageinfo::Region::new( + op_to_str_slice(&args[FILE_NAME]), + op_to_u32(&args[START_LINE]), + op_to_u32(&args[START_COL]), + op_to_u32(&args[END_LINE]), + op_to_u32(&args[END_COL]), + ), + ); } - - // Only the `count_code_region` coverage intrinsic is translated into an actual LLVM - // intrinsic call (local or not); otherwise, set `is_codegen_intrinsic` to `false`. - match intrinsic { - sym::coverage_counter_add - | sym::coverage_counter_subtract - | sym::coverage_unreachable => { - is_codegen_intrinsic = false; - } - _ => {} + sym::coverage_counter_add | sym::coverage_counter_subtract => { + is_codegen_intrinsic = false; + use coverage::coverage_counter_expression_args::*; + self.add_counter_expression_region( + caller_instance, + op_to_u32(&args[EXPRESSION_ID]), + op_to_u32(&args[LEFT_ID]), + if intrinsic == sym::coverage_counter_add { + coverageinfo::ExprKind::Add + } else { + coverageinfo::ExprKind::Subtract + }, + op_to_u32(&args[RIGHT_ID]), + coverageinfo::Region::new( + op_to_str_slice(&args[FILE_NAME]), + op_to_u32(&args[START_LINE]), + op_to_u32(&args[START_COL]), + op_to_u32(&args[END_LINE]), + op_to_u32(&args[END_COL]), + ), + ); } + sym::coverage_unreachable => { + is_codegen_intrinsic = false; + use coverage::coverage_unreachable_args::*; + self.add_unreachable_region( + caller_instance, + coverageinfo::Region::new( + op_to_str_slice(&args[FILE_NAME]), + op_to_u32(&args[START_LINE]), + op_to_u32(&args[START_COL]), + op_to_u32(&args[END_LINE]), + op_to_u32(&args[END_COL]), + ), + ); + } + _ => {} } is_codegen_intrinsic } @@ -215,9 +215,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.call(llfn, &[], None) } sym::count_code_region => { - // FIXME(richkadel): The current implementation assumes the MIR for the given - // caller_instance represents a single function. Validate and/or correct if inlining - // and/or monomorphization invalidates these assumptions. let coverageinfo = tcx.coverageinfo(caller_instance.def_id()); let mangled_fn = tcx.symbol_name(caller_instance); let (mangled_fn_name, _len_val) = self.const_str(Symbol::intern(mangled_fn.name)); @@ -634,22 +631,19 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } sym::float_to_int_unchecked => { - let float_width = match float_type_width(arg_tys[0]) { - Some(width) => width, - None => { - span_invalid_monomorphization_error( - tcx.sess, - span, - &format!( - "invalid monomorphization of `float_to_int_unchecked` \ + if float_type_width(arg_tys[0]).is_none() { + span_invalid_monomorphization_error( + tcx.sess, + span, + &format!( + "invalid monomorphization of `float_to_int_unchecked` \ intrinsic: expected basic float type, \ found `{}`", - arg_tys[0] - ), - ); - return; - } - }; + arg_tys[0] + ), + ); + return; + } let (width, signed) = match int_type_width_signed(ret_ty, self.cx) { Some(pair) => pair, None => { @@ -666,48 +660,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { return; } }; - - // The LLVM backend can reorder and speculate `fptosi` and - // `fptoui`, so on WebAssembly the codegen for this instruction - // is quite heavyweight. To avoid this heavyweight codegen we - // instead use the raw wasm intrinsics which will lower to one - // instruction in WebAssembly (`iNN.trunc_fMM_{s,u}`). This one - // instruction will trap if the operand is out of bounds, but - // that's ok since this intrinsic is UB if the operands are out - // of bounds, so the behavior can be different on WebAssembly - // than other targets. - // - // Note, however, that when the `nontrapping-fptoint` feature is - // enabled in LLVM then LLVM will lower `fptosi` to - // `iNN.trunc_sat_fMM_{s,u}`, so if that's the case we don't - // bother with intrinsics. - let mut result = None; - if self.sess().target.target.arch == "wasm32" - && !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint) - { - let name = match (width, float_width, signed) { - (32, 32, true) => Some("llvm.wasm.trunc.signed.i32.f32"), - (32, 64, true) => Some("llvm.wasm.trunc.signed.i32.f64"), - (64, 32, true) => Some("llvm.wasm.trunc.signed.i64.f32"), - (64, 64, true) => Some("llvm.wasm.trunc.signed.i64.f64"), - (32, 32, false) => Some("llvm.wasm.trunc.unsigned.i32.f32"), - (32, 64, false) => Some("llvm.wasm.trunc.unsigned.i32.f64"), - (64, 32, false) => Some("llvm.wasm.trunc.unsigned.i64.f32"), - (64, 64, false) => Some("llvm.wasm.trunc.unsigned.i64.f64"), - _ => None, - }; - if let Some(name) = name { - let intrinsic = self.get_intrinsic(name); - result = Some(self.call(intrinsic, &[args[0].immediate()], None)); - } + if signed { + self.fptosi(args[0].immediate(), self.cx.type_ix(width)) + } else { + self.fptoui(args[0].immediate(), self.cx.type_ix(width)) } - result.unwrap_or_else(|| { - if signed { - self.fptosi(args[0].immediate(), self.cx.type_ix(width)) - } else { - self.fptoui(args[0].immediate(), self.cx.type_ix(width)) - } - }) } sym::discriminant_value => { @@ -2283,6 +2240,10 @@ fn float_type_width(ty: Ty<'_>) -> Option<u64> { } } +fn op_to_str_slice<'tcx>(op: &Operand<'tcx>) -> &'tcx str { + Operand::value_from_const(op).try_to_str_slice().expect("Value is &str") +} + fn op_to_u32<'tcx>(op: &Operand<'tcx>) -> u32 { Operand::scalar_from_const(op).to_u32().expect("Scalar is u32") } diff --git a/src/librustc_codegen_ssa/coverageinfo/map.rs b/src/librustc_codegen_ssa/coverageinfo/map.rs index 72138065a90..7f6841f9daa 100644 --- a/src/librustc_codegen_ssa/coverageinfo/map.rs +++ b/src/librustc_codegen_ssa/coverageinfo/map.rs @@ -3,12 +3,8 @@ pub use super::ffi::*; use rustc_index::vec::IndexVec; use rustc_middle::ty::Instance; use rustc_middle::ty::TyCtxt; -use rustc_span::source_map::{Pos, SourceMap}; -use rustc_span::{BytePos, FileName, Loc, RealFileName}; -use std::cmp::{Ord, Ordering}; -use std::fmt; -use std::path::PathBuf; +use std::cmp::Ord; rustc_index::newtype_index! { pub struct ExpressionOperandId { @@ -38,127 +34,35 @@ rustc_index::newtype_index! { } } -#[derive(Clone, Debug)] -pub struct Region { - start: Loc, - end: Loc, -} - -impl Ord for Region { - fn cmp(&self, other: &Self) -> Ordering { - (&self.start.file.name, &self.start.line, &self.start.col, &self.end.line, &self.end.col) - .cmp(&( - &other.start.file.name, - &other.start.line, - &other.start.col, - &other.end.line, - &other.end.col, - )) - } -} - -impl PartialOrd for Region { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl PartialEq for Region { - fn eq(&self, other: &Self) -> bool { - self.start.file.name == other.start.file.name - && self.start.line == other.start.line - && self.start.col == other.start.col - && self.end.line == other.end.line - && self.end.col == other.end.col - } -} - -impl Eq for Region {} - -impl fmt::Display for Region { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let (file_path, start_line, start_col, end_line, end_col) = self.file_start_and_end(); - write!(f, "{:?}:{}:{} - {}:{}", file_path, start_line, start_col, end_line, end_col) - } +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct Region<'tcx> { + pub file_name: &'tcx str, + pub start_line: u32, + pub start_col: u32, + pub end_line: u32, + pub end_col: u32, } -impl Region { - pub fn new(source_map: &SourceMap, start_byte_pos: u32, end_byte_pos: u32) -> Self { - let start = source_map.lookup_char_pos(BytePos::from_u32(start_byte_pos)); - let end = source_map.lookup_char_pos(BytePos::from_u32(end_byte_pos)); - assert_eq!( - start.file.name, end.file.name, - "Region start ({} -> {:?}) and end ({} -> {:?}) don't come from the same source file!", - start_byte_pos, start, end_byte_pos, end - ); - Self { start, end } - } - - pub fn file_start_and_end<'a>(&'a self) -> (&'a PathBuf, u32, u32, u32, u32) { - let start = &self.start; - let end = &self.end; - match &start.file.name { - FileName::Real(RealFileName::Named(path)) => ( - path, - start.line as u32, - start.col.to_u32() + 1, - end.line as u32, - end.col.to_u32() + 1, - ), - _ => { - bug!("start.file.name should be a RealFileName, but it was: {:?}", start.file.name) - } - } +impl<'tcx> Region<'tcx> { + pub fn new( + file_name: &'tcx str, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { file_name, start_line, start_col, end_line, end_col } } } #[derive(Clone, Debug)] -pub struct ExpressionRegion { +pub struct ExpressionRegion<'tcx> { lhs: ExpressionOperandId, op: ExprKind, rhs: ExpressionOperandId, - region: Region, + region: Region<'tcx>, } -// FIXME(richkadel): There seems to be a problem computing the file location in -// some cases. I need to investigate this more. When I generate and show coverage -// for the example binary in the crates.io crate `json5format`, I had a couple of -// notable problems: -// -// 1. I saw a lot of coverage spans in `llvm-cov show` highlighting regions in -// various comments (not corresponding to rustdoc code), indicating a possible -// problem with the byte_pos-to-source-map implementation. -// -// 2. And (perhaps not related) when I build the aforementioned example binary with: -// `RUST_FLAGS="-Zinstrument-coverage" cargo build --example formatjson5` -// and then run that binary with -// `LLVM_PROFILE_FILE="formatjson5.profraw" ./target/debug/examples/formatjson5 \ -// some.json5` for some reason the binary generates *TWO* `.profraw` files. One -// named `default.profraw` and the other named `formatjson5.profraw` (the expected -// name, in this case). -// -// 3. I think that if I eliminate regions within a function, their region_ids, -// referenced in expressions, will be wrong? I think the ids are implied by their -// array position in the final coverage map output (IIRC). -// -// 4. I suspect a problem (if not the only problem) is the SourceMap is wrong for some -// region start/end byte positions. Just like I couldn't get the function hash at -// intrinsic codegen time for external crate functions, I think the SourceMap I -// have here only applies to the local crate, and I know I have coverages that -// reference external crates. -// -// I still don't know if I fixed the hash problem correctly. If external crates -// implement the function, can't I use the coverage counters already compiled -// into those external crates? (Maybe not for generics and/or maybe not for -// macros... not sure. But I need to understand this better.) -// -// If the byte range conversion is wrong, fix it. But if it -// is right, then it is possible for the start and end to be in different files. -// Can I do something other than ignore coverages that span multiple files? -// -// If I can resolve this, remove the "Option<>" result type wrapper -// `regions_in_file_order()` accordingly. - /// Collects all of the coverage regions associated with (a) injected counters, (b) counter /// expressions (additions or subtraction), and (c) unreachable regions (always counted as zero), /// for a given Function. Counters and counter expressions have non-overlapping `id`s because they @@ -171,19 +75,17 @@ pub struct ExpressionRegion { /// only whitespace or comments). According to LLVM Code Coverage Mapping documentation, "A count /// for a gap area is only used as the line execution count if there are no other regions on a /// line." -pub struct FunctionCoverage<'a> { - source_map: &'a SourceMap, +pub struct FunctionCoverage<'tcx> { source_hash: u64, - counters: IndexVec<CounterValueReference, Option<Region>>, - expressions: IndexVec<InjectedExpressionIndex, Option<ExpressionRegion>>, - unreachable_regions: Vec<Region>, + counters: IndexVec<CounterValueReference, Option<Region<'tcx>>>, + expressions: IndexVec<InjectedExpressionIndex, Option<ExpressionRegion<'tcx>>>, + unreachable_regions: Vec<Region<'tcx>>, } -impl<'a> FunctionCoverage<'a> { - pub fn new<'tcx: 'a>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { +impl<'tcx> FunctionCoverage<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { let coverageinfo = tcx.coverageinfo(instance.def_id()); Self { - source_map: tcx.sess.source_map(), source_hash: 0, // will be set with the first `add_counter()` counters: IndexVec::from_elem_n(None, coverageinfo.num_counters as usize), expressions: IndexVec::from_elem_n(None, coverageinfo.num_expressions as usize), @@ -194,20 +96,14 @@ impl<'a> FunctionCoverage<'a> { /// Adds a code region to be counted by an injected counter intrinsic. /// The source_hash (computed during coverage instrumentation) should also be provided, and /// should be the same for all counters in a given function. - pub fn add_counter( - &mut self, - source_hash: u64, - id: u32, - start_byte_pos: u32, - end_byte_pos: u32, - ) { + pub fn add_counter(&mut self, source_hash: u64, id: u32, region: Region<'tcx>) { if self.source_hash == 0 { self.source_hash = source_hash; } else { debug_assert_eq!(source_hash, self.source_hash); } self.counters[CounterValueReference::from(id)] - .replace(Region::new(self.source_map, start_byte_pos, end_byte_pos)) + .replace(region) .expect_none("add_counter called with duplicate `id`"); } @@ -231,8 +127,7 @@ impl<'a> FunctionCoverage<'a> { lhs: u32, op: ExprKind, rhs: u32, - start_byte_pos: u32, - end_byte_pos: u32, + region: Region<'tcx>, ) { let expression_id = ExpressionOperandId::from(id_descending_from_max); let lhs = ExpressionOperandId::from(lhs); @@ -240,18 +135,13 @@ impl<'a> FunctionCoverage<'a> { let expression_index = self.expression_index(expression_id); self.expressions[expression_index] - .replace(ExpressionRegion { - lhs, - op, - rhs, - region: Region::new(self.source_map, start_byte_pos, end_byte_pos), - }) + .replace(ExpressionRegion { lhs, op, rhs, region }) .expect_none("add_counter_expression called with duplicate `id_descending_from_max`"); } /// Add a region that will be marked as "unreachable", with a constant "zero counter". - pub fn add_unreachable_region(&mut self, start_byte_pos: u32, end_byte_pos: u32) { - self.unreachable_regions.push(Region::new(self.source_map, start_byte_pos, end_byte_pos)); + pub fn add_unreachable_region(&mut self, region: Region<'tcx>) { + self.unreachable_regions.push(region) } /// Return the source hash, generated from the HIR node structure, and used to indicate whether @@ -264,8 +154,8 @@ impl<'a> FunctionCoverage<'a> { /// associated `Regions` (from which the LLVM-specific `CoverageMapGenerator` will create /// `CounterMappingRegion`s. pub fn get_expressions_and_counter_regions( - &'a self, - ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a Region)>) { + &'tcx self, + ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'tcx Region<'tcx>)>) { assert!(self.source_hash != 0); let counter_regions = self.counter_regions(); @@ -277,7 +167,7 @@ impl<'a> FunctionCoverage<'a> { (counter_expressions, counter_regions) } - fn counter_regions(&'a self) -> impl Iterator<Item = (Counter, &'a Region)> { + fn counter_regions(&'tcx self) -> impl Iterator<Item = (Counter, &'tcx Region<'tcx>)> { self.counters.iter_enumerated().filter_map(|(index, entry)| { // Option::map() will return None to filter out missing counters. This may happen // if, for example, a MIR-instrumented counter is removed during an optimization. @@ -288,8 +178,8 @@ impl<'a> FunctionCoverage<'a> { } fn expressions_with_regions( - &'a self, - ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a Region)>) { + &'tcx self, + ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'tcx Region<'tcx>)>) { let mut counter_expressions = Vec::with_capacity(self.expressions.len()); let mut expression_regions = Vec::with_capacity(self.expressions.len()); let mut new_indexes = @@ -350,7 +240,7 @@ impl<'a> FunctionCoverage<'a> { (counter_expressions, expression_regions.into_iter()) } - fn unreachable_regions(&'a self) -> impl Iterator<Item = (Counter, &'a Region)> { + fn unreachable_regions(&'tcx self) -> impl Iterator<Item = (Counter, &'tcx Region<'tcx>)> { self.unreachable_regions.iter().map(|region| (Counter::zero(), region)) } diff --git a/src/librustc_codegen_ssa/coverageinfo/mod.rs b/src/librustc_codegen_ssa/coverageinfo/mod.rs index 1f0ffd289b1..ff794a75c36 100644 --- a/src/librustc_codegen_ssa/coverageinfo/mod.rs +++ b/src/librustc_codegen_ssa/coverageinfo/mod.rs @@ -2,3 +2,4 @@ pub mod ffi; pub mod map; pub use map::ExprKind; +pub use map::Region; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 9c108998bc9..77e94fe3d0a 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -11,7 +11,7 @@ use rustc_apfloat::{ieee, Float, Round, Status}; use rustc_hir::lang_items::ExchangeMallocFnLangItem; use rustc_middle::mir; use rustc_middle::ty::cast::{CastTy, IntTy}; -use rustc_middle::ty::layout::HasTyCtxt; +use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::symbol::sym; @@ -369,10 +369,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.inttoptr(usize_llval, ll_t_out) } (CastTy::Float, CastTy::Int(IntTy::I)) => { - cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out) + cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out, cast) } (CastTy::Float, CastTy::Int(_)) => { - cast_float_to_int(&mut bx, false, llval, ll_t_in, ll_t_out) + cast_float_to_int(&mut bx, false, llval, ll_t_in, ll_t_out, cast) } _ => bug!("unsupported cast: {:?} to {:?}", operand.layout.ty, cast.ty), }; @@ -772,6 +772,7 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( x: Bx::Value, float_ty: Bx::Type, int_ty: Bx::Type, + int_layout: TyAndLayout<'tcx>, ) -> Bx::Value { if let Some(false) = bx.cx().sess().opts.debugging_opts.saturating_float_casts { return if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) }; @@ -782,8 +783,6 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( return try_sat_result; } - let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) }; - let int_width = bx.cx().int_width(int_ty); let float_width = bx.cx().float_width(float_ty); // LLVM's fpto[su]i returns undef when the input x is infinite, NaN, or does not fit into the @@ -870,36 +869,138 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // int_ty::MIN and therefore the return value of int_ty::MIN is correct. // QED. - // Step 1 was already performed above. - - // Step 2: We use two comparisons and two selects, with %s1 being the result: - // %less_or_nan = fcmp ult %x, %f_min - // %greater = fcmp olt %x, %f_max - // %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result - // %s1 = select %greater, int_ty::MAX, %s0 - // Note that %less_or_nan uses an *unordered* comparison. This comparison is true if the - // operands are not comparable (i.e., if x is NaN). The unordered comparison ensures that s1 - // becomes int_ty::MIN if x is NaN. - // Performance note: Unordered comparison can be lowered to a "flipped" comparison and a - // negation, and the negation can be merged into the select. Therefore, it not necessarily any - // more expensive than a ordered ("normal") comparison. Whether these optimizations will be - // performed is ultimately up to the backend, but at least x86 does perform them. - let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min); - let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max); let int_max = bx.cx().const_uint_big(int_ty, int_max(signed, int_width)); let int_min = bx.cx().const_uint_big(int_ty, int_min(signed, int_width) as u128); - let s0 = bx.select(less_or_nan, int_min, fptosui_result); - let s1 = bx.select(greater, int_max, s0); - - // Step 3: NaN replacement. - // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN. - // Therefore we only need to execute this step for signed integer types. - if signed { - // LLVM has no isNaN predicate, so we use (x == x) instead - let zero = bx.cx().const_uint(int_ty, 0); - let cmp = bx.fcmp(RealPredicate::RealOEQ, x, x); - bx.select(cmp, s1, zero) + let zero = bx.cx().const_uint(int_ty, 0); + + // The codegen here differs quite a bit depending on whether our builder's + // `fptosi` and `fptoui` instructions may trap for out-of-bounds values. If + // they don't trap then we can start doing everything inline with a + // `select` instruction because it's ok to execute `fptosi` and `fptoui` + // even if we don't use the results. + if !bx.fptosui_may_trap(x, int_ty) { + // Step 1 ... + let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) }; + let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min); + let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max); + + // Step 2: We use two comparisons and two selects, with %s1 being the + // result: + // %less_or_nan = fcmp ult %x, %f_min + // %greater = fcmp olt %x, %f_max + // %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result + // %s1 = select %greater, int_ty::MAX, %s0 + // Note that %less_or_nan uses an *unordered* comparison. This + // comparison is true if the operands are not comparable (i.e., if x is + // NaN). The unordered comparison ensures that s1 becomes int_ty::MIN if + // x is NaN. + // + // Performance note: Unordered comparison can be lowered to a "flipped" + // comparison and a negation, and the negation can be merged into the + // select. Therefore, it not necessarily any more expensive than a + // ordered ("normal") comparison. Whether these optimizations will be + // performed is ultimately up to the backend, but at least x86 does + // perform them. + let s0 = bx.select(less_or_nan, int_min, fptosui_result); + let s1 = bx.select(greater, int_max, s0); + + // Step 3: NaN replacement. + // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN. + // Therefore we only need to execute this step for signed integer types. + if signed { + // LLVM has no isNaN predicate, so we use (x == x) instead + let cmp = bx.fcmp(RealPredicate::RealOEQ, x, x); + bx.select(cmp, s1, zero) + } else { + s1 + } } else { - s1 + // In this case we cannot execute `fptosi` or `fptoui` and then later + // discard the result. The builder is telling us that these instructions + // will trap on out-of-bounds values, so we need to use basic blocks and + // control flow to avoid executing the `fptosi` and `fptoui` + // instructions. + // + // The general idea of what we're constructing here is, for f64 -> i32: + // + // ;; block so far... %0 is the argument + // %result = alloca i32, align 4 + // %inbound_lower = fcmp oge double %0, 0xC1E0000000000000 + // %inbound_upper = fcmp ole double %0, 0x41DFFFFFFFC00000 + // ;; match (inbound_lower, inbound_upper) { + // ;; (true, true) => %0 can be converted without trapping + // ;; (false, false) => %0 is a NaN + // ;; (true, false) => %0 is too large + // ;; (false, true) => %0 is too small + // ;; } + // ;; + // ;; The (true, true) check, go to %convert if so. + // %inbounds = and i1 %inbound_lower, %inbound_upper + // br i1 %inbounds, label %convert, label %specialcase + // + // convert: + // %cvt = call i32 @llvm.wasm.trunc.signed.i32.f64(double %0) + // store i32 %cvt, i32* %result, align 4 + // br label %done + // + // specialcase: + // ;; Handle the cases where the number is NaN, too large or too small + // + // ;; Either (true, false) or (false, true) + // %is_not_nan = or i1 %inbound_lower, %inbound_upper + // ;; Figure out which saturated value we are interested in if not `NaN` + // %saturated = select i1 %inbound_lower, i32 2147483647, i32 -2147483648 + // ;; Figure out between saturated and NaN representations + // %result_nan = select i1 %is_not_nan, i32 %saturated, i32 0 + // store i32 %result_nan, i32* %result, align 4 + // br label %done + // + // done: + // %r = load i32, i32* %result, align 4 + // ;; ... + let done = bx.build_sibling_block("float_cast_done"); + let mut convert = bx.build_sibling_block("float_cast_convert"); + let mut specialcase = bx.build_sibling_block("float_cast_specialcase"); + + let result = PlaceRef::alloca(bx, int_layout); + result.storage_live(bx); + + // Use control flow to figure out whether we can execute `fptosi` in a + // basic block, or whether we go to a different basic block to implement + // the saturating logic. + let inbound_lower = bx.fcmp(RealPredicate::RealOGE, x, f_min); + let inbound_upper = bx.fcmp(RealPredicate::RealOLE, x, f_max); + let inbounds = bx.and(inbound_lower, inbound_upper); + bx.cond_br(inbounds, convert.llbb(), specialcase.llbb()); + + // Translation of the `convert` basic block + let cvt = if signed { convert.fptosi(x, int_ty) } else { convert.fptoui(x, int_ty) }; + convert.store(cvt, result.llval, result.align); + convert.br(done.llbb()); + + // Translation of the `specialcase` basic block. Note that like above + // we try to be a bit clever here for unsigned conversions. In those + // cases the `int_min` is zero so we don't need two select instructions, + // just one to choose whether we need `int_max` or not. If + // `inbound_lower` is true then we're guaranteed to not be `NaN` and + // since we're greater than zero we must be saturating to `int_max`. If + // `inbound_lower` is false then we're either NaN or less than zero, so + // we saturate to zero. + let result_nan = if signed { + let is_not_nan = specialcase.or(inbound_lower, inbound_upper); + let saturated = specialcase.select(inbound_lower, int_max, int_min); + specialcase.select(is_not_nan, saturated, zero) + } else { + specialcase.select(inbound_lower, int_max, int_min) + }; + specialcase.store(result_nan, result.llval, result.align); + specialcase.br(done.llbb()); + + // Translation of the `done` basic block, positioning ourselves to + // continue from that point as well. + *bx = done; + let ret = bx.load(result.llval, result.align); + result.storage_dead(bx); + ret } } diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 65eb70e173e..4e11ef5fd6e 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -160,6 +160,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option<Self::Value>; fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option<Self::Value>; + fn fptosui_may_trap(&self, val: Self::Value, dest_ty: Self::Type) -> bool; fn fptoui(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptosi(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn uitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/src/librustc_codegen_ssa/traits/coverageinfo.rs b/src/librustc_codegen_ssa/traits/coverageinfo.rs index db1d86c974e..2b5878f46bc 100644 --- a/src/librustc_codegen_ssa/traits/coverageinfo.rs +++ b/src/librustc_codegen_ssa/traits/coverageinfo.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use crate::coverageinfo::ExprKind; +use crate::coverageinfo::{ExprKind, Region}; use rustc_middle::ty::Instance; pub trait CoverageInfoMethods: BackendTypes { @@ -12,8 +12,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { instance: Instance<'tcx>, function_source_hash: u64, index: u32, - start_byte_pos: u32, - end_byte_pos: u32, + region: Region<'tcx>, ); fn add_counter_expression_region( @@ -23,14 +22,8 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { lhs: u32, op: ExprKind, rhs: u32, - start_byte_pos: u32, - end_byte_pos: u32, + region: Region<'tcx>, ); - fn add_unreachable_region( - &mut self, - instance: Instance<'tcx>, - start_byte_pos: u32, - end_byte_pos: u32, - ); + fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: Region<'tcx>); } diff --git a/src/librustc_error_codes/error_codes/E0733.md b/src/librustc_error_codes/error_codes/E0733.md index 0bda7a7d682..051b75148e5 100644 --- a/src/librustc_error_codes/error_codes/E0733.md +++ b/src/librustc_error_codes/error_codes/E0733.md @@ -1,4 +1,6 @@ -Recursion in an `async fn` requires boxing. For example, this will not compile: +An [`async`] function used recursion without boxing. + +Erroneous code example: ```edition2018,compile_fail,E0733 async fn foo(n: usize) { @@ -8,8 +10,8 @@ async fn foo(n: usize) { } ``` -To achieve async recursion, the `async fn` needs to be desugared -such that the `Future` is explicit in the return type: +To perform async recursion, the `async fn` needs to be desugared such that the +`Future` is explicit in the return type: ```edition2018,compile_fail,E0720 use std::future::Future; @@ -36,5 +38,7 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> { } ``` -The `Box<...>` ensures that the result is of known size, -and the pin is required to keep it in the same place in memory. +The `Box<...>` ensures that the result is of known size, and the pin is +required to keep it in the same place in memory. + +[`async`]: https://doc.rust-lang.org/std/keyword.async.html diff --git a/src/librustc_error_codes/error_codes/E0744.md b/src/librustc_error_codes/error_codes/E0744.md index 56b947a8282..14cff3613e0 100644 --- a/src/librustc_error_codes/error_codes/E0744.md +++ b/src/librustc_error_codes/error_codes/E0744.md @@ -1,7 +1,6 @@ -Control-flow expressions are not allowed inside a const context. +A control-flow expression was used inside a const context. -At the moment, `if` and `match`, as well as the looping constructs `for`, -`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`. +Erroneous code example: ```compile_fail,E0744 const _: i32 = { @@ -13,6 +12,9 @@ const _: i32 = { }; ``` +At the moment, `if` and `match`, as well as the looping constructs `for`, +`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`. + This will be allowed at some point in the future, but the implementation is not yet complete. See the tracking issue for [conditionals] or [loops] in a const context for the current status. diff --git a/src/librustc_error_codes/error_codes/E0745.md b/src/librustc_error_codes/error_codes/E0745.md index 6595691ce78..23ee7af30f4 100644 --- a/src/librustc_error_codes/error_codes/E0745.md +++ b/src/librustc_error_codes/error_codes/E0745.md @@ -1,20 +1,23 @@ -Cannot take address of temporary value. +The address of temporary value was taken. Erroneous code example: ```compile_fail,E0745 # #![feature(raw_ref_op)] fn temp_address() { - let ptr = &raw const 2; // ERROR + let ptr = &raw const 2; // error! } ``` -To avoid the error, first bind the temporary to a named local variable. +In this example, `2` is destroyed right after the assignment, which means that +`ptr` now points to an unavailable location. + +To avoid this error, first bind the temporary to a named local variable: ``` # #![feature(raw_ref_op)] fn temp_address() { let val = 2; - let ptr = &raw const val; + let ptr = &raw const val; // ok! } ``` diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 1362a1155bc..cca8b47c781 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -362,7 +362,7 @@ pub trait Emitter { format!( "in this expansion of `{}`{}", trace.kind.descr(), - if macro_backtrace.len() > 2 { + if macro_backtrace.len() > 1 { // if macro_backtrace.len() == 1 it'll be // pointed at by "in this macro invocation" format!(" (#{})", i + 1) @@ -393,7 +393,7 @@ pub trait Emitter { trace.call_site, format!( "in this macro invocation{}", - if macro_backtrace.len() > 2 && always_backtrace { + if macro_backtrace.len() > 1 && always_backtrace { // only specify order when the macro // backtrace is multiple levels deep format!(" (#{})", i + 1) diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index e4c0fcaa298..0cc340c205a 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1644,14 +1644,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } if let Some(list) = at.meta_item_list() { - if !list.iter().any(|it| it.check_name(sym::include)) { + if !list.iter().any(|it| it.has_name(sym::include)) { return noop_visit_attribute(at, self); } let mut items = vec![]; for mut it in list { - if !it.check_name(sym::include) { + if !it.has_name(sym::include) { items.push({ noop_visit_meta_list_item(&mut it, self); it diff --git a/src/librustc_expand/mbe.rs b/src/librustc_expand/mbe.rs index a728261d711..6f2daaa81c0 100644 --- a/src/librustc_expand/mbe.rs +++ b/src/librustc_expand/mbe.rs @@ -9,7 +9,7 @@ crate mod macro_rules; crate mod quoted; crate mod transcribe; -use rustc_ast::token::{self, Token, TokenKind}; +use rustc_ast::token::{self, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::DelimSpan; use rustc_span::symbol::Ident; @@ -84,7 +84,7 @@ enum TokenTree { /// e.g., `$var` MetaVar(Span, Ident), /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros. - MetaVarDecl(Span, Ident /* name to bind */, Ident /* kind of nonterminal */), + MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>), } impl TokenTree { diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 3c15a81c67f..d2fe7fe10a8 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -76,15 +76,11 @@ use TokenTreeOrTokenTreeSlice::*; use crate::mbe::{self, TokenTree}; -use rustc_ast::ptr::P; use rustc_ast::token::{self, DocComment, Nonterminal, Token}; -use rustc_ast_pretty::pprust; -use rustc_parse::parser::{FollowedByType, Parser, PathStyle}; +use rustc_parse::parser::Parser; use rustc_session::parse::ParseSess; -use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol}; +use rustc_span::symbol::MacroRulesNormalizedIdent; -use rustc_errors::PResult; -use rustc_span::Span; use smallvec::{smallvec, SmallVec}; use rustc_data_structures::fx::FxHashMap; @@ -382,7 +378,7 @@ fn nameize<I: Iterator<Item = NamedMatch>>( n_rec(sess, next_m, res.by_ref(), ret_val)?; } } - TokenTree::MetaVarDecl(span, _, id) if id.name == kw::Invalid => { + TokenTree::MetaVarDecl(span, _, None) => { if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { return Err((span, "missing fragment specifier".to_string())); } @@ -565,7 +561,7 @@ fn inner_parse_loop<'root, 'tt>( } // We need to match a metavar (but the identifier is invalid)... this is an error - TokenTree::MetaVarDecl(span, _, id) if id.name == kw::Invalid => { + TokenTree::MetaVarDecl(span, _, None) => { if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { return Error(span, "missing fragment specifier".to_string()); } @@ -573,10 +569,10 @@ fn inner_parse_loop<'root, 'tt>( // We need to match a metavar with a valid ident... call out to the black-box // parser by adding an item to `bb_items`. - TokenTree::MetaVarDecl(_, _, id) => { + TokenTree::MetaVarDecl(_, _, Some(kind)) => { // Built-in nonterminals never start with these tokens, // so we can eliminate them from consideration. - if may_begin_with(token, id.name) { + if Parser::nonterminal_may_begin_with(kind, token) { bb_items.push(item); } } @@ -706,7 +702,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na let nts = bb_items .iter() .map(|item| match item.top_elts.get_tt(item.idx) { - TokenTree::MetaVarDecl(_, bind, name) => format!("{} ('{}')", name, bind), + TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind), _ => panic!(), }) .collect::<Vec<String>>() @@ -736,10 +732,17 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na assert_eq!(bb_items.len(), 1); let mut item = bb_items.pop().unwrap(); - if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) { + if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) { let match_cur = item.match_cur; - let nt = match parse_nt(parser.to_mut(), span, ident.name) { - Err(()) => return ErrorReported, + let nt = match parser.to_mut().parse_nonterminal(kind) { + Err(mut err) => { + err.span_label( + span, + format!("while parsing argument for this `{}` macro fragment", kind), + ) + .emit(); + return ErrorReported; + } Ok(nt) => nt, }; item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt))); @@ -754,178 +757,3 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na assert!(!cur_items.is_empty()); } } - -/// The token is an identifier, but not `_`. -/// We prohibit passing `_` to macros expecting `ident` for now. -fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> { - token.ident().filter(|(ident, _)| ident.name != kw::Underscore) -} - -/// Checks whether a non-terminal may begin with a particular token. -/// -/// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that -/// token. Be conservative (return true) if not sure. -fn may_begin_with(token: &Token, name: Symbol) -> bool { - /// Checks whether the non-terminal may contain a single (non-keyword) identifier. - fn may_be_ident(nt: &token::Nonterminal) -> bool { - match *nt { - token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => false, - _ => true, - } - } - - match name { - sym::expr => { - token.can_begin_expr() - // This exception is here for backwards compatibility. - && !token.is_keyword(kw::Let) - } - sym::ty => token.can_begin_type(), - sym::ident => get_macro_ident(token).is_some(), - sym::literal => token.can_begin_literal_maybe_minus(), - sym::vis => match token.kind { - // The follow-set of :vis + "priv" keyword + interpolated - token::Comma | token::Ident(..) | token::Interpolated(..) => true, - _ => token.can_begin_type(), - }, - sym::block => match token.kind { - token::OpenDelim(token::Brace) => true, - token::Interpolated(ref nt) => match **nt { - token::NtItem(_) - | token::NtPat(_) - | token::NtTy(_) - | token::NtIdent(..) - | token::NtMeta(_) - | token::NtPath(_) - | token::NtVis(_) => false, // none of these may start with '{'. - _ => true, - }, - _ => false, - }, - sym::path | sym::meta => match token.kind { - token::ModSep | token::Ident(..) => true, - token::Interpolated(ref nt) => match **nt { - token::NtPath(_) | token::NtMeta(_) => true, - _ => may_be_ident(&nt), - }, - _ => false, - }, - sym::pat => match token.kind { - token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) - token::OpenDelim(token::Paren) | // tuple pattern - token::OpenDelim(token::Bracket) | // slice pattern - token::BinOp(token::And) | // reference - token::BinOp(token::Minus) | // negative literal - token::AndAnd | // double reference - token::Literal(..) | // literal - token::DotDot | // range pattern (future compat) - token::DotDotDot | // range pattern (future compat) - token::ModSep | // path - token::Lt | // path (UFCS constant) - token::BinOp(token::Shl) => true, // path (double UFCS) - token::Interpolated(ref nt) => may_be_ident(nt), - _ => false, - }, - sym::lifetime => match token.kind { - token::Lifetime(_) => true, - token::Interpolated(ref nt) => match **nt { - token::NtLifetime(_) | token::NtTT(_) => true, - _ => false, - }, - _ => false, - }, - _ => match token.kind { - token::CloseDelim(_) => false, - _ => true, - }, - } -} - -/// A call to the "black-box" parser to parse some Rust non-terminal. -/// -/// # Parameters -/// -/// - `p`: the "black-box" parser to use -/// - `sp`: the `Span` we want to parse -/// - `name`: the name of the metavar _matcher_ we want to match (e.g., `tt`, `ident`, `block`, -/// etc...) -/// -/// # Returns -/// -/// The parsed non-terminal. -fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Result<Nonterminal, ()> { - // FIXME(Centril): Consider moving this to `parser.rs` to make - // the visibilities of the methods used below `pub(super)` at most. - if name == sym::tt { - return Ok(token::NtTT(p.parse_token_tree())); - } - parse_nt_inner(p, sp, name).map_err(|mut err| { - err.span_label(sp, format!("while parsing argument for this `{}` macro fragment", name)) - .emit() - }) -} - -fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> { - // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`) - // needs to have them force-captured here. - // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, - // which requires having captured tokens available. Since we cannot determine - // in advance whether or not a proc-macro will be (transitively) invoked, - // we always capture tokens for any `Nonterminal` which needs them. - Ok(match name { - sym::item => match p.collect_tokens(|this| this.parse_item())? { - (Some(mut item), tokens) => { - // If we captured tokens during parsing (due to outer attributes), - // use those. - if item.tokens.is_none() { - item.tokens = Some(tokens); - } - token::NtItem(item) - } - (None, _) => return Err(p.struct_span_err(p.token.span, "expected an item keyword")), - }, - sym::block => token::NtBlock(p.parse_block()?), - sym::stmt => match p.parse_stmt()? { - Some(s) => token::NtStmt(s), - None => return Err(p.struct_span_err(p.token.span, "expected a statement")), - }, - sym::pat => token::NtPat(p.parse_pat(None)?), - sym::expr => { - let (mut expr, tokens) = p.collect_tokens(|this| this.parse_expr())?; - // If we captured tokens during parsing (due to outer attributes), - // use those. - if expr.tokens.is_none() { - expr.tokens = Some(tokens); - } - token::NtExpr(expr) - } - sym::literal => token::NtLiteral(p.parse_literal_maybe_minus()?), - sym::ty => token::NtTy(p.parse_ty()?), - // this could be handled like a token, since it is one - sym::ident => { - if let Some((ident, is_raw)) = get_macro_ident(&p.token) { - p.bump(); - token::NtIdent(ident, is_raw) - } else { - let token_str = pprust::token_to_string(&p.token); - let msg = &format!("expected ident, found {}", &token_str); - return Err(p.struct_span_err(p.token.span, msg)); - } - } - sym::path => token::NtPath(p.parse_path(PathStyle::Type)?), - sym::meta => token::NtMeta(P(p.parse_attr_item()?)), - sym::vis => token::NtVis(p.parse_visibility(FollowedByType::Yes)?), - sym::lifetime => { - if p.check_lifetime() { - token::NtLifetime(p.expect_lifetime().ident) - } else { - let token_str = pprust::token_to_string(&p.token); - let msg = &format!("expected a lifetime, found `{}`", &token_str); - return Err(p.struct_span_err(p.token.span, msg)); - } - } - // this is not supposed to happen, since it has been checked - // when compiling the macro. - _ => p.span_bug(sp, "invalid fragment specifier"), - }) -} diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 36b323df697..74d4023b410 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -9,7 +9,7 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; use crate::mbe::transcribe::transcribe; use rustc_ast::ast; -use rustc_ast::token::{self, NtTT, Token, TokenKind::*}; +use rustc_ast::token::{self, NonterminalKind, NtTT, Token, TokenKind::*}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; @@ -21,7 +21,7 @@ use rustc_parse::parser::Parser; use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::Transparency; -use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol}; +use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent}; use rustc_span::Span; use log::debug; @@ -29,10 +29,6 @@ use std::borrow::Cow; use std::collections::hash_map::Entry; use std::{mem, slice}; -const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ - `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ - `literal`, `path`, `meta`, `tt`, `item` and `vis`"; - crate struct ParserAnyMacro<'a> { parser: Parser<'a>, @@ -403,7 +399,7 @@ pub fn compile_declarative_macro( let diag = &sess.span_diagnostic; let lhs_nm = Ident::new(sym::lhs, def.span); let rhs_nm = Ident::new(sym::rhs, def.span); - let tt_spec = Ident::new(sym::tt, def.span); + let tt_spec = Some(NonterminalKind::TT); // Parse the macro_rules! invocation let (macro_rules, body) = match &def.kind { @@ -571,7 +567,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { TokenTree::Sequence(span, ref seq) => { if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| match *seq_tt { - TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis, + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true, TokenTree::Sequence(_, ref sub_seq) => { sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne @@ -890,21 +886,7 @@ fn check_matcher_core( // of NT tokens that might end the sequence `... token`. match *token { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => { - let can_be_followed_by_any; - if let Err(bad_frag) = has_legal_fragment_specifier(sess, features, attrs, token) { - let msg = format!("invalid fragment specifier `{}`", bad_frag); - sess.span_diagnostic - .struct_span_err(token.span(), &msg) - .help(VALID_FRAGMENT_NAMES_MSG) - .emit(); - // (This eliminates false positives and duplicates - // from error messages.) - can_be_followed_by_any = true; - } else { - can_be_followed_by_any = token_can_be_followed_by_any(token); - } - - if can_be_followed_by_any { + if token_can_be_followed_by_any(token) { // don't need to track tokens that work with any, last.replace_with_irrelevant(); // ... and don't need to check tokens that can be @@ -967,19 +949,10 @@ fn check_matcher_core( // Now `last` holds the complete set of NT tokens that could // end the sequence before SUFFIX. Check that every one works with `suffix`. - 'each_last: for token in &last.tokens { - if let TokenTree::MetaVarDecl(_, name, frag_spec) = *token { + for token in &last.tokens { + if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token { for next_token in &suffix_first.tokens { - match is_in_follow(next_token, frag_spec.name) { - IsInFollow::Invalid(msg, help) => { - sess.span_diagnostic - .struct_span_err(next_token.span(), &msg) - .help(help) - .emit(); - // don't bother reporting every source of - // conflict for a particular element of `last`. - continue 'each_last; - } + match is_in_follow(next_token, kind) { IsInFollow::Yes => {} IsInFollow::No(possible) => { let may_be = if last.tokens.len() == 1 && suffix_first.tokens.len() == 1 @@ -996,22 +969,19 @@ fn check_matcher_core( "`${name}:{frag}` {may_be} followed by `{next}`, which \ is not allowed for `{frag}` fragments", name = name, - frag = frag_spec, + frag = kind, next = quoted_tt_to_string(next_token), may_be = may_be ), ); - err.span_label( - sp, - format!("not allowed after `{}` fragments", frag_spec), - ); + err.span_label(sp, format!("not allowed after `{}` fragments", kind)); let msg = "allowed there are: "; match possible { &[] => {} &[t] => { err.note(&format!( "only {} is allowed after `{}` fragments", - t, frag_spec, + t, kind, )); } ts => { @@ -1038,8 +1008,8 @@ fn check_matcher_core( } fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { - if let mbe::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok { - frag_can_be_followed_by_any(frag_spec.name) + if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok { + frag_can_be_followed_by_any(kind) } else { // (Non NT's can always be followed by anything in matchers.) true @@ -1054,26 +1024,23 @@ fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { /// specifier which consumes at most one token tree can be followed by /// a fragment specifier (indeed, these fragments can be followed by /// ANYTHING without fear of future compatibility hazards). -fn frag_can_be_followed_by_any(frag: Symbol) -> bool { - match frag { - sym::item | // always terminated by `}` or `;` - sym::block | // exactly one token tree - sym::ident | // exactly one token tree - sym::literal | // exactly one token tree - sym::meta | // exactly one token tree - sym::lifetime | // exactly one token tree - sym::tt => // exactly one token tree - true, - - _ => - false, +fn frag_can_be_followed_by_any(kind: NonterminalKind) -> bool { + match kind { + NonterminalKind::Item // always terminated by `}` or `;` + | NonterminalKind::Block // exactly one token tree + | NonterminalKind::Ident // exactly one token tree + | NonterminalKind::Literal // exactly one token tree + | NonterminalKind::Meta // exactly one token tree + | NonterminalKind::Lifetime // exactly one token tree + | NonterminalKind::TT => true, // exactly one token tree + + _ => false, } } enum IsInFollow { Yes, No(&'static [&'static str]), - Invalid(String, &'static str), } /// Returns `true` if `frag` can legally be followed by the token `tok`. For @@ -1084,7 +1051,7 @@ enum IsInFollow { /// break macros that were relying on that binary operator as a /// separator. // when changing this do not forget to update doc/book/macros.md! -fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { +fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { use mbe::TokenTree; if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok { @@ -1092,18 +1059,18 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { // iow, we always require that `(` and `)` match, etc. IsInFollow::Yes } else { - match frag { - sym::item => { + match kind { + NonterminalKind::Item => { // since items *must* be followed by either a `;` or a `}`, we can // accept anything after them IsInFollow::Yes } - sym::block => { + NonterminalKind::Block => { // anything can follow block, the braces provide an easy boundary to // maintain IsInFollow::Yes } - sym::stmt | sym::expr => { + NonterminalKind::Stmt | NonterminalKind::Expr => { const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"]; match tok { TokenTree::Token(token) => match token.kind { @@ -1113,7 +1080,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { _ => IsInFollow::No(TOKENS), } } - sym::pat => { + NonterminalKind::Pat => { const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"]; match tok { TokenTree::Token(token) => match token.kind { @@ -1124,7 +1091,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { _ => IsInFollow::No(TOKENS), } } - sym::path | sym::ty => { + NonterminalKind::Path | NonterminalKind::Ty => { const TOKENS: &[&str] = &[ "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`", "`where`", @@ -1146,26 +1113,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { } _ => IsInFollow::No(TOKENS), }, - TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block => { - IsInFollow::Yes - } + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } - sym::ident | sym::lifetime => { + NonterminalKind::Ident | NonterminalKind::Lifetime => { // being a single token, idents and lifetimes are harmless IsInFollow::Yes } - sym::literal => { + NonterminalKind::Literal => { // literals may be of a single token, or two tokens (negative numbers) IsInFollow::Yes } - sym::meta | sym::tt => { + NonterminalKind::Meta | NonterminalKind::TT => { // being either a single token or a delimited sequence, tt is // harmless IsInFollow::Yes } - sym::vis => { + NonterminalKind::Vis => { // Explicitly disallow `priv`, on the off chance it comes back. const TOKENS: &[&str] = &["`,`", "an ident", "a type"]; match tok { @@ -1180,78 +1145,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { } } }, - TokenTree::MetaVarDecl(_, _, frag) - if frag.name == sym::ident - || frag.name == sym::ty - || frag.name == sym::path => - { - IsInFollow::Yes - } + TokenTree::MetaVarDecl( + _, + _, + Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path), + ) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } - kw::Invalid => IsInFollow::Yes, - _ => IsInFollow::Invalid( - format!("invalid fragment specifier `{}`", frag), - VALID_FRAGMENT_NAMES_MSG, - ), } } } -fn has_legal_fragment_specifier( - sess: &ParseSess, - features: &Features, - attrs: &[ast::Attribute], - tok: &mbe::TokenTree, -) -> Result<(), String> { - debug!("has_legal_fragment_specifier({:?})", tok); - if let mbe::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok { - let frag_span = tok.span(); - if !is_legal_fragment_specifier(sess, features, attrs, frag_spec.name, frag_span) { - return Err(frag_spec.to_string()); - } - } - Ok(()) -} - -fn is_legal_fragment_specifier( - _sess: &ParseSess, - _features: &Features, - _attrs: &[ast::Attribute], - frag_name: Symbol, - _frag_span: Span, -) -> bool { - /* - * If new fragment specifiers are invented in nightly, `_sess`, - * `_features`, `_attrs`, and `_frag_span` will be useful here - * for checking against feature gates. See past versions of - * this function. - */ - match frag_name { - sym::item - | sym::block - | sym::stmt - | sym::expr - | sym::pat - | sym::lifetime - | sym::path - | sym::ty - | sym::ident - | sym::meta - | sym::tt - | sym::vis - | sym::literal - | kw::Invalid => true, - _ => false, - } -} - fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { match *tt { mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token), mbe::TokenTree::MetaVar(_, name) => format!("${}", name), - mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name), _ => panic!( "unexpected mbe::TokenTree::{{Sequence or Delimited}} \ in follow set checker" diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs index 09306f26ee0..774cc84afde 100644 --- a/src/librustc_expand/mbe/quoted.rs +++ b/src/librustc_expand/mbe/quoted.rs @@ -12,6 +12,10 @@ use rustc_span::Span; use rustc_data_structures::sync::Lrc; +const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ + `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ + `literal`, `path`, `meta`, `tt`, `item` and `vis`"; + /// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a /// collection of `TokenTree` for use in parsing a macro. @@ -55,9 +59,21 @@ pub(super) fn parse( Some(tokenstream::TokenTree::Token(Token { kind: token::Colon, span })) => { match trees.next() { Some(tokenstream::TokenTree::Token(token)) => match token.ident() { - Some((kind, _)) => { + Some((frag, _)) => { let span = token.span.with_lo(start_sp.lo()); - result.push(TokenTree::MetaVarDecl(span, ident, kind)); + let kind = token::NonterminalKind::from_symbol(frag.name) + .unwrap_or_else(|| { + let msg = format!( + "invalid fragment specifier `{}`", + frag.name + ); + sess.span_diagnostic + .struct_span_err(span, &msg) + .help(VALID_FRAGMENT_NAMES_MSG) + .emit(); + token::NonterminalKind::Ident + }); + result.push(TokenTree::MetaVarDecl(span, ident, Some(kind))); continue; } _ => token.span, @@ -71,7 +87,7 @@ pub(super) fn parse( // Macros loaded from other crates have dummy node ids. sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id); } - result.push(TokenTree::MetaVarDecl(span, ident, Ident::invalid())); + result.push(TokenTree::MetaVarDecl(span, ident, None)); } // Not a metavar or no matchers allowed, so just return the tree diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index cd5da7a6768..d451d9a22a4 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -149,7 +149,7 @@ impl AssertModuleSource<'tcx> { fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(name) { + if item.has_name(name) { if let Some(value) = item.value_str() { return value; } else { diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index d48810f1cf1..02f37f82352 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -231,7 +231,7 @@ impl DirtyCleanVisitor<'tcx> { fn labels(&self, attr: &Attribute) -> Option<Labels> { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(LABEL) { + if item.has_name(LABEL) { let value = expect_associated_value(self.tcx, &item); return Some(self.resolve_labels(&item, value)); } @@ -242,7 +242,7 @@ impl DirtyCleanVisitor<'tcx> { /// `except=` attribute value fn except(&self, attr: &Attribute) -> Labels { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(EXCEPT) { + if item.has_name(EXCEPT) { let value = expect_associated_value(self.tcx, &item); return self.resolve_labels(&item, value); } @@ -474,15 +474,15 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool { debug!("check_config: config={:?}", config); let (mut cfg, mut except, mut label) = (None, false, false); for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(CFG) { + if item.has_name(CFG) { let value = expect_associated_value(tcx, &item); debug!("check_config: searching for cfg {:?}", value); cfg = Some(config.contains(&(value, None))); } - if item.check_name(LABEL) { + if item.has_name(LABEL) { label = true; } - if item.check_name(EXCEPT) { + if item.has_name(EXCEPT) { except = true; } } diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs index b369be25218..e4b7c24a249 100644 --- a/src/librustc_index/bit_set.rs +++ b/src/librustc_index/bit_set.rs @@ -1034,6 +1034,30 @@ pub trait FiniteBitSetTy: fn checked_shr(self, rhs: u32) -> Option<Self>; } +impl FiniteBitSetTy for u32 { + const DOMAIN_SIZE: u32 = 32; + + const FILLED: Self = Self::MAX; + const EMPTY: Self = Self::MIN; + + const ONE: Self = 1u32; + const ZERO: Self = 0u32; + + fn checked_shl(self, rhs: u32) -> Option<Self> { + self.checked_shl(rhs) + } + + fn checked_shr(self, rhs: u32) -> Option<Self> { + self.checked_shr(rhs) + } +} + +impl std::fmt::Debug for FiniteBitSet<u32> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:032b}", self.0) + } +} + impl FiniteBitSetTy for u64 { const DOMAIN_SIZE: u32 = 64; diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs index 2dc803b9595..ea32a1ae5a5 100644 --- a/src/librustc_infer/infer/canonical/canonicalizer.rs +++ b/src/librustc_infer/infer/canonical/canonicalizer.rs @@ -199,8 +199,8 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse { // rust-lang/rust#57464: `impl Trait` can leak local // scopes (in manner violating typeck). Therefore, use // `delay_span_bug` to allow type error over an ICE. - ty::tls::with_context(|c| { - c.tcx.sess.delay_span_bug( + ty::tls::with(|tcx| { + tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!("unexpected region in query response: `{:?}`", r), ); diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs index 5b4d91de3ca..133c4bf2db5 100644 --- a/src/librustc_infer/infer/combine.rs +++ b/src/librustc_infer/infer/combine.rs @@ -166,7 +166,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { return self.unify_const_variable(!a_is_expected, vid, a); } (ty::ConstKind::Unevaluated(..), _) if self.tcx.lazy_normalization() => { - // FIXME(#59490): Need to remove the leak check to accomodate + // FIXME(#59490): Need to remove the leak check to accommodate // escaping bound variables here. if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { relation.const_equate_obligation(a, b); @@ -174,7 +174,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { return Ok(b); } (_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => { - // FIXME(#59490): Need to remove the leak check to accomodate + // FIXME(#59490): Need to remove the leak check to accommodate // escaping bound variables here. if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { relation.const_equate_obligation(a, b); diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 4fa6d9d2394..0125e0f48e8 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -195,7 +195,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) { - // Provide a more targetted error code and description. + // Provide a more targeted error code and description. err.code(rustc_errors::error_code!(E0772)); err.set_primary_message(&format!( "{} has {} but calling `{}` introduces an implicit `'static` lifetime \ diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index e50622a0053..ad30f5eda4d 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -17,7 +17,6 @@ use rustc_session::early_error; use rustc_session::lint; use rustc_session::parse::{CrateConfig, ParseSess}; use rustc_session::{DiagnosticOutput, Session}; -use rustc_span::edition; use rustc_span::source_map::{FileLoader, FileName}; use std::path::PathBuf; use std::result; @@ -208,13 +207,3 @@ pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R || create_compiler_and_run(config, f), ) } - -pub fn setup_callbacks_and_run_in_default_thread_pool_with_globals<R: Send>( - edition: edition::Edition, - f: impl FnOnce() -> R + Send, -) -> R { - // the 1 here is duplicating code in config.opts.debugging_opts.threads - // which also defaults to 1; it ultimately doesn't matter as the default - // isn't threaded, and just ignores this parameter - util::setup_callbacks_and_run_in_thread_pool_with_globals(edition, 1, &None, f) -} diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 125a020de37..3a562847d3e 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -752,7 +752,8 @@ impl<'tcx> QueryContext<'tcx> { where F: FnOnce(TyCtxt<'tcx>) -> R, { - ty::tls::enter_global(self.0, f) + let icx = ty::tls::ImplicitCtxt::new(self.0); + ty::tls::enter_context(&icx, |_| f(icx.tcx)) } pub fn print_stats(&mut self) { @@ -811,8 +812,9 @@ pub fn create_global_ctxt<'tcx>( }); // Do some initialization of the DepGraph that can only be done with the tcx available. - ty::tls::enter_global(&gcx, |tcx| { - tcx.sess.time("dep_graph_tcx_init", || rustc_incremental::dep_graph_tcx_init(tcx)); + let icx = ty::tls::ImplicitCtxt::new(&gcx); + ty::tls::enter_context(&icx, |_| { + icx.tcx.sess.time("dep_graph_tcx_init", || rustc_incremental::dep_graph_tcx_init(icx.tcx)); }); QueryContext(gcx) diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 5b648608b6b..bbb2f9d8b25 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -10,10 +10,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[cfg(parallel_compiler)] use rustc_data_structures::jobserver; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; use rustc_metadata::dynamic_lib::DynamicLibrary; -use rustc_middle::ty; use rustc_resolve::{self, Resolver}; use rustc_session as session; use rustc_session::config::{self, CrateType}; @@ -144,12 +143,10 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se let main_handler = move || { rustc_ast::with_session_globals(edition, || { - ty::tls::GCX_PTR.set(&Lock::new(0), || { - if let Some(stderr) = stderr { - io::set_panic(Some(box Sink(stderr.clone()))); - } - f() - }) + if let Some(stderr) = stderr { + io::set_panic(Some(box Sink(stderr.clone()))); + } + f() }) }; @@ -163,6 +160,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se stderr: &Option<Arc<Mutex<Vec<u8>>>>, f: F, ) -> R { + use rustc_middle::ty; crate::callbacks::setup_callbacks(); let mut config = rayon::ThreadPoolBuilder::new() @@ -189,12 +187,10 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se let main_handler = move |thread: rayon::ThreadBuilder| { rustc_ast::SESSION_GLOBALS.set(ast_session_globals, || { rustc_span::SESSION_GLOBALS.set(span_session_globals, || { - ty::tls::GCX_PTR.set(&Lock::new(0), || { - if let Some(stderr) = stderr { - io::set_panic(Some(box Sink(stderr.clone()))); - } - thread.run() - }) + if let Some(stderr) = stderr { + io::set_panic(Some(box Sink(stderr.clone()))); + } + thread.run() }) }) }; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e32c8fbee68..6515708e115 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -330,7 +330,7 @@ fn has_doc(attr: &ast::Attribute) -> bool { if let Some(list) = attr.meta_item_list() { for meta in list { - if meta.check_name(sym::include) || meta.check_name(sym::hidden) { + if meta.has_name(sym::include) || meta.has_name(sym::hidden) { return true; } } diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 84f5ea7bcda..31d30a264a5 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -573,7 +573,7 @@ pub trait LintContext: Sized { } } BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { - stability::deprecation_suggestion(&mut db, suggestion, span) + stability::deprecation_suggestion(&mut db, "macro", suggestion, span) } BuiltinLintDiagnostics::UnusedDocComment(span) => { db.span_label(span, "rustdoc does not generate documentation for macro invocations"); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 8d8fb8c3c60..1e98ddbd7db 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -275,10 +275,26 @@ declare_lint_pass!(PathStatements => [PATH_STATEMENTS]); impl<'tcx> LateLintPass<'tcx> for PathStatements { fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) { - if let hir::StmtKind::Semi(ref expr) = s.kind { + if let hir::StmtKind::Semi(expr) = s.kind { if let hir::ExprKind::Path(_) = expr.kind { cx.struct_span_lint(PATH_STATEMENTS, s.span, |lint| { - lint.build("path statement with no effect").emit() + let ty = cx.typeck_results().expr_ty(expr); + if ty.needs_drop(cx.tcx, cx.param_env) { + let mut lint = lint.build("path statement drops value"); + if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) { + lint.span_suggestion( + s.span, + "use `drop` to clarify the intent", + format!("drop({});", snippet), + Applicability::MachineApplicable, + ); + } else { + lint.span_help(s.span, "use `drop` to clarify the intent"); + } + lint.emit() + } else { + lint.build("path statement with no effect").emit() + } }); } } @@ -422,7 +438,7 @@ trait UnusedDelimLint { lhs_needs_parens || (followed_by_block && match inner.kind { - ExprKind::Ret(_) | ExprKind::Break(..) => true, + ExprKind::Ret(_) | ExprKind::Break(..) | ExprKind::Yield(..) => true, _ => parser::contains_exterior_struct_lit(&inner), }) } @@ -520,7 +536,10 @@ trait UnusedDelimLint { (cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right)) } - While(ref cond, ref block, ..) => { + // Do not lint `unused_braces` in `while let` expressions. + While(ref cond, ref block, ..) + if !matches!(cond.kind, Let(_, _)) || Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => + { let left = e.span.lo() + rustc_span::BytePos(5); let right = block.span.lo(); (cond, UnusedDelimsCtx::WhileCond, true, Some(left), Some(right)) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index a4ccc8c74c8..9bc6c054e4d 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -13,7 +13,7 @@ use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_index::vec::IndexVec; -use rustc_middle::middle::cstore::{CrateSource, DepKind, ExternCrate}; +use rustc_middle::middle::cstore::{CrateDepKind, CrateSource, ExternCrate}; use rustc_middle::middle::cstore::{ExternCrateSource, MetadataLoaderDyn}; use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, ExternLocation}; @@ -306,7 +306,7 @@ impl<'a> CrateLoader<'a> { host_lib: Option<Library>, root: Option<&CratePaths>, lib: Library, - dep_kind: DepKind, + dep_kind: CrateDepKind, name: Symbol, ) -> Result<CrateNum, CrateError> { let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate"); @@ -437,7 +437,7 @@ impl<'a> CrateLoader<'a> { &'b mut self, name: Symbol, span: Span, - dep_kind: DepKind, + dep_kind: CrateDepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> CrateNum { if dep.is_none() { @@ -450,7 +450,7 @@ impl<'a> CrateLoader<'a> { fn maybe_resolve_crate<'b>( &'b mut self, name: Symbol, - mut dep_kind: DepKind, + mut dep_kind: CrateDepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> Result<CrateNum, CrateError> { info!("resolving crate `{}`", name); @@ -487,7 +487,7 @@ impl<'a> CrateLoader<'a> { match self.load(&mut locator)? { Some(res) => (res, None), None => { - dep_kind = DepKind::MacrosOnly; + dep_kind = CrateDepKind::MacrosOnly; match self.load_proc_macro(&mut locator, path_kind)? { Some(res) => res, None => return Err(locator.into_error()), @@ -500,7 +500,7 @@ impl<'a> CrateLoader<'a> { (LoadResult::Previous(cnum), None) => { let data = self.cstore.get_crate_data(cnum); if data.is_proc_macro_crate() { - dep_kind = DepKind::MacrosOnly; + dep_kind = CrateDepKind::MacrosOnly; } data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind)); Ok(cnum) @@ -560,7 +560,7 @@ impl<'a> CrateLoader<'a> { crate_root: &CrateRoot<'_>, metadata: &MetadataBlob, krate: CrateNum, - dep_kind: DepKind, + dep_kind: CrateDepKind, ) -> Result<CrateNumMap, CrateError> { debug!("resolving deps of external crate"); if crate_root.is_proc_macro_crate() { @@ -579,7 +579,7 @@ impl<'a> CrateLoader<'a> { dep.name, dep.hash, dep.extra_filename ); let dep_kind = match dep_kind { - DepKind::MacrosOnly => DepKind::MacrosOnly, + CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly, _ => dep.kind, }; let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((root, &dep)))?; @@ -646,7 +646,7 @@ impl<'a> CrateLoader<'a> { self.inject_dependency_if(cnum, "a panic runtime", &|data| { data.needs_panic_runtime() }); - runtime_found = runtime_found || data.dep_kind() == DepKind::Explicit; + runtime_found = runtime_found || data.dep_kind() == CrateDepKind::Explicit; } }); @@ -675,7 +675,7 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime @@ -705,7 +705,7 @@ impl<'a> CrateLoader<'a> { info!("loading profiler"); let name = sym::profiler_builtins; - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -901,9 +901,9 @@ impl<'a> CrateLoader<'a> { None => item.ident.name, }; let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) { - DepKind::MacrosOnly + CrateDepKind::MacrosOnly } else { - DepKind::Explicit + CrateDepKind::Explicit }; let cnum = self.resolve_crate(name, item.span, dep_kind, None); @@ -925,7 +925,7 @@ impl<'a> CrateLoader<'a> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, DepKind::Explicit, None); + let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, None); self.update_extern_crate( cnum, @@ -942,6 +942,6 @@ impl<'a> CrateLoader<'a> { } pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> { - self.maybe_resolve_crate(name, DepKind::Explicit, None).ok() + self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok() } } diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs index aa5fafcc614..bb5ae4d0557 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/src/librustc_metadata/dependency_format.rs @@ -56,7 +56,7 @@ use crate::creader::CStore; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic}; -use rustc_middle::middle::cstore::{self, DepKind}; +use rustc_middle::middle::cstore::{self, CrateDepKind}; use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage}; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; @@ -188,7 +188,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { let src = tcx.used_crate_source(cnum); if src.dylib.is_none() && !formats.contains_key(&cnum) - && tcx.dep_kind(cnum) == DepKind::Explicit + && tcx.dep_kind(cnum) == CrateDepKind::Explicit { assert!(src.rlib.is_some() || src.rmeta.is_some()); log::info!("adding staticlib: {}", tcx.crate_name(cnum)); @@ -284,7 +284,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> { let last_crate = tcx.crates().len(); let mut ret = (1..last_crate + 1) .map(|cnum| { - if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit { + if tcx.dep_kind(CrateNum::new(cnum)) == CrateDepKind::Explicit { Linkage::Static } else { Linkage::NotLinked diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index fc4235a3eda..d01c598d059 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -58,7 +58,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { let mut kind_specified = false; for item in items.iter() { - if item.check_name(sym::kind) { + if item.has_name(sym::kind) { kind_specified = true; let kind = match item.value_str() { Some(name) => name, @@ -84,9 +84,9 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { NativeLibKind::Unspecified } }; - } else if item.check_name(sym::name) { + } else if item.has_name(sym::name) { lib.name = item.value_str(); - } else if item.check_name(sym::cfg) { + } else if item.has_name(sym::cfg) { let cfg = match item.meta_item_list() { Some(list) => list, None => continue, // skip like historical compilers @@ -98,7 +98,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { } else { self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`"); } - } else if item.check_name(sym::wasm_import_module) { + } else if item.has_name(sym::wasm_import_module) { match item.value_str() { Some(s) => lib.wasm_import_module = Some(s), None => { diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 414c3ad633e..9fb4e08e284 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -78,7 +78,8 @@ crate struct CrateMetadata { /// Trait impl data. /// FIXME: Used only from queries and can use query cache, /// so pre-decoding can probably be avoided. - trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>, + trait_impls: + FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>>, /// Proc macro descriptions for this crate, if it's a proc macro crate. raw_proc_macros: Option<&'static [ProcMacro]>, /// Source maps for code from the crate. @@ -100,7 +101,7 @@ crate struct CrateMetadata { /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime. dependencies: Lock<Vec<CrateNum>>, /// How to link (or not link) this crate to the currently compiled crate. - dep_kind: Lock<DepKind>, + dep_kind: Lock<CrateDepKind>, /// Filesystem location of this crate. source: CrateSource, /// Whether or not this crate should be consider a private dependency @@ -1150,7 +1151,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .decode((self, tcx)) } - fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u64> { + fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u32> { self.root .tables .unused_generic_params @@ -1289,7 +1290,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { &self, tcx: TyCtxt<'tcx>, filter: Option<DefId>, - ) -> &'tcx [DefId] { + ) -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { if self.root.is_proc_macro_crate() { // proc-macro crates export no trait impls. return &[]; @@ -1305,16 +1306,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { if let Some(filter) = filter { if let Some(impls) = self.trait_impls.get(&filter) { - tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx))) + tcx.arena.alloc_from_iter( + impls.decode(self).map(|(idx, simplified_self_ty)| { + (self.local_def_id(idx), simplified_self_ty) + }), + ) } else { &[] } } else { - tcx.arena.alloc_from_iter( - self.trait_impls - .values() - .flat_map(|impls| impls.decode(self).map(|idx| self.local_def_id(idx))), - ) + tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| { + impls + .decode(self) + .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)) + })) } } @@ -1669,7 +1674,7 @@ impl CrateMetadata { raw_proc_macros: Option<&'static [ProcMacro]>, cnum: CrateNum, cnum_map: CrateNumMap, - dep_kind: DepKind, + dep_kind: CrateDepKind, source: CrateSource, private_dep: bool, host_hash: Option<Svh>, @@ -1727,11 +1732,11 @@ impl CrateMetadata { &self.source } - crate fn dep_kind(&self) -> DepKind { + crate fn dep_kind(&self) -> CrateDepKind { *self.dep_kind.lock() } - crate fn update_dep_kind(&self, f: impl FnOnce(DepKind) -> DepKind) { + crate fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) { self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind)) } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 49aaa845bc2..acae44e6bf7 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -267,7 +267,7 @@ impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> { // real code should never need to care about this. // // 2. Using `Span::def_site` or `Span::mixed_site` will not - // include any hygiene information associated with the defintion + // include any hygiene information associated with the definition // site. This means that a proc-macro cannot emit a `$crate` // identifier which resolves to one of its dependencies, // which also should never come up in practice. @@ -1134,8 +1134,11 @@ impl EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id)); - record!(self.tables.unused_generic_params[def_id.to_def_id()] <- - self.tcx.unused_generic_params(def_id)); + + let unused = self.tcx.unused_generic_params(def_id); + if !unused.is_empty() { + record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused); + } } } @@ -1607,7 +1610,7 @@ impl EncodeContext<'a, 'tcx> { .into_iter() .map(|(trait_def_id, mut impls)| { // Bring everything into deterministic order for hashing - impls.sort_by_cached_key(|&index| { + impls.sort_by_cached_key(|&(index, _)| { tcx.hir().definitions().def_path_hash(LocalDefId { local_def_index: index }) }); @@ -1849,7 +1852,7 @@ impl EncodeContext<'a, 'tcx> { struct ImplVisitor<'tcx> { tcx: TyCtxt<'tcx>, - impls: FxHashMap<DefId, Vec<DefIndex>>, + impls: FxHashMap<DefId, Vec<(DefIndex, Option<ty::fast_reject::SimplifiedType>)>>, } impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { @@ -1857,7 +1860,13 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { if let hir::ItemKind::Impl { .. } = item.kind { let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id.to_def_id()) { - self.impls.entry(trait_ref.def_id).or_default().push(impl_id.local_def_index); + let simplified_self_ty = + ty::fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), false); + + self.impls + .entry(trait_ref.def_id) + .or_default() + .push((impl_id.local_def_index, simplified_self_ty)); } } } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 1837b86f4b5..1c287be9f6b 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, DefIndex}; use rustc_hir::lang_items; use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; use rustc_middle::hir::exports::Export; -use rustc_middle::middle::cstore::{DepKind, ForeignModule, LinkagePreference, NativeLib}; +use rustc_middle::middle::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc_middle::mir; use rustc_middle::ty::{self, ReprOptions, Ty}; @@ -226,14 +226,14 @@ crate struct CrateDep { pub name: Symbol, pub hash: Svh, pub host_hash: Option<Svh>, - pub kind: DepKind, + pub kind: CrateDepKind, pub extra_filename: String, } #[derive(RustcEncodable, RustcDecodable)] crate struct TraitImpls { trait_id: (u32, DefIndex), - impls: Lazy<[DefIndex]>, + impls: Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>, } /// Define `LazyTables` and `TableBuilders` at the same time. @@ -285,7 +285,7 @@ define_tables! { super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>, mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>, promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>, - unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u64>>>, + unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>, } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 678fcfe6539..03431cb5a88 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -12,7 +12,6 @@ doctest = false [dependencies] rustc_arena = { path = "../librustc_arena" } bitflags = "1.2.1" -scoped-tls = "1.0" log = { package = "tracing", version = "0.1" } rustc-rayon-core = "0.3.0" polonius-engine = "0.12.0" diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs index b7dccb8d8ce..a49287840e1 100644 --- a/src/librustc_middle/lib.rs +++ b/src/librustc_middle/lib.rs @@ -55,8 +55,6 @@ #[macro_use] extern crate bitflags; #[macro_use] -extern crate scoped_tls; -#[macro_use] extern crate rustc_macros; #[macro_use] extern crate rustc_data_structures; diff --git a/src/librustc_middle/middle/cstore.rs b/src/librustc_middle/middle/cstore.rs index 97e877df966..0a34c06adf0 100644 --- a/src/librustc_middle/middle/cstore.rs +++ b/src/librustc_middle/middle/cstore.rs @@ -40,7 +40,7 @@ impl CrateSource { #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] #[derive(HashStable)] -pub enum DepKind { +pub enum CrateDepKind { /// A dependency that is only used for its macros. MacrosOnly, /// A dependency that is always injected into the dependency list and so @@ -51,11 +51,11 @@ pub enum DepKind { Explicit, } -impl DepKind { +impl CrateDepKind { pub fn macros_only(self) -> bool { match self { - DepKind::MacrosOnly => true, - DepKind::Implicit | DepKind::Explicit => false, + CrateDepKind::MacrosOnly => true, + CrateDepKind::Implicit | CrateDepKind::Explicit => false, } } } diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs index 5f7ff54fd31..b913d7dd4ad 100644 --- a/src/librustc_middle/middle/stability.rs +++ b/src/librustc_middle/middle/stability.rs @@ -166,29 +166,31 @@ pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) pub fn deprecation_suggestion( diag: &mut DiagnosticBuilder<'_>, + kind: &str, suggestion: Option<Symbol>, span: Span, ) { if let Some(suggestion) = suggestion { diag.span_suggestion( span, - "replace the use of the deprecated item", + &format!("replace the use of the deprecated {}", kind), suggestion.to_string(), Applicability::MachineApplicable, ); } } -pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) { +pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) { let (message, lint) = if deprecation_in_effect( depr.is_since_rustc_version, depr.since.map(Symbol::as_str).as_deref(), ) { - (format!("use of deprecated item '{}'", path), DEPRECATED) + (format!("use of deprecated {} `{}`", kind, path), DEPRECATED) } else { ( format!( - "use of item '{}' that will be deprecated in future version {}", + "use of {} `{}` that will be deprecated in future version {}", + kind, path, depr.since.unwrap() ), @@ -224,6 +226,7 @@ fn late_report_deprecation( lint: &'static Lint, span: Span, hir_id: HirId, + def_id: DefId, ) { if span.in_derive_expansion() { return; @@ -232,7 +235,8 @@ fn late_report_deprecation( tcx.struct_span_lint_hir(lint, hir_id, span, |lint| { let mut diag = lint.build(message); if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { - deprecation_suggestion(&mut diag, suggestion, span); + let kind = tcx.def_kind(def_id).descr(def_id); + deprecation_suggestion(&mut diag, kind, suggestion, span); } diag.emit() }); @@ -304,8 +308,9 @@ impl<'tcx> TyCtxt<'tcx> { // #[rustc_deprecated] however wants to emit down the whole // hierarchy. if !skip || depr_entry.attr.is_since_rustc_version { - let (message, lint) = - deprecation_message(&depr_entry.attr, &self.def_path_str(def_id)); + let path = &self.def_path_str(def_id); + let kind = self.def_kind(def_id).descr(def_id); + let (message, lint) = deprecation_message(&depr_entry.attr, kind, path); late_report_deprecation( self, &message, @@ -313,6 +318,7 @@ impl<'tcx> TyCtxt<'tcx> { lint, span, id, + def_id, ); } }; diff --git a/src/librustc_middle/mir/coverage/mod.rs b/src/librustc_middle/mir/coverage/mod.rs index 82365ef6a73..6b1514da644 100644 --- a/src/librustc_middle/mir/coverage/mod.rs +++ b/src/librustc_middle/mir/coverage/mod.rs @@ -4,8 +4,11 @@ pub mod count_code_region_args { pub const FUNCTION_SOURCE_HASH: usize = 0; pub const COUNTER_ID: usize = 1; - pub const START_BYTE_POS: usize = 2; - pub const END_BYTE_POS: usize = 3; + pub const FILE_NAME: usize = 2; + pub const START_LINE: usize = 3; + pub const START_COL: usize = 4; + pub const END_LINE: usize = 5; + pub const END_COL: usize = 6; } /// Positional arguments to `libcore::coverage_counter_add()` and @@ -14,12 +17,18 @@ pub mod coverage_counter_expression_args { pub const EXPRESSION_ID: usize = 0; pub const LEFT_ID: usize = 1; pub const RIGHT_ID: usize = 2; - pub const START_BYTE_POS: usize = 3; - pub const END_BYTE_POS: usize = 4; + pub const FILE_NAME: usize = 3; + pub const START_LINE: usize = 4; + pub const START_COL: usize = 5; + pub const END_LINE: usize = 6; + pub const END_COL: usize = 7; } /// Positional arguments to `libcore::coverage_unreachable()` pub mod coverage_unreachable_args { - pub const START_BYTE_POS: usize = 0; - pub const END_BYTE_POS: usize = 1; + pub const FILE_NAME: usize = 0; + pub const START_LINE: usize = 1; + pub const START_COL: usize = 2; + pub const END_LINE: usize = 3; + pub const END_COL: usize = 4; } diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index 1d76bb525eb..c904cd83a78 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -27,7 +27,7 @@ pub enum ErrorHandled { TooGeneric, } -CloneTypeFoldableImpls! { +CloneTypeFoldableAndLiftImpls! { ErrorHandled, } @@ -242,9 +242,9 @@ impl From<ErrorHandled> for InterpErrorInfo<'_> { impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> { fn from(kind: InterpError<'tcx>) -> Self { - let capture_backtrace = tls::with_context_opt(|ctxt| { - if let Some(ctxt) = ctxt { - *Lock::borrow(&ctxt.tcx.sess.ctfe_backtrace) + let capture_backtrace = tls::with_opt(|tcx| { + if let Some(tcx) = tcx { + *Lock::borrow(&tcx.sess.ctfe_backtrace) } else { CtfeBacktrace::Disabled } diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs index 2c76f0b5ad0..b4e7a5b98e3 100644 --- a/src/librustc_middle/mir/interpret/value.rs +++ b/src/librustc_middle/mir/interpret/value.rs @@ -56,6 +56,15 @@ impl<'tcx> ConstValue<'tcx> { } } + pub fn try_to_str_slice(&self) -> Option<&'tcx str> { + if let ConstValue::Slice { data, start, end } = *self { + ::std::str::from_utf8(data.inspect_with_undef_and_ptr_outside_interpreter(start..end)) + .ok() + } else { + None + } + } + pub fn try_to_bits(&self, size: Size) -> Option<u128> { self.try_to_scalar()?.to_bits(size).ok() } diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 31b8de500e0..3b0c480f6d4 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -2,7 +2,7 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html -use crate::mir::interpret::{GlobalAlloc, Scalar}; +use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar}; use crate::mir::visit::MirVisitable; use crate::ty::adjustment::PointerCast; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; @@ -1842,6 +1842,33 @@ impl<'tcx> Operand<'tcx> { } } + /// Convenience helper to make a literal-like constant from a given `&str` slice. + /// Since this is used to synthesize MIR, assumes `user_ty` is None. + pub fn const_from_str(tcx: TyCtxt<'tcx>, val: &str, span: Span) -> Operand<'tcx> { + let tcx = tcx; + let allocation = Allocation::from_byte_aligned_bytes(val.as_bytes()); + let allocation = tcx.intern_const_alloc(allocation); + let const_val = ConstValue::Slice { data: allocation, start: 0, end: val.len() }; + let ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.types.str_); + Operand::Constant(box Constant { + span, + user_ty: None, + literal: ty::Const::from_value(tcx, const_val, ty), + }) + } + + /// Convenience helper to make a `ConstValue` from the given `Operand`, assuming that `Operand` + /// wraps a constant value (such as a `&str` slice). Panics if this is not the case. + pub fn value_from_const(operand: &Operand<'tcx>) -> ConstValue<'tcx> { + match operand { + Operand::Constant(constant) => match constant.literal.val.try_to_value() { + Some(const_value) => const_value, + _ => panic!("{:?}: ConstValue expected", constant.literal.val), + }, + _ => panic!("{:?}: Constant expected", operand), + } + } + pub fn to_copy(&self) -> Self { match *self { Operand::Copy(_) | Operand::Constant(_) => self.clone(), diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 69f1366abf8..a8f6723a356 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -1125,11 +1125,11 @@ rustc_queries! { TypeChecking { query implementations_of_trait(_: (CrateNum, DefId)) - -> &'tcx [DefId] { + -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { desc { "looking up implementations of a trait in a crate" } } query all_trait_implementations(_: CrateNum) - -> &'tcx [DefId] { + -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { desc { "looking up all (?) trait implementations" } } } @@ -1186,7 +1186,7 @@ rustc_queries! { } Other { - query dep_kind(_: CrateNum) -> DepKind { + query dep_kind(_: CrateNum) -> CrateDepKind { eval_always desc { "fetching what a dependency looks like" } } @@ -1319,7 +1319,7 @@ rustc_queries! { query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> { desc { "codegen_unit" } } - query unused_generic_params(key: DefId) -> FiniteBitSet<u64> { + query unused_generic_params(key: DefId) -> FiniteBitSet<u32> { cache_on_disk_if { key.is_local() } desc { |tcx| "determining which generic parameters are unused by `{}`", diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index d2747e5fc65..585f29386a8 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -30,7 +30,6 @@ pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx pub use self::ImplSource::*; pub use self::ObligationCauseCode::*; -pub use self::SelectionError::*; pub use self::chalk::{ ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner, @@ -86,7 +85,7 @@ pub enum Reveal { /// /// We do not want to intern this as there are a lot of obligation causes which /// only live for a short period of time. -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash, Lift)] pub struct ObligationCause<'tcx> { /// `None` for `ObligationCause::dummy`, `Some` otherwise. data: Option<Rc<ObligationCauseData<'tcx>>>, @@ -111,7 +110,7 @@ impl Deref for ObligationCause<'tcx> { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub struct ObligationCauseData<'tcx> { pub span: Span, @@ -169,14 +168,14 @@ impl<'tcx> ObligationCause<'tcx> { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub struct UnifyReceiverContext<'tcx> { pub assoc_item: ty::AssocItem, pub param_env: ty::ParamEnv<'tcx>, pub substs: SubstsRef<'tcx>, } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from the span. MiscObligation, @@ -343,7 +342,7 @@ impl ObligationCauseCode<'_> { #[cfg(target_arch = "x86_64")] static_assert_size!(ObligationCauseCode<'_>, 32); -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub struct MatchExpressionArmCause<'tcx> { pub arm_span: Span, pub source: hir::MatchSource, @@ -359,7 +358,7 @@ pub struct IfExpressionCause { pub semicolon: Option<Span>, } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub struct DerivedObligationCause<'tcx> { /// The trait reference of the parent obligation that led to the /// current obligation. Note that only trait obligations lead to @@ -371,7 +370,7 @@ pub struct DerivedObligationCause<'tcx> { pub parent_code: Rc<ObligationCauseCode<'tcx>>, } -#[derive(Clone, Debug, TypeFoldable)] +#[derive(Clone, Debug, TypeFoldable, Lift)] pub enum SelectionError<'tcx> { Unimplemented, OutputTypeParameterMismatch( @@ -427,7 +426,7 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>; /// ### The type parameter `N` /// /// See explanation on `ImplSourceUserDefinedData`. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub enum ImplSource<'tcx, N> { /// ImplSource identifying a particular impl. ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>), @@ -558,14 +557,14 @@ impl<'tcx, N> ImplSource<'tcx, N> { /// is `Obligation`, as one might expect. During codegen, however, this /// is `()`, because codegen only requires a shallow resolution of an /// impl, and nested obligations are satisfied later. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceUserDefinedData<'tcx, N> { pub impl_def_id: DefId, pub substs: SubstsRef<'tcx>, pub nested: Vec<N>, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceGeneratorData<'tcx, N> { pub generator_def_id: DefId, pub substs: SubstsRef<'tcx>, @@ -574,7 +573,7 @@ pub struct ImplSourceGeneratorData<'tcx, N> { pub nested: Vec<N>, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceClosureData<'tcx, N> { pub closure_def_id: DefId, pub substs: SubstsRef<'tcx>, @@ -583,18 +582,18 @@ pub struct ImplSourceClosureData<'tcx, N> { pub nested: Vec<N>, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceAutoImplData<N> { pub trait_def_id: DefId, pub nested: Vec<N>, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceBuiltinData<N> { pub nested: Vec<N>, } -#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceObjectData<'tcx, N> { /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`. pub upcast_trait_ref: ty::PolyTraitRef<'tcx>, @@ -607,17 +606,17 @@ pub struct ImplSourceObjectData<'tcx, N> { pub nested: Vec<N>, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceFnPointerData<'tcx, N> { pub fn_ty: Ty<'tcx>, pub nested: Vec<N>, } // FIXME(@lcnr): This should be refactored and merged with other builtin vtables. -#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] pub struct ImplSourceDiscriminantKindData; -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct ImplSourceTraitAliasData<'tcx, N> { pub alias_def_id: DefId, pub substs: SubstsRef<'tcx>, diff --git a/src/librustc_middle/traits/select.rs b/src/librustc_middle/traits/select.rs index a12f5910b14..6ad514c6be2 100644 --- a/src/librustc_middle/traits/select.rs +++ b/src/librustc_middle/traits/select.rs @@ -6,29 +6,18 @@ use self::EvaluationResult::*; use super::{SelectionError, SelectionResult}; -use crate::dep_graph::DepNodeIndex; -use crate::ty::{self, TyCtxt}; +use crate::ty; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lock; use rustc_hir::def_id::DefId; +use rustc_query_system::cache::Cache; -#[derive(Clone, Default)] -pub struct SelectionCache<'tcx> { - pub hashmap: Lock< - FxHashMap< - ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>, - WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>, - >, - >, -} +pub type SelectionCache<'tcx> = Cache< + ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>, + SelectionResult<'tcx, SelectionCandidate<'tcx>>, +>; -impl<'tcx> SelectionCache<'tcx> { - /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` - pub fn clear(&self) { - *self.hashmap.borrow_mut() = Default::default(); - } -} +pub type EvaluationCache<'tcx> = + Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, EvaluationResult>; /// The selection process begins by considering all impls, where /// clauses, and so forth that might resolve an obligation. Sometimes @@ -264,75 +253,3 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> { SelectionError::Overflow } } - -#[derive(Clone, Default)] -pub struct EvaluationCache<'tcx> { - pub hashmap: Lock< - FxHashMap<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, WithDepNode<EvaluationResult>>, - >, -} - -impl<'tcx> EvaluationCache<'tcx> { - /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` - pub fn clear(&self) { - *self.hashmap.borrow_mut() = Default::default(); - } -} - -#[derive(Clone, Eq, PartialEq)] -pub struct WithDepNode<T> { - dep_node: DepNodeIndex, - cached_value: T, -} - -impl<T: Clone> WithDepNode<T> { - pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { - WithDepNode { dep_node, cached_value } - } - - pub fn get(&self, tcx: TyCtxt<'_>) -> T { - tcx.dep_graph.read_index(self.dep_node); - self.cached_value.clone() - } -} - -#[derive(Clone, Debug)] -pub enum IntercrateAmbiguityCause { - DownstreamCrate { trait_desc: String, self_desc: Option<String> }, - UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> }, - ReservationImpl { message: String }, -} - -impl IntercrateAmbiguityCause { - /// Emits notes when the overlap is caused by complex intercrate ambiguities. - /// See #23980 for details. - pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) { - err.note(&self.intercrate_ambiguity_hint()); - } - - pub fn intercrate_ambiguity_hint(&self) -> String { - match self { - &IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => { - let self_desc = if let &Some(ref ty) = self_desc { - format!(" for type `{}`", ty) - } else { - String::new() - }; - format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc) - } - &IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => { - let self_desc = if let &Some(ref ty) = self_desc { - format!(" for type `{}`", ty) - } else { - String::new() - }; - format!( - "upstream crates may add a new impl of trait `{}`{} \ - in future versions", - trait_desc, self_desc - ) - } - &IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(), - } - } -} diff --git a/src/librustc_middle/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs index 18b4371053a..d73fc628ceb 100644 --- a/src/librustc_middle/traits/structural_impls.rs +++ b/src/librustc_middle/traits/structural_impls.rs @@ -1,8 +1,6 @@ use crate::traits; -use crate::ty::{Lift, TyCtxt}; use std::fmt; -use std::rc::Rc; // Structural impls for the structs in `traits`. @@ -107,222 +105,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, /////////////////////////////////////////////////////////////////////////// // Lift implementations -impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> { - type Lifted = traits::SelectionError<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - match *self { - super::Unimplemented => Some(super::Unimplemented), - super::OutputTypeParameterMismatch(a, b, ref err) => { - tcx.lift(&(a, b)).and_then(|(a, b)| { - tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err)) - }) - } - super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)), - super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)), - super::Overflow => Some(super::Overflow), - } - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { - type Lifted = traits::ObligationCauseCode<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - match *self { - super::ReturnNoExpression => Some(super::ReturnNoExpression), - super::MiscObligation => Some(super::MiscObligation), - super::SliceOrArrayElem => Some(super::SliceOrArrayElem), - super::TupleElem => Some(super::TupleElem), - super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf), - super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)), - super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)), - super::ReferenceOutlivesReferent(ty) => { - tcx.lift(&ty).map(super::ReferenceOutlivesReferent) - } - super::ObjectTypeBound(ty, r) => { - tcx.lift(&ty).and_then(|ty| tcx.lift(&r).map(|r| super::ObjectTypeBound(ty, r))) - } - super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation), - super::Coercion { source, target } => { - Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? }) - } - super::AssignmentLhsSized => Some(super::AssignmentLhsSized), - super::TupleInitializerSized => Some(super::TupleInitializerSized), - super::StructInitializerSized => Some(super::StructInitializerSized), - super::VariableType(id) => Some(super::VariableType(id)), - super::ReturnValue(id) => Some(super::ReturnValue(id)), - super::ReturnType => Some(super::ReturnType), - super::SizedArgumentType(sp) => Some(super::SizedArgumentType(sp)), - super::SizedReturnType => Some(super::SizedReturnType), - super::SizedYieldType => Some(super::SizedYieldType), - super::InlineAsmSized => Some(super::InlineAsmSized), - super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)), - super::FieldSized { adt_kind, span, last } => { - Some(super::FieldSized { adt_kind, span, last }) - } - super::ConstSized => Some(super::ConstSized), - super::ConstPatternStructural => Some(super::ConstPatternStructural), - super::SharedStatic => Some(super::SharedStatic), - super::BuiltinDerivedObligation(ref cause) => { - tcx.lift(cause).map(super::BuiltinDerivedObligation) - } - super::ImplDerivedObligation(ref cause) => { - tcx.lift(cause).map(super::ImplDerivedObligation) - } - super::DerivedObligation(ref cause) => tcx.lift(cause).map(super::DerivedObligation), - super::CompareImplConstObligation => Some(super::CompareImplConstObligation), - super::CompareImplMethodObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } => Some(super::CompareImplMethodObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - }), - super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => { - Some(super::CompareImplTypeObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - }) - } - super::ExprAssignable => Some(super::ExprAssignable), - super::MatchExpressionArm(box super::MatchExpressionArmCause { - arm_span, - source, - ref prior_arms, - last_ty, - scrut_hir_id, - }) => tcx.lift(&last_ty).map(|last_ty| { - super::MatchExpressionArm(box super::MatchExpressionArmCause { - arm_span, - source, - prior_arms: prior_arms.clone(), - last_ty, - scrut_hir_id, - }) - }), - super::Pattern { span, root_ty, origin_expr } => { - tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr }) - } - super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => { - Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon })) - } - super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse), - super::MainFunctionType => Some(super::MainFunctionType), - super::StartFunctionType => Some(super::StartFunctionType), - super::IntrinsicType => Some(super::IntrinsicType), - super::MethodReceiver => Some(super::MethodReceiver), - super::UnifyReceiver(ref ctxt) => tcx.lift(ctxt).map(|ctxt| super::UnifyReceiver(ctxt)), - super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)), - super::TrivialBound => Some(super::TrivialBound), - } - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::UnifyReceiverContext<'a> { - type Lifted = traits::UnifyReceiverContext<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - tcx.lift(&self.param_env).and_then(|param_env| { - tcx.lift(&self.substs).map(|substs| traits::UnifyReceiverContext { - assoc_item: self.assoc_item, - param_env, - substs, - }) - }) - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { - type Lifted = traits::DerivedObligationCause<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| { - tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause { - parent_trait_ref: trait_ref, - parent_code: Rc::new(code), - }) - }) - } -} - -impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> { - type Lifted = traits::ObligationCause<'tcx>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - tcx.lift(&self.code).map(|code| traits::ObligationCause::new(self.span, self.body_id, code)) - } -} - -// For codegen only. -impl<'a, 'tcx> Lift<'tcx> for traits::ImplSource<'a, ()> { - type Lifted = traits::ImplSource<'tcx, ()>; - fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - match self.clone() { - traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData { - impl_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| { - traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData { - impl_def_id, - substs, - nested, - }) - }), - traits::ImplSourceAutoImpl(t) => Some(traits::ImplSourceAutoImpl(t)), - traits::ImplSourceGenerator(traits::ImplSourceGeneratorData { - generator_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| { - traits::ImplSourceGenerator(traits::ImplSourceGeneratorData { - generator_def_id, - substs, - nested, - }) - }), - traits::ImplSourceClosure(traits::ImplSourceClosureData { - closure_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| { - traits::ImplSourceClosure(traits::ImplSourceClosureData { - closure_def_id, - substs, - nested, - }) - }), - traits::ImplSourceFnPointer(traits::ImplSourceFnPointerData { fn_ty, nested }) => { - tcx.lift(&fn_ty).map(|fn_ty| { - traits::ImplSourceFnPointer(traits::ImplSourceFnPointerData { fn_ty, nested }) - }) - } - traits::ImplSourceDiscriminantKind(traits::ImplSourceDiscriminantKindData) => { - Some(traits::ImplSourceDiscriminantKind(traits::ImplSourceDiscriminantKindData)) - } - traits::ImplSourceParam(n) => Some(traits::ImplSourceParam(n)), - traits::ImplSourceBuiltin(n) => Some(traits::ImplSourceBuiltin(n)), - traits::ImplSourceObject(traits::ImplSourceObjectData { - upcast_trait_ref, - vtable_base, - nested, - }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| { - traits::ImplSourceObject(traits::ImplSourceObjectData { - upcast_trait_ref: trait_ref, - vtable_base, - nested, - }) - }), - traits::ImplSourceTraitAlias(traits::ImplSourceTraitAliasData { - alias_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| { - traits::ImplSourceTraitAlias(traits::ImplSourceTraitAliasData { - alias_def_id, - substs, - nested, - }) - }), - } - } +CloneTypeFoldableAndLiftImpls! { + super::IfExpressionCause, + super::ImplSourceDiscriminantKindData, } diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index 775d755444d..6cbf5db8373 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1632,7 +1632,6 @@ pub mod tls { use crate::ty::query; use rustc_data_structures::sync::{self, Lock}; use rustc_data_structures::thin_vec::ThinVec; - use rustc_data_structures::OnDrop; use rustc_errors::Diagnostic; use std::mem; @@ -1649,8 +1648,7 @@ pub mod tls { /// in this module. #[derive(Clone)] pub struct ImplicitCtxt<'a, 'tcx> { - /// The current `TyCtxt`. Initially created by `enter_global` and updated - /// by `enter_local` with a new local interner. + /// The current `TyCtxt`. pub tcx: TyCtxt<'tcx>, /// The current query job, if any. This is updated by `JobOwner::start` in @@ -1669,6 +1667,13 @@ pub mod tls { pub task_deps: Option<&'a Lock<TaskDeps>>, } + impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> { + pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self { + let tcx = TyCtxt { gcx }; + ImplicitCtxt { tcx, query: None, diagnostics: None, layout_depth: 0, task_deps: None } + } + } + /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs /// to `value` during the call to `f`. It is restored to its previous value after. /// This is used to set the pointer to the new `ImplicitCtxt`. @@ -1682,7 +1687,7 @@ pub mod tls { /// This is used to get the pointer to the current `ImplicitCtxt`. #[cfg(parallel_compiler)] #[inline] - fn get_tlv() -> usize { + pub fn get_tlv() -> usize { rayon_core::tlv::get() } @@ -1699,7 +1704,7 @@ pub mod tls { #[inline] fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R { let old = get_tlv(); - let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old))); + let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old))); TLV.with(|tlv| tlv.set(value)); f() } @@ -1720,50 +1725,6 @@ pub mod tls { set_tlv(context as *const _ as usize, || f(&context)) } - /// Enters `GlobalCtxt` by setting up librustc_ast callbacks and - /// creating a initial `TyCtxt` and `ImplicitCtxt`. - /// This happens once per rustc session and `TyCtxt`s only exists - /// inside the `f` function. - pub fn enter_global<'tcx, F, R>(gcx: &'tcx GlobalCtxt<'tcx>, f: F) -> R - where - F: FnOnce(TyCtxt<'tcx>) -> R, - { - // Update `GCX_PTR` to indicate there's a `GlobalCtxt` available. - GCX_PTR.with(|lock| { - *lock.lock() = gcx as *const _ as usize; - }); - // Set `GCX_PTR` back to 0 when we exit. - let _on_drop = OnDrop(move || { - GCX_PTR.with(|lock| *lock.lock() = 0); - }); - - let tcx = TyCtxt { gcx }; - let icx = - ImplicitCtxt { tcx, query: None, diagnostics: None, layout_depth: 0, task_deps: None }; - enter_context(&icx, |_| f(tcx)) - } - - scoped_thread_local! { - /// Stores a pointer to the `GlobalCtxt` if one is available. - /// This is used to access the `GlobalCtxt` in the deadlock handler given to Rayon. - pub static GCX_PTR: Lock<usize> - } - - /// Creates a `TyCtxt` and `ImplicitCtxt` based on the `GCX_PTR` thread local. - /// This is used in the deadlock handler. - pub unsafe fn with_global<F, R>(f: F) -> R - where - F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R, - { - let gcx = GCX_PTR.with(|lock| *lock.lock()); - assert!(gcx != 0); - let gcx = &*(gcx as *const GlobalCtxt<'_>); - let tcx = TyCtxt { gcx }; - let icx = - ImplicitCtxt { query: None, diagnostics: None, tcx, layout_depth: 0, task_deps: None }; - enter_context(&icx, |_| f(tcx)) - } - /// Allows access to the current `ImplicitCtxt` in a closure if one is available. #[inline] pub fn with_context_opt<F, R>(f: F) -> R diff --git a/src/librustc_middle/ty/query/job.rs b/src/librustc_middle/ty/query/job.rs index 60b93b3d44d..1811d945a1d 100644 --- a/src/librustc_middle/ty/query/job.rs +++ b/src/librustc_middle/ty/query/job.rs @@ -10,18 +10,20 @@ use std::thread; pub unsafe fn handle_deadlock() { let registry = rayon_core::Registry::current(); - let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| gcx_ptr as *const _); - let gcx_ptr = &*gcx_ptr; + let context = tls::get_tlv(); + assert!(context != 0); + rustc_data_structures::sync::assert_sync::<tls::ImplicitCtxt<'_, '_>>(); + let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>); let span_session_globals = rustc_span::SESSION_GLOBALS.with(|ssg| ssg as *const _); let span_session_globals = &*span_session_globals; let ast_session_globals = rustc_ast::attr::SESSION_GLOBALS.with(|asg| asg as *const _); let ast_session_globals = &*ast_session_globals; thread::spawn(move || { - tls::GCX_PTR.set(gcx_ptr, || { + tls::enter_context(icx, |_| { rustc_ast::attr::SESSION_GLOBALS.set(ast_session_globals, || { rustc_span::SESSION_GLOBALS - .set(span_session_globals, || tls::with_global(|tcx| deadlock(tcx, ®istry))) + .set(span_session_globals, || tls::with(|tcx| deadlock(tcx, ®istry))) }); }) }); diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs index 2f7a9aee536..b39c0b5190a 100644 --- a/src/librustc_middle/ty/query/mod.rs +++ b/src/librustc_middle/ty/query/mod.rs @@ -1,10 +1,10 @@ -use crate::dep_graph::{self, DepNode, DepNodeParams}; +use crate::dep_graph::{self, DepKind, DepNode, DepNodeParams}; use crate::hir::exports::Export; use crate::hir::map; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintLevelMap; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; -use crate::middle::cstore::{CrateSource, DepKind}; +use crate::middle::cstore::{CrateDepKind, CrateSource}; use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use crate::middle::lib_features::LibFeatures; @@ -161,7 +161,7 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool // hit the cache instead of having to go through `force_from_dep_node`. // This assertion makes sure, we actually keep applying the solution above. debug_assert!( - dep_node.kind != crate::dep_graph::DepKind::codegen_unit, + dep_node.kind != DepKind::codegen_unit, "calling force_from_dep_node() on DepKind::codegen_unit" ); @@ -172,14 +172,14 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool rustc_dep_node_force!([dep_node, tcx] // These are inputs that are expected to be pre-allocated and that // should therefore always be red or green already. - crate::dep_graph::DepKind::CrateMetadata | + DepKind::CrateMetadata | // These are anonymous nodes. - crate::dep_graph::DepKind::TraitSelect | + DepKind::TraitSelect | // We don't have enough information to reconstruct the query key of // these. - crate::dep_graph::DepKind::CompileCodegenUnit => { + DepKind::CompileCodegenUnit => { bug!("force_from_dep_node: encountered {:?}", dep_node) } ); diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index 21b8d7101a3..dfa9e38a466 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -282,6 +282,7 @@ CloneTypeFoldableAndLiftImpls! { ::rustc_hir::def::Res, ::rustc_hir::def_id::DefId, ::rustc_hir::def_id::LocalDefId, + ::rustc_hir::HirId, ::rustc_hir::LlvmInlineAsmInner, ::rustc_hir::MatchSource, ::rustc_hir::Mutability, @@ -298,6 +299,7 @@ CloneTypeFoldableAndLiftImpls! { // really meant to be folded. In general, we can only fold a fully // general `Region`. crate::ty::BoundRegion, + crate::ty::AssocItem, crate::ty::Placeholder<crate::ty::BoundRegion>, crate::ty::ClosureKind, crate::ty::FreeRegion, diff --git a/src/librustc_middle/ty/subst.rs b/src/librustc_middle/ty/subst.rs index e9fd67a748c..866b529f35e 100644 --- a/src/librustc_middle/ty/subst.rs +++ b/src/librustc_middle/ty/subst.rs @@ -425,8 +425,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T { substs: &[GenericArg<'tcx>], span: Option<Span>, ) -> T { - let mut folder = - SubstFolder { tcx, substs, span, root_ty: None, ty_stack_depth: 0, binders_passed: 0 }; + let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 }; (*self).fold_with(&mut folder) } } @@ -441,12 +440,6 @@ struct SubstFolder<'a, 'tcx> { /// The location for which the substitution is performed, if available. span: Option<Span>, - /// The root type that is being substituted, if available. - root_ty: Option<Ty<'tcx>>, - - /// Depth of type stack - ty_stack_depth: usize, - /// Number of region binders we have passed through while doing the substitution binders_passed: u32, } @@ -478,9 +471,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { let span = self.span.unwrap_or(DUMMY_SP); let msg = format!( "Region parameter out of range \ - when substituting in region {} (root type={:?}) \ - (index={})", - data.name, self.root_ty, data.index + when substituting in region {} (index={})", + data.name, data.index ); span_bug!(span, "{}", msg); } @@ -495,25 +487,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { return t; } - // track the root type we were asked to substitute - let depth = self.ty_stack_depth; - if depth == 0 { - self.root_ty = Some(t); - } - self.ty_stack_depth += 1; - - let t1 = match t.kind { + match t.kind { ty::Param(p) => self.ty_for_param(p, t), _ => t.super_fold_with(self), - }; - - assert_eq!(depth + 1, self.ty_stack_depth); - self.ty_stack_depth -= 1; - if depth == 0 { - self.root_ty = None; } - - t1 } fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { @@ -540,12 +517,11 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { span_bug!( span, "expected type for `{:?}` ({:?}/{}) but found {:?} \ - when substituting (root type={:?}) substs={:?}", + when substituting, substs={:?}", p, source_ty, p.index, kind, - self.root_ty, self.substs, ); } @@ -554,11 +530,10 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { span_bug!( span, "type parameter `{:?}` ({:?}/{}) out of range \ - when substituting (root type={:?}) substs={:?}", + when substituting, substs={:?}", p, source_ty, p.index, - self.root_ty, self.substs, ); } diff --git a/src/librustc_middle/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs index 8f125098ee6..f93cce3f4da 100644 --- a/src/librustc_middle/ty/trait_def.rs +++ b/src/librustc_middle/ty/trait_def.rs @@ -187,32 +187,38 @@ pub(super) fn all_local_trait_impls<'tcx>( pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls { let mut impls = TraitImpls::default(); - { - let mut add_impl = |impl_def_id: DefId| { - let impl_self_ty = tcx.type_of(impl_def_id); - if impl_def_id.is_local() && impl_self_ty.references_error() { - return; - } - - if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) { - impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id); - } else { - impls.blanket_impls.push(impl_def_id); - } - }; - - // Traits defined in the current crate can't have impls in upstream - // crates, so we don't bother querying the cstore. - if !trait_id.is_local() { - for &cnum in tcx.crates().iter() { - for &def_id in tcx.implementations_of_trait((cnum, trait_id)).iter() { - add_impl(def_id); + // Traits defined in the current crate can't have impls in upstream + // crates, so we don't bother querying the cstore. + if !trait_id.is_local() { + for &cnum in tcx.crates().iter() { + for &(impl_def_id, simplified_self_ty) in + tcx.implementations_of_trait((cnum, trait_id)).iter() + { + if let Some(simplified_self_ty) = simplified_self_ty { + impls + .non_blanket_impls + .entry(simplified_self_ty) + .or_default() + .push(impl_def_id); + } else { + impls.blanket_impls.push(impl_def_id); } } } + } + + for &hir_id in tcx.hir().trait_impls(trait_id) { + let impl_def_id = tcx.hir().local_def_id(hir_id).to_def_id(); + + let impl_self_ty = tcx.type_of(impl_def_id); + if impl_self_ty.references_error() { + continue; + } - for &hir_id in tcx.hir().trait_impls(trait_id) { - add_impl(tcx.hir().local_def_id(hir_id).to_def_id()); + if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) { + impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id); + } else { + impls.blanket_impls.push(impl_def_id); } } diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index db78fa535cf..07221082048 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -585,7 +585,7 @@ struct OpaqueTypeExpander<'tcx> { found_recursion: bool, /// Whether or not to check for recursive opaque types. /// This is `true` when we're explicitly checking for opaque type - /// recursion, and 'false' otherwise to avoid unecessary work. + /// recursion, and 'false' otherwise to avoid unnecessary work. check_recursion: bool, tcx: TyCtxt<'tcx>, } diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs index 003c40f290b..2113d40a594 100644 --- a/src/librustc_mir/dataflow/framework/engine.rs +++ b/src/librustc_mir/dataflow/framework/engine.rs @@ -339,7 +339,7 @@ impl RustcMirAttrs { .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter())); for attr in rustc_mir_attrs { - let attr_result = if attr.check_name(sym::borrowck_graphviz_postflow) { + let attr_result = if attr.has_name(sym::borrowck_graphviz_postflow) { Self::set_field(&mut ret.basename_and_suffix, tcx, &attr, |s| { let path = PathBuf::from(s.to_string()); match path.file_name() { @@ -350,7 +350,7 @@ impl RustcMirAttrs { } } }) - } else if attr.check_name(sym::borrowck_graphviz_format) { + } else if attr.has_name(sym::borrowck_graphviz_format) { Self::set_field(&mut ret.formatter, tcx, &attr, |s| match s { sym::gen_kill | sym::two_phase => Ok(s), _ => { diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index ae1328dbd12..8a9edb23a10 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -34,7 +34,7 @@ pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Opti let items = attr.meta_item_list(); for item in items.iter().flat_map(|l| l.iter()) { match item.meta_item() { - Some(mi) if mi.check_name(name) => return Some(mi.clone()), + Some(mi) if mi.has_name(name) => return Some(mi.clone()), _ => continue, } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index a9e6e324eb2..7dfa913fd08 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -952,7 +952,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if compressed.no_bytes_init() { // Fast path: If all bytes are `uninit` then there is nothing to copy. The target range - // is marked as unititialized but we otherwise omit changing the byte representation which may + // is marked as uninitialized but we otherwise omit changing the byte representation which may // be arbitrary for uninitialized bytes. // This also avoids writing to the target bytes so that the backing allocation is never // touched if the bytes stay uninitialized for the whole interpreter execution. On contemporary diff --git a/src/librustc_mir/interpret/util.rs b/src/librustc_mir/interpret/util.rs index c0eac8a9305..57c5fc59cc0 100644 --- a/src/librustc_mir/interpret/util.rs +++ b/src/librustc_mir/interpret/util.rs @@ -47,14 +47,26 @@ where unused_params.contains(index).map(|unused| !unused).unwrap_or(true); // Only recurse when generic parameters in fns, closures and generators // are used and require substitution. - if is_used && subst.needs_subst() { + match (is_used, subst.needs_subst()) { // Just in case there are closures or generators within this subst, // recurse. - if subst.super_visit_with(self) { + (true, true) if subst.super_visit_with(self) => { // Only return when we find a parameter so the remaining substs // are not skipped. return true; } + // Confirm that polymorphization replaced the parameter with + // `ty::Param`/`ty::ConstKind::Param`. + (false, true) if cfg!(debug_assertions) => match subst.unpack() { + ty::subst::GenericArgKind::Type(ty) => { + assert!(matches!(ty.kind, ty::Param(_))) + } + ty::subst::GenericArgKind::Const(ct) => { + assert!(matches!(ct.val, ty::ConstKind::Param(_))) + } + ty::subst::GenericArgKind::Lifetime(..) => (), + }, + _ => {} } } false diff --git a/src/librustc_mir/monomorphize/polymorphize.rs b/src/librustc_mir/monomorphize/polymorphize.rs index 562f512c5da..8fc1458f592 100644 --- a/src/librustc_mir/monomorphize/polymorphize.rs +++ b/src/librustc_mir/monomorphize/polymorphize.rs @@ -28,7 +28,7 @@ pub fn provide(providers: &mut Providers) { /// Determine which generic parameters are used by the function/method/closure represented by /// `def_id`. Returns a bitset where bits representing unused parameters are set (`is_empty` /// indicates all parameters are used). -fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> { +fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> { debug!("unused_generic_params({:?})", def_id); if !tcx.sess.opts.debugging_opts.polymorphize { @@ -36,6 +36,13 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> { return FiniteBitSet::new_empty(); } + // Polymorphization results are stored in cross-crate metadata only when there are unused + // parameters, so assume that non-local items must have only used parameters (else this query + // would not be invoked, and the cross-crate metadata used instead). + if !def_id.is_local() { + return FiniteBitSet::new_empty(); + } + let generics = tcx.generics_of(def_id); debug!("unused_generic_params: generics={:?}", generics); @@ -53,7 +60,7 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> { // Create a bitset with N rightmost ones for each parameter. let generics_count: u32 = generics.count().try_into().expect("more generic parameters than can fit into a `u32`"); - let mut unused_parameters = FiniteBitSet::<u64>::new_empty(); + let mut unused_parameters = FiniteBitSet::<u32>::new_empty(); unused_parameters.set_range(0..generics_count); debug!("unused_generic_params: (start) unused_parameters={:?}", unused_parameters); mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters); @@ -84,7 +91,7 @@ fn mark_used_by_default_parameters<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, generics: &'tcx ty::Generics, - unused_parameters: &mut FiniteBitSet<u64>, + unused_parameters: &mut FiniteBitSet<u32>, ) { if !tcx.is_trait(def_id) && (tcx.is_closure(def_id) || tcx.type_of(def_id).is_generator()) { for param in &generics.params { @@ -110,11 +117,11 @@ fn mark_used_by_default_parameters<'tcx>( fn mark_used_by_predicates<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, - unused_parameters: &mut FiniteBitSet<u64>, + unused_parameters: &mut FiniteBitSet<u32>, ) { let def_id = tcx.closure_base_def_id(def_id); - let is_self_ty_used = |unused_parameters: &mut FiniteBitSet<u64>, self_ty: Ty<'tcx>| { + let is_self_ty_used = |unused_parameters: &mut FiniteBitSet<u32>, self_ty: Ty<'tcx>| { debug!("unused_generic_params: self_ty={:?}", self_ty); if let ty::Param(param) = self_ty.kind { !unused_parameters.contains(param.index).unwrap_or(false) @@ -123,7 +130,7 @@ fn mark_used_by_predicates<'tcx>( } }; - let mark_ty = |unused_parameters: &mut FiniteBitSet<u64>, ty: Ty<'tcx>| { + let mark_ty = |unused_parameters: &mut FiniteBitSet<u32>, ty: Ty<'tcx>| { let mut vis = UsedGenericParametersVisitor { tcx, def_id, unused_parameters }; ty.visit_with(&mut vis); }; @@ -159,7 +166,7 @@ fn emit_unused_generic_params_error<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, generics: &'tcx ty::Generics, - unused_parameters: &FiniteBitSet<u64>, + unused_parameters: &FiniteBitSet<u32>, ) { debug!("emit_unused_generic_params_error: def_id={:?}", def_id); let base_def_id = tcx.closure_base_def_id(def_id); @@ -195,7 +202,7 @@ fn emit_unused_generic_params_error<'tcx>( struct UsedGenericParametersVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, def_id: DefId, - unused_parameters: &'a mut FiniteBitSet<u64>, + unused_parameters: &'a mut FiniteBitSet<u32>, } impl<'a, 'tcx> Visitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> { diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/src/librustc_mir/transform/instrument_coverage.rs index fe63a67fdbb..5b2954dd5b0 100644 --- a/src/librustc_mir/transform/instrument_coverage.rs +++ b/src/librustc_mir/transform/instrument_coverage.rs @@ -5,18 +5,19 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::lang_items; use rustc_middle::hir; use rustc_middle::ich::StableHashingContext; +use rustc_middle::mir; use rustc_middle::mir::coverage::*; use rustc_middle::mir::interpret::Scalar; +use rustc_middle::mir::traversal; use rustc_middle::mir::{ - self, traversal, BasicBlock, BasicBlockData, CoverageInfo, Operand, Place, SourceInfo, - SourceScope, StatementKind, Terminator, TerminatorKind, + BasicBlock, BasicBlockData, CoverageInfo, Operand, Place, SourceInfo, SourceScope, + StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::FnDef; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{FnDef, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_span::{Pos, Span}; +use rustc_span::{FileName, Pos, RealFileName, Span}; /// Inserts call to count_code_region() as a placeholder to be replaced during code generation with /// the intrinsic llvm.instrprof.increment. @@ -112,6 +113,7 @@ enum Op { struct InjectedCall<'tcx> { func: Operand<'tcx>, args: Vec<Operand<'tcx>>, + span: Span, inject_at: Span, } @@ -179,12 +181,11 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let _ignore = mir_body; let id = self.next_counter(); let function_source_hash = self.function_source_hash(); - let code_region = body_span; let scope = rustc_middle::mir::OUTERMOST_SOURCE_SCOPE; let is_cleanup = false; let next_block = rustc_middle::mir::START_BLOCK; self.inject_call( - self.make_counter(id, function_source_hash, code_region), + self.make_counter(id, function_source_hash, body_span), scope, is_cleanup, next_block, @@ -201,14 +202,13 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let op = if add { Op::Add } else { Op::Subtract }; let rhs = 2; - let code_region = body_span; let scope = rustc_middle::mir::OUTERMOST_SOURCE_SCOPE; let is_cleanup = false; let next_block = rustc_middle::mir::START_BLOCK; let id = self.next_expression(); self.inject_call( - self.make_expression(id, code_region, lhs, op, rhs), + self.make_expression(id, body_span, lhs, op, rhs), scope, is_cleanup, next_block, @@ -216,13 +216,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } } - fn make_counter( - &self, - id: u32, - function_source_hash: u64, - code_region: Span, - ) -> InjectedCall<'tcx> { - let inject_at = code_region.shrink_to_lo(); + fn make_counter(&self, id: u32, function_source_hash: u64, span: Span) -> InjectedCall<'tcx> { + let inject_at = span.shrink_to_lo(); let func = function_handle( self.tcx, @@ -239,24 +234,18 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { debug_assert_eq!(COUNTER_ID, args.len()); args.push(self.const_u32(id, inject_at)); - debug_assert_eq!(START_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.lo().to_u32(), inject_at)); - - debug_assert_eq!(END_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.hi().to_u32(), inject_at)); - - InjectedCall { func, args, inject_at } + InjectedCall { func, args, span, inject_at } } fn make_expression( &self, id: u32, - code_region: Span, + span: Span, lhs: u32, op: Op, rhs: u32, ) -> InjectedCall<'tcx> { - let inject_at = code_region.shrink_to_lo(); + let inject_at = span.shrink_to_lo(); let func = function_handle( self.tcx, @@ -282,13 +271,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { debug_assert_eq!(RIGHT_ID, args.len()); args.push(self.const_u32(rhs, inject_at)); - debug_assert_eq!(START_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.lo().to_u32(), inject_at)); - - debug_assert_eq!(END_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.hi().to_u32(), inject_at)); - - InjectedCall { func, args, inject_at } + InjectedCall { func, args, span, inject_at } } fn inject_call( @@ -298,7 +281,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { is_cleanup: bool, next_block: BasicBlock, ) { - let InjectedCall { func, args, inject_at } = call; + let InjectedCall { func, mut args, span, inject_at } = call; debug!( " injecting {}call to {:?}({:?}) at: {:?}, scope: {:?}", if is_cleanup { "cleanup " } else { "" }, @@ -310,6 +293,14 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let mut patch = MirPatch::new(self.mir_body); + let (file_name, start_line, start_col, end_line, end_col) = self.code_region(&span); + + args.push(self.const_str(&file_name, inject_at)); + args.push(self.const_u32(start_line, inject_at)); + args.push(self.const_u32(start_col, inject_at)); + args.push(self.const_u32(end_line, inject_at)); + args.push(self.const_u32(end_col, inject_at)); + let temp = patch.new_temp(self.tcx.mk_unit(), inject_at); let new_block = patch.new_block(placeholder_block(inject_at, scope, is_cleanup)); patch.patch_terminator( @@ -335,6 +326,43 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { self.mir_body.basic_blocks_mut().swap(next_block, new_block); } + /// Convert the Span into its file name, start line and column, and end line and column + fn code_region(&self, span: &Span) -> (String, u32, u32, u32, u32) { + let source_map = self.tcx.sess.source_map(); + let start = source_map.lookup_char_pos(span.lo()); + let end = if span.hi() == span.lo() { + start.clone() + } else { + let end = source_map.lookup_char_pos(span.hi()); + debug_assert_eq!( + start.file.name, + end.file.name, + "Region start ({:?} -> {:?}) and end ({:?} -> {:?}) don't come from the same source file!", + span.lo(), + start, + span.hi(), + end + ); + end + }; + match &start.file.name { + FileName::Real(RealFileName::Named(path)) => ( + path.to_string_lossy().to_string(), + start.line as u32, + start.col.to_u32() + 1, + end.line as u32, + end.col.to_u32() + 1, + ), + _ => { + bug!("start.file.name should be a RealFileName, but it was: {:?}", start.file.name) + } + } + } + + fn const_str(&self, value: &str, span: Span) -> Operand<'tcx> { + Operand::const_from_str(self.tcx, value, span) + } + fn const_u32(&self, value: u32, span: Span) -> Operand<'tcx> { Operand::const_from_scalar(self.tcx, self.tcx.types.u32, Scalar::from_u32(value), span) } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index f6847348063..f1a7338d11f 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -524,7 +524,7 @@ impl<'tcx> Validator<'_, 'tcx> { // The `is_empty` predicate is introduced to exclude the case // where the projection operations are [ .field, * ]. // The reason is because promotion will be illegal if field - // accesses preceed the dereferencing. + // accesses precede the dereferencing. // Discussion can be found at // https://github.com/rust-lang/rust/pull/74945#discussion_r463063247 // There may be opportunity for generalization, but this needs to be diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index de7d7f27186..34fa840408f 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -193,7 +193,15 @@ fn check_rvalue( _, ) => Err((span, "function pointer casts are not allowed in const fn".into())), Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => { - let pointee_ty = cast_ty.builtin_deref(true).unwrap().ty; + let pointee_ty = if let Some(deref_ty) = cast_ty.builtin_deref(true) { + deref_ty.ty + } else { + // We cannot allow this for now. + return Err(( + span, + "unsizing casts are only allowed for references right now".into(), + )); + }; let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id)); if let ty::Slice(_) | ty::Str = unsized_ty.kind { check_operand(tcx, op, span, def_id, body)?; diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 9288d6e16f5..d8995e92abf 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -142,8 +142,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } self.basic_blocks[bb].terminator = Some(terminator); - - changed |= inner_changed; } if !changed { @@ -212,6 +210,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } => target, _ => unreachable!(), }; + *changed |= *target != last; *target = last; debug!("collapsing goto chain from {:?} to {:?}", current, target); @@ -223,7 +222,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.pred_count[*target] += 1; self.pred_count[current] -= 1; } - *changed = true; self.basic_blocks[current].terminator = Some(terminator); } } diff --git a/src/librustc_mir_build/thir/pattern/mod.rs b/src/librustc_mir_build/thir/pattern/mod.rs index bdefaadfdfe..daff10eb194 100644 --- a/src/librustc_mir_build/thir/pattern/mod.rs +++ b/src/librustc_mir_build/thir/pattern/mod.rs @@ -133,7 +133,7 @@ crate enum PatKind<'tcx> { var: hir::HirId, ty: Ty<'tcx>, subpattern: Option<Pat<'tcx>>, - /// Is this the leftmost occurance of the binding, i.e., is `var` the + /// Is this the leftmost occurrence of the binding, i.e., is `var` the /// `HirId` of this pattern? is_primary: bool, }, diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index f214ec020cb..25144bd610d 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -21,3 +21,4 @@ rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_ast = { path = "../librustc_ast" } unicode-normalization = "0.1.11" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index be86b4b7c77..3319ca44da4 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -7,14 +7,16 @@ #![feature(or_patterns)] use rustc_ast::ast; -use rustc_ast::token::{self, Nonterminal}; +use rustc_ast::token::{self, DelimToken, Nonterminal, Token}; use rustc_ast::tokenstream::{self, TokenStream, TokenTree}; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Diagnostic, FatalError, Level, PResult}; use rustc_session::parse::ParseSess; -use rustc_span::{FileName, SourceFile, Span}; +use rustc_span::{symbol::kw, FileName, SourceFile, Span, DUMMY_SP}; +use smallvec::SmallVec; +use std::mem; use std::path::Path; use std::str; @@ -306,7 +308,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke // modifications, including adding/removing typically non-semantic // tokens such as extra braces and commas, don't happen. if let Some(tokens) = tokens { - if tokens.probably_equal_for_proc_macro(&tokens_for_real) { + if tokenstream_probably_equal_for_proc_macro(&tokens, &tokens_for_real) { return tokens; } info!( @@ -319,6 +321,186 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke tokens_for_real } +// See comments in `Nonterminal::to_tokenstream` for why we care about +// *probably* equal here rather than actual equality +// +// This is otherwise the same as `eq_unspanned`, only recursing with a +// different method. +pub fn tokenstream_probably_equal_for_proc_macro(first: &TokenStream, other: &TokenStream) -> bool { + // When checking for `probably_eq`, we ignore certain tokens that aren't + // preserved in the AST. Because they are not preserved, the pretty + // printer arbitrarily adds or removes them when printing as token + // streams, making a comparison between a token stream generated from an + // AST and a token stream which was parsed into an AST more reliable. + fn semantic_tree(tree: &TokenTree) -> bool { + if let TokenTree::Token(token) = tree { + if let + // The pretty printer tends to add trailing commas to + // everything, and in particular, after struct fields. + | token::Comma + // The pretty printer emits `NoDelim` as whitespace. + | token::OpenDelim(DelimToken::NoDelim) + | token::CloseDelim(DelimToken::NoDelim) + // The pretty printer collapses many semicolons into one. + | token::Semi + // The pretty printer collapses whitespace arbitrarily and can + // introduce whitespace from `NoDelim`. + | token::Whitespace + // The pretty printer can turn `$crate` into `::crate_name` + | token::ModSep = token.kind { + return false; + } + } + true + } + + // When comparing two `TokenStream`s, we ignore the `IsJoint` information. + // + // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will + // use `Token.glue` on adjacent tokens with the proper `IsJoint`. + // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`) + // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent + // when determining if two `TokenStream`s are 'probably equal'. + // + // Therefore, we use `break_two_token_op` to convert all tokens + // to the 'unglued' form (if it exists). This ensures that two + // `TokenStream`s which differ only in how their tokens are glued + // will be considered 'probably equal', which allows us to keep spans. + // + // This is important when the original `TokenStream` contained + // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces + // will be omitted when we pretty-print, which can cause the original + // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`, + // leading to some tokens being 'glued' together in one stream but not + // the other. See #68489 for more details. + fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> { + // In almost all cases, we should have either zero or one levels + // of 'unglueing'. However, in some unusual cases, we may need + // to iterate breaking tokens mutliple times. For example: + // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]' + let mut token_trees: SmallVec<[_; 2]>; + if let TokenTree::Token(token) = &tree { + let mut out = SmallVec::<[_; 2]>::new(); + out.push(token.clone()); + // Iterate to fixpoint: + // * We start off with 'out' containing our initial token, and `temp` empty + // * If we are able to break any tokens in `out`, then `out` will have + // at least one more element than 'temp', so we will try to break tokens + // again. + // * If we cannot break any tokens in 'out', we are done + loop { + let mut temp = SmallVec::<[_; 2]>::new(); + let mut changed = false; + + for token in out.into_iter() { + if let Some((first, second)) = token.kind.break_two_token_op() { + temp.push(Token::new(first, DUMMY_SP)); + temp.push(Token::new(second, DUMMY_SP)); + changed = true; + } else { + temp.push(token); + } + } + out = temp; + if !changed { + break; + } + } + token_trees = out.into_iter().map(TokenTree::Token).collect(); + if token_trees.len() != 1 { + debug!("break_tokens: broke {:?} to {:?}", tree, token_trees); + } + } else { + token_trees = SmallVec::new(); + token_trees.push(tree); + } + token_trees.into_iter() + } + + let mut t1 = first.trees().filter(semantic_tree).flat_map(break_tokens); + let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens); + for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { + if !tokentree_probably_equal_for_proc_macro(&t1, &t2) { + return false; + } + } + t1.next().is_none() && t2.next().is_none() +} + +// See comments in `Nonterminal::to_tokenstream` for why we care about +// *probably* equal here rather than actual equality +// +// This is otherwise the same as `eq_unspanned`, only recursing with a +// different method. +fn tokentree_probably_equal_for_proc_macro(first: &TokenTree, other: &TokenTree) -> bool { + match (first, other) { + (TokenTree::Token(token), TokenTree::Token(token2)) => { + token_probably_equal_for_proc_macro(token, token2) + } + (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => { + delim == delim2 && tokenstream_probably_equal_for_proc_macro(&tts, &tts2) + } + _ => false, + } +} + +// See comments in `Nonterminal::to_tokenstream` for why we care about +// *probably* equal here rather than actual equality +fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool { + if mem::discriminant(&first.kind) != mem::discriminant(&other.kind) { + return false; + } + use rustc_ast::token::TokenKind::*; + match (&first.kind, &other.kind) { + (&Eq, &Eq) + | (&Lt, &Lt) + | (&Le, &Le) + | (&EqEq, &EqEq) + | (&Ne, &Ne) + | (&Ge, &Ge) + | (&Gt, &Gt) + | (&AndAnd, &AndAnd) + | (&OrOr, &OrOr) + | (&Not, &Not) + | (&Tilde, &Tilde) + | (&At, &At) + | (&Dot, &Dot) + | (&DotDot, &DotDot) + | (&DotDotDot, &DotDotDot) + | (&DotDotEq, &DotDotEq) + | (&Comma, &Comma) + | (&Semi, &Semi) + | (&Colon, &Colon) + | (&ModSep, &ModSep) + | (&RArrow, &RArrow) + | (&LArrow, &LArrow) + | (&FatArrow, &FatArrow) + | (&Pound, &Pound) + | (&Dollar, &Dollar) + | (&Question, &Question) + | (&Whitespace, &Whitespace) + | (&Comment, &Comment) + | (&Eof, &Eof) => true, + + (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, + + (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b, + + (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b, + + (&Literal(a), &Literal(b)) => a == b, + + (&Lifetime(a), &Lifetime(b)) => a == b, + (&Ident(a, b), &Ident(c, d)) => { + b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate) + } + + (&Interpolated(..), &Interpolated(..)) => false, + + _ => panic!("forgot to add a token?"), + } +} + fn prepend_attrs( sess: &ParseSess, attrs: &[ast::Attribute], diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 609a0c961e9..5e9411327ca 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -333,6 +333,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable }, ); + self.sess.type_ascription_path_suggestions.borrow_mut().insert(sp); } else if op_pos.line != next_pos.line && maybe_expected_semicolon { err.span_suggestion( sp, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index d06b172bc14..3aec300d86d 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1450,7 +1450,7 @@ impl<'a> Parser<'a> { /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). /// Keep this in sync with `Token::can_begin_literal_maybe_minus`. - pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { + pub(super) fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { maybe_whole_expr!(self); let lo = self.token.span; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 72866468b65..2509a979221 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -1,16 +1,17 @@ pub mod attr; +mod diagnostics; mod expr; +mod generics; mod item; +mod nonterminal; mod pat; mod path; -mod ty; -pub use path::PathStyle; -mod diagnostics; -mod generics; mod stmt; -use diagnostics::Error; +mod ty; use crate::lexer::UnmatchedBrace; +use diagnostics::Error; +pub use path::PathStyle; use log::debug; use rustc_ast::ast::DUMMY_NODE_ID; @@ -958,7 +959,7 @@ impl<'a> Parser<'a> { } /// Parses a single token tree from the input. - pub fn parse_token_tree(&mut self) -> TokenTree { + pub(crate) fn parse_token_tree(&mut self) -> TokenTree { match self.token.kind { token::OpenDelim(..) => { let frame = mem::replace( @@ -1017,7 +1018,7 @@ impl<'a> Parser<'a> { /// If the following element can't be a tuple (i.e., it's a function definition), then /// it's not a tuple struct field), and the contents within the parentheses isn't valid, /// so emit a proper diagnostic. - pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { + pub(crate) fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { maybe_whole!(self, NtVis, |x| x); self.expected_tokens.push(TokenType::Keyword(kw::Crate)); diff --git a/src/librustc_parse/parser/nonterminal.rs b/src/librustc_parse/parser/nonterminal.rs new file mode 100644 index 00000000000..12139771bbf --- /dev/null +++ b/src/librustc_parse/parser/nonterminal.rs @@ -0,0 +1,163 @@ +use rustc_ast::ptr::P; +use rustc_ast::token::{self, Nonterminal, NonterminalKind, Token}; +use rustc_ast_pretty::pprust; +use rustc_errors::PResult; +use rustc_span::symbol::{kw, Ident}; + +use crate::parser::{FollowedByType, Parser, PathStyle}; + +impl<'a> Parser<'a> { + /// Checks whether a non-terminal may begin with a particular token. + /// + /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that + /// token. Be conservative (return true) if not sure. + pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool { + /// Checks whether the non-terminal may contain a single (non-keyword) identifier. + fn may_be_ident(nt: &token::Nonterminal) -> bool { + match *nt { + token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => { + false + } + _ => true, + } + } + + match kind { + NonterminalKind::Expr => { + token.can_begin_expr() + // This exception is here for backwards compatibility. + && !token.is_keyword(kw::Let) + } + NonterminalKind::Ty => token.can_begin_type(), + NonterminalKind::Ident => get_macro_ident(token).is_some(), + NonterminalKind::Literal => token.can_begin_literal_maybe_minus(), + NonterminalKind::Vis => match token.kind { + // The follow-set of :vis + "priv" keyword + interpolated + token::Comma | token::Ident(..) | token::Interpolated(..) => true, + _ => token.can_begin_type(), + }, + NonterminalKind::Block => match token.kind { + token::OpenDelim(token::Brace) => true, + token::Interpolated(ref nt) => match **nt { + token::NtItem(_) + | token::NtPat(_) + | token::NtTy(_) + | token::NtIdent(..) + | token::NtMeta(_) + | token::NtPath(_) + | token::NtVis(_) => false, // none of these may start with '{'. + _ => true, + }, + _ => false, + }, + NonterminalKind::Path | NonterminalKind::Meta => match token.kind { + token::ModSep | token::Ident(..) => true, + token::Interpolated(ref nt) => match **nt { + token::NtPath(_) | token::NtMeta(_) => true, + _ => may_be_ident(&nt), + }, + _ => false, + }, + NonterminalKind::Pat => match token.kind { + token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) + token::OpenDelim(token::Paren) | // tuple pattern + token::OpenDelim(token::Bracket) | // slice pattern + token::BinOp(token::And) | // reference + token::BinOp(token::Minus) | // negative literal + token::AndAnd | // double reference + token::Literal(..) | // literal + token::DotDot | // range pattern (future compat) + token::DotDotDot | // range pattern (future compat) + token::ModSep | // path + token::Lt | // path (UFCS constant) + token::BinOp(token::Shl) => true, // path (double UFCS) + token::Interpolated(ref nt) => may_be_ident(nt), + _ => false, + }, + NonterminalKind::Lifetime => match token.kind { + token::Lifetime(_) => true, + token::Interpolated(ref nt) => match **nt { + token::NtLifetime(_) | token::NtTT(_) => true, + _ => false, + }, + _ => false, + }, + NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => match token.kind + { + token::CloseDelim(_) => false, + _ => true, + }, + } + } + + pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, Nonterminal> { + // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`) + // needs to have them force-captured here. + // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, + // which requires having captured tokens available. Since we cannot determine + // in advance whether or not a proc-macro will be (transitively) invoked, + // we always capture tokens for any `Nonterminal` which needs them. + Ok(match kind { + NonterminalKind::Item => match self.collect_tokens(|this| this.parse_item())? { + (Some(mut item), tokens) => { + // If we captured tokens during parsing (due to outer attributes), + // use those. + if item.tokens.is_none() { + item.tokens = Some(tokens); + } + token::NtItem(item) + } + (None, _) => { + return Err(self.struct_span_err(self.token.span, "expected an item keyword")); + } + }, + NonterminalKind::Block => token::NtBlock(self.parse_block()?), + NonterminalKind::Stmt => match self.parse_stmt()? { + Some(s) => token::NtStmt(s), + None => return Err(self.struct_span_err(self.token.span, "expected a statement")), + }, + NonterminalKind::Pat => token::NtPat(self.parse_pat(None)?), + NonterminalKind::Expr => { + let (mut expr, tokens) = self.collect_tokens(|this| this.parse_expr())?; + // If we captured tokens during parsing (due to outer attributes), + // use those. + if expr.tokens.is_none() { + expr.tokens = Some(tokens); + } + token::NtExpr(expr) + } + NonterminalKind::Literal => token::NtLiteral(self.parse_literal_maybe_minus()?), + NonterminalKind::Ty => token::NtTy(self.parse_ty()?), + // this could be handled like a token, since it is one + NonterminalKind::Ident => { + if let Some((ident, is_raw)) = get_macro_ident(&self.token) { + self.bump(); + token::NtIdent(ident, is_raw) + } else { + let token_str = pprust::token_to_string(&self.token); + let msg = &format!("expected ident, found {}", &token_str); + return Err(self.struct_span_err(self.token.span, msg)); + } + } + NonterminalKind::Path => token::NtPath(self.parse_path(PathStyle::Type)?), + NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item()?)), + NonterminalKind::TT => token::NtTT(self.parse_token_tree()), + NonterminalKind::Vis => token::NtVis(self.parse_visibility(FollowedByType::Yes)?), + NonterminalKind::Lifetime => { + if self.check_lifetime() { + token::NtLifetime(self.expect_lifetime().ident) + } else { + let token_str = pprust::token_to_string(&self.token); + let msg = &format!("expected a lifetime, found `{}`", &token_str); + return Err(self.struct_span_err(self.token.span, msg)); + } + } + }) + } +} + +/// The token is an identifier, but not `_`. +/// We prohibit passing `_` to macros expecting `ident` for now. +fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> { + token.ident().filter(|(ident, _)| ident.name != kw::Underscore) +} diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 3dcefd36257..d4e44c54b12 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -125,7 +125,7 @@ impl<'a> Parser<'a> { /// `a::b::C::<D>` (with disambiguator) /// `Fn(Args)` (without disambiguator) /// `Fn::(Args)` (with disambiguator) - pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> { + pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> { maybe_whole!(self, NtPath, |path| { if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some()) { diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index d04920de47f..5c3a5e99873 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -21,7 +21,7 @@ use std::mem; impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. - pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> { + pub(super) fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> { Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| { e.emit(); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); @@ -247,7 +247,7 @@ impl<'a> Parser<'a> { } /// Parses a block. No inner attributes are allowed. - pub fn parse_block(&mut self) -> PResult<'a, P<Block>> { + pub(super) fn parse_block(&mut self) -> PResult<'a, P<Block>> { let (attrs, block) = self.parse_inner_attrs_and_block()?; if let [.., last] = &*attrs { self.error_on_forbidden_inner_attr(last.span, DEFAULT_INNER_ATTR_FORBIDDEN); diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index a6015504a32..cd66b917f23 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -610,13 +610,13 @@ impl<'a> Parser<'a> { } } - pub fn check_lifetime(&mut self) -> bool { + pub(super) fn check_lifetime(&mut self) -> bool { self.expected_tokens.push(TokenType::Lifetime); self.token.is_lifetime() } /// Parses a single lifetime `'a` or panics. - pub fn expect_lifetime(&mut self) -> Lifetime { + pub(super) fn expect_lifetime(&mut self) -> Lifetime { if let Some(ident) = self.token.lifetime() { self.bump(); Lifetime { ident, id: ast::DUMMY_NODE_ID } diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index 3e63a63d9d0..1ff47ee038d 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -222,7 +222,7 @@ impl CheckAttrVisitor<'tcx> { if let Some(mi) = attr.meta() { if let Some(list) = mi.meta_item_list() { for meta in list { - if meta.check_name(sym::alias) { + if meta.has_name(sym::alias) { if !meta.is_value_str() || meta .value_str() diff --git a/src/librustc_query_system/cache.rs b/src/librustc_query_system/cache.rs new file mode 100644 index 00000000000..be3d3607728 --- /dev/null +++ b/src/librustc_query_system/cache.rs @@ -0,0 +1,62 @@ +//! Cache for candidate selection. + +use crate::dep_graph::DepNodeIndex; +use crate::query::QueryContext; + +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::HashMapExt; +use rustc_data_structures::sync::Lock; + +use std::hash::Hash; + +#[derive(Clone)] +pub struct Cache<Key, Value> { + hashmap: Lock<FxHashMap<Key, WithDepNode<Value>>>, +} + +impl<Key, Value> Default for Cache<Key, Value> { + fn default() -> Self { + Self { hashmap: Default::default() } + } +} + +impl<Key, Value> Cache<Key, Value> { + /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` + pub fn clear(&self) { + *self.hashmap.borrow_mut() = Default::default(); + } +} + +impl<Key: Eq + Hash, Value: Clone> Cache<Key, Value> { + pub fn get<CTX: QueryContext>(&self, key: &Key, tcx: CTX) -> Option<Value> { + Some(self.hashmap.borrow().get(key)?.get(tcx)) + } + + pub fn insert(&self, key: Key, dep_node: DepNodeIndex, value: Value) { + self.hashmap.borrow_mut().insert(key, WithDepNode::new(dep_node, value)); + } + + pub fn insert_same(&self, key: Key, dep_node: DepNodeIndex, value: Value) + where + Value: Eq, + { + self.hashmap.borrow_mut().insert_same(key, WithDepNode::new(dep_node, value)); + } +} + +#[derive(Clone, Eq, PartialEq)] +pub struct WithDepNode<T> { + dep_node: DepNodeIndex, + cached_value: T, +} + +impl<T: Clone> WithDepNode<T> { + pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { + WithDepNode { dep_node, cached_value } + } + + pub fn get<CTX: QueryContext>(&self, tcx: CTX) -> T { + tcx.dep_graph().read_index(self.dep_node); + self.cached_value.clone() + } +} diff --git a/src/librustc_query_system/lib.rs b/src/librustc_query_system/lib.rs index b7615b25c4a..4bbba7befe9 100644 --- a/src/librustc_query_system/lib.rs +++ b/src/librustc_query_system/lib.rs @@ -11,5 +11,6 @@ extern crate log; #[macro_use] extern crate rustc_data_structures; +pub mod cache; pub mod dep_graph; pub mod query; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index bcd2c6c1f1c..44ff4209095 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1510,30 +1510,18 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { pat_src: PatternSource, bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>, ) { - let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _)); - // Visit all direct subpatterns of this pattern. pat.walk(&mut |pat| { debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind); match pat.kind { PatKind::Ident(bmode, ident, ref sub) => { - if is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some() { - // In tuple struct patterns ignore the invalid `ident @ ...`. - // It will be handled as an error by the AST lowering. - self.r - .session - .delay_span_bug(ident.span, "ident in tuple pattern is invalid"); - } else { - // First try to resolve the identifier as some existing entity, - // then fall back to a fresh binding. - let has_sub = sub.is_some(); - let res = self - .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) - .unwrap_or_else(|| { - self.fresh_binding(ident, pat.id, pat_src, bindings) - }); - self.r.record_partial_res(pat.id, PartialRes::new(res)); - } + // First try to resolve the identifier as some existing entity, + // then fall back to a fresh binding. + let has_sub = sub.is_some(); + let res = self + .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) + .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings)); + self.r.record_partial_res(pat.id, PartialRes::new(res)); } PatKind::TupleStruct(ref path, ..) => { self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct(pat.span)); @@ -2241,8 +2229,15 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.resolve_expr(argument, None); } } - ExprKind::Type(ref type_expr, _) => { - self.diagnostic_metadata.current_type_ascription.push(type_expr.span); + ExprKind::Type(ref type_expr, ref ty) => { + // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in + // type ascription. Here we are trying to retrieve the span of the colon token as + // well, but only if it's written without spaces `expr:Ty` and therefore confusable + // with `expr::Ty`, only in this case it will match the span from + // `type_ascription_path_suggestions`. + self.diagnostic_metadata + .current_type_ascription + .push(type_expr.span.between(ty.span)); visit::walk_expr(self, expr); self.diagnostic_metadata.current_type_ascription.pop(); } diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index c86b4141847..ec6dbb070df 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -17,7 +17,7 @@ use rustc_hir::PrimTy; use rustc_session::config::nightly_options; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use log::debug; @@ -223,13 +223,31 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) { let enum_candidates = self.r.lookup_import_candidates(ident, ns, &self.parent_scope, is_enum_variant); - let mut enum_candidates = enum_candidates - .iter() - .map(|suggestion| import_candidate_to_enum_paths(&suggestion)) - .collect::<Vec<_>>(); - enum_candidates.sort(); if !enum_candidates.is_empty() { + if let (PathSource::Type, Some(span)) = + (source, self.diagnostic_metadata.current_type_ascription.last()) + { + if self + .r + .session + .parse_sess + .type_ascription_path_suggestions + .borrow() + .contains(span) + { + // Already reported this issue on the lhs of the type ascription. + err.delay_as_bug(); + return (err, candidates); + } + } + + let mut enum_candidates = enum_candidates + .iter() + .map(|suggestion| import_candidate_to_enum_paths(&suggestion)) + .collect::<Vec<_>>(); + enum_candidates.sort(); + // Contextualize for E0412 "cannot find type", but don't belabor the point // (that it's a variant) for E0573 "expected type, found variant". let preamble = if res.is_none() { @@ -484,10 +502,21 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { match source { PathSource::Expr(Some( parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. }, - )) => { - path_sep(err, &parent); - } - PathSource::Expr(None) if followed_by_brace => { + )) if path_sep(err, &parent) => {} + PathSource::Expr( + None + | Some(Expr { + kind: + ExprKind::Path(..) + | ExprKind::Binary(..) + | ExprKind::Unary(..) + | ExprKind::If(..) + | ExprKind::While(..) + | ExprKind::ForLoop(..) + | ExprKind::Match(..), + .. + }), + ) if followed_by_brace => { if let Some(sp) = closing_brace { err.multipart_suggestion( "surround the struct literal with parentheses", @@ -508,11 +537,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { ); } } - PathSource::Expr( - None | Some(Expr { kind: ExprKind::Call(..) | ExprKind::Path(..), .. }), - ) - | PathSource::TupleStruct(_) - | PathSource::Pat => { + PathSource::Expr(_) | PathSource::TupleStruct(_) | PathSource::Pat => { let span = match &source { PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. @@ -593,6 +618,24 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct(_) | PathSource::Expr(..), ) => { + if self + .diagnostic_metadata + .current_type_ascription + .last() + .map(|sp| { + self.r + .session + .parse_sess + .type_ascription_path_suggestions + .borrow() + .contains(&sp) + }) + .unwrap_or(false) + { + err.delay_as_bug(); + // We already suggested changing `:` into `::` during parsing. + return false; + } if let Some(variants) = self.collect_enum_variants(def_id) { if !variants.is_empty() { let msg = if variants.len() == 1 { @@ -609,7 +652,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { ); } } else { - err.note("did you mean to use one of the enum's variants?"); + err.note("you might have meant to use one of the enum's variants"); } } (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => { @@ -829,77 +872,73 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { fn type_ascription_suggestion(&self, err: &mut DiagnosticBuilder<'_>, base_span: Span) { let sm = self.r.session.source_map(); let base_snippet = sm.span_to_snippet(base_span); - if let Some(sp) = self.diagnostic_metadata.current_type_ascription.last() { - let mut sp = *sp; - loop { - // Try to find the `:`; bail on first non-':' / non-whitespace. - sp = sm.next_point(sp); - if let Ok(snippet) = sm.span_to_snippet(sp.to(sm.next_point(sp))) { - let line_sp = sm.lookup_char_pos(sp.hi()).line; - let line_base_sp = sm.lookup_char_pos(base_span.lo()).line; - if snippet == ":" { - let mut show_label = true; - if line_sp != line_base_sp { - err.span_suggestion_short( - sp, - "did you mean to use `;` here instead?", - ";".to_string(), + if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() { + if let Ok(snippet) = sm.span_to_snippet(sp) { + let len = snippet.trim_end().len() as u32; + if snippet.trim() == ":" { + let colon_sp = + sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len)); + let mut show_label = true; + if sm.is_multiline(sp) { + err.span_suggestion_short( + colon_sp, + "maybe you meant to write `;` here", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + let after_colon_sp = + self.get_colon_suggestion_span(colon_sp.shrink_to_hi()); + if snippet.len() == 1 { + // `foo:bar` + err.span_suggestion( + colon_sp, + "maybe you meant to write a path separator here", + "::".to_string(), Applicability::MaybeIncorrect, ); - } else { - let colon_sp = self.get_colon_suggestion_span(sp); - let after_colon_sp = - self.get_colon_suggestion_span(colon_sp.shrink_to_hi()); - if !sm - .span_to_snippet(after_colon_sp) - .map(|s| s == " ") - .unwrap_or(false) + show_label = false; + if !self + .r + .session + .parse_sess + .type_ascription_path_suggestions + .borrow_mut() + .insert(colon_sp) { - err.span_suggestion( - colon_sp, - "maybe you meant to write a path separator here", - "::".to_string(), - Applicability::MaybeIncorrect, - ); - show_label = false; + err.delay_as_bug(); } - if let Ok(base_snippet) = base_snippet { - let mut sp = after_colon_sp; - for _ in 0..100 { - // Try to find an assignment - sp = sm.next_point(sp); - let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp))); - match snippet { - Ok(ref x) if x.as_str() == "=" => { - err.span_suggestion( - base_span, - "maybe you meant to write an assignment here", - format!("let {}", base_snippet), - Applicability::MaybeIncorrect, - ); - show_label = false; - break; - } - Ok(ref x) if x.as_str() == "\n" => break, - Err(_) => break, - Ok(_) => {} + } + if let Ok(base_snippet) = base_snippet { + let mut sp = after_colon_sp; + for _ in 0..100 { + // Try to find an assignment + sp = sm.next_point(sp); + let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp))); + match snippet { + Ok(ref x) if x.as_str() == "=" => { + err.span_suggestion( + base_span, + "maybe you meant to write an assignment here", + format!("let {}", base_snippet), + Applicability::MaybeIncorrect, + ); + show_label = false; + break; } + Ok(ref x) if x.as_str() == "\n" => break, + Err(_) => break, + Ok(_) => {} } } } - if show_label { - err.span_label( - base_span, - "expecting a type here because of type ascription", - ); - } - break; - } else if !snippet.trim().is_empty() { - debug!("tried to find type ascription `:` token, couldn't find it"); - break; } - } else { - break; + if show_label { + err.span_label( + base_span, + "expecting a type here because of type ascription", + ); + } } } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fee7cb4836e..ccc7e16ae4c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1020,7 +1020,7 @@ impl<'a> Resolver<'a> { } if let Some(depr) = &ext.deprecation { let path = pprust::path_to_string(&path); - let (message, lint) = stability::deprecation_message(depr, &path); + let (message, lint) = stability::deprecation_message(depr, "macro", &path); stability::early_report_deprecation( &mut self.lint_buffer, &message, diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 0751dbb027a..8e379a35100 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -832,10 +832,10 @@ impl<'tcx> SaveContext<'tcx> { if let Some(meta_list) = attr.meta_item_list() { meta_list .into_iter() - .filter(|it| it.check_name(sym::include)) + .filter(|it| it.has_name(sym::include)) .filter_map(|it| it.meta_item_list().map(|l| l.to_owned())) .flat_map(|it| it) - .filter(|meta| meta.check_name(sym::contents)) + .filter(|meta| meta.has_name(sym::contents)) .filter_map(|meta| meta.value_str()) .for_each(|val| { result.push_str(&val.as_str()); diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 620a04b45b0..9fcdd46539c 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1717,7 +1717,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } // `-Z instrument-coverage` implies: - // * `-Z symbol-mangling-version=v0` - to ensure consistent and reversable name mangling. + // * `-Z symbol-mangling-version=v0` - to ensure consistent and reversible name mangling. // Note, LLVM coverage tools can analyze coverage over multiple runs, including some // changes to source code; so mangled names must be consistent across compilations. // * `-C link-dead-code` - so unexecuted code is still counted as zero, rather than be diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index b428315b3cd..9cdb7e966fe 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -63,7 +63,7 @@ impl GatedSpans { #[derive(Default)] pub struct SymbolGallery { - /// All symbols occurred and their first occurrance span. + /// All symbols occurred and their first occurrence span. pub symbols: Lock<BTreeMap<Symbol, Span>>, } @@ -138,6 +138,8 @@ pub struct ParseSess { pub reached_eof: Lock<bool>, /// Environment variables accessed during the build and their values when they exist. pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>, + /// All the type ascriptions expressions that have had a suggestion for likely path typo. + pub type_ascription_path_suggestions: Lock<FxHashSet<Span>>, } impl ParseSess { @@ -164,6 +166,7 @@ impl ParseSess { symbol_gallery: SymbolGallery::default(), reached_eof: Lock::new(false), env_depinfo: Default::default(), + type_ascription_path_suggestions: Default::default(), } } diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index 13bc1751831..a03ac4e1fdb 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -891,7 +891,7 @@ impl UseSpecializedDecodable for ExpnId {} #[derive(Default)] pub struct HygieneEncodeContext { - /// All `SyntaxContexts` for which we have writen `SyntaxContextData` into crate metadata. + /// All `SyntaxContexts` for which we have written `SyntaxContextData` into crate metadata. /// This is `None` after we finish encoding `SyntaxContexts`, to ensure /// that we don't accidentally try to encode any more `SyntaxContexts` serialized_ctxts: Lock<FxHashSet<SyntaxContext>>, @@ -961,7 +961,7 @@ pub struct HygieneDecodeContext { // Maps serialized `SyntaxContext` ids to a `SyntaxContext` in the current // global `HygieneData`. When we deserialize a `SyntaxContext`, we need to create // a new id in the global `HygieneData`. This map tracks the ID we end up picking, - // so that multiple occurences of the same serialized id are decoded to the same + // so that multiple occurrences of the same serialized id are decoded to the same // `SyntaxContext` remapped_ctxts: Lock<Vec<Option<SyntaxContext>>>, // The same as `remapepd_ctxts`, but for `ExpnId`s diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs index 8423573b52d..62fc8f06183 100644 --- a/src/librustc_target/spec/wasm32_base.rs +++ b/src/librustc_target/spec/wasm32_base.rs @@ -10,13 +10,6 @@ pub fn options() -> TargetOptions { clang_args.push(format!("-Wl,{}", arg)); }; - // There have been reports in the wild (rustwasm/wasm-bindgen#119) of - // using threads causing weird hangs and bugs. Disable it entirely as - // this isn't yet the bottleneck of compilation at all anyway. - // - // FIXME: we should file an upstream issue with LLD about this - arg("--no-threads"); - // By default LLD only gives us one page of stack (64k) which is a // little small. Default to a larger stack closer to other PC platforms // (1MB) and users can always inject their own link-args to override this. diff --git a/src/librustc_trait_selection/traits/on_unimplemented.rs b/src/librustc_trait_selection/traits/on_unimplemented.rs index deb33708681..446d5a489df 100644 --- a/src/librustc_trait_selection/traits/on_unimplemented.rs +++ b/src/librustc_trait_selection/traits/on_unimplemented.rs @@ -95,27 +95,27 @@ impl<'tcx> OnUnimplementedDirective { }; for item in item_iter { - if item.check_name(sym::message) && message.is_none() { + if item.has_name(sym::message) && message.is_none() { if let Some(message_) = item.value_str() { message = parse_value(message_)?; continue; } - } else if item.check_name(sym::label) && label.is_none() { + } else if item.has_name(sym::label) && label.is_none() { if let Some(label_) = item.value_str() { label = parse_value(label_)?; continue; } - } else if item.check_name(sym::note) && note.is_none() { + } else if item.has_name(sym::note) && note.is_none() { if let Some(note_) = item.value_str() { note = parse_value(note_)?; continue; } - } else if item.check_name(sym::enclosing_scope) && enclosing_scope.is_none() { + } else if item.has_name(sym::enclosing_scope) && enclosing_scope.is_none() { if let Some(enclosing_scope_) = item.value_str() { enclosing_scope = parse_value(enclosing_scope_)?; continue; } - } else if item.check_name(sym::on) + } else if item.has_name(sym::on) && is_root && message.is_none() && label.is_none() diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index 4123f293826..75e11619924 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -51,6 +51,47 @@ pub use rustc_middle::traits::select::*; mod candidate_assembly; mod confirmation; +#[derive(Clone, Debug)] +pub enum IntercrateAmbiguityCause { + DownstreamCrate { trait_desc: String, self_desc: Option<String> }, + UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> }, + ReservationImpl { message: String }, +} + +impl IntercrateAmbiguityCause { + /// Emits notes when the overlap is caused by complex intercrate ambiguities. + /// See #23980 for details. + pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) { + err.note(&self.intercrate_ambiguity_hint()); + } + + pub fn intercrate_ambiguity_hint(&self) -> String { + match self { + &IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => { + let self_desc = if let &Some(ref ty) = self_desc { + format!(" for type `{}`", ty) + } else { + String::new() + }; + format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc) + } + &IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => { + let self_desc = if let &Some(ref ty) = self_desc { + format!(" for type `{}`", ty) + } else { + String::new() + }; + format!( + "upstream crates may add a new impl of trait `{}`{} \ + in future versions", + trait_desc, self_desc + ) + } + &IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(), + } + } +} + pub struct SelectionContext<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, @@ -833,17 +874,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Option<EvaluationResult> { let tcx = self.tcx(); if self.can_use_global_caches(param_env) { - let cache = tcx.evaluation_cache.hashmap.borrow(); - if let Some(cached) = cache.get(¶m_env.and(trait_ref)) { - return Some(cached.get(tcx)); + if let Some(res) = tcx.evaluation_cache.get(¶m_env.and(trait_ref), tcx) { + return Some(res); } } - self.infcx - .evaluation_cache - .hashmap - .borrow() - .get(¶m_env.and(trait_ref)) - .map(|v| v.get(tcx)) + self.infcx.evaluation_cache.get(¶m_env.and(trait_ref), tcx) } fn insert_evaluation_cache( @@ -869,21 +904,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME: Due to #50507 this overwrites the different values // This should be changed to use HashMapExt::insert_same // when that is fixed - self.tcx() - .evaluation_cache - .hashmap - .borrow_mut() - .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, result)); + self.tcx().evaluation_cache.insert(param_env.and(trait_ref), dep_node, result); return; } } debug!("insert_evaluation_cache(trait_ref={:?}, candidate={:?})", trait_ref, result,); - self.infcx - .evaluation_cache - .hashmap - .borrow_mut() - .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, result)); + self.infcx.evaluation_cache.insert(param_env.and(trait_ref), dep_node, result); } /// For various reasons, it's possible for a subobligation @@ -1180,17 +1207,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.tcx(); let trait_ref = &cache_fresh_trait_pred.skip_binder().trait_ref; if self.can_use_global_caches(param_env) { - let cache = tcx.selection_cache.hashmap.borrow(); - if let Some(cached) = cache.get(¶m_env.and(*trait_ref)) { - return Some(cached.get(tcx)); + if let Some(res) = tcx.selection_cache.get(¶m_env.and(*trait_ref), tcx) { + return Some(res); } } - self.infcx - .selection_cache - .hashmap - .borrow() - .get(¶m_env.and(*trait_ref)) - .map(|v| v.get(tcx)) + self.infcx.selection_cache.get(¶m_env.and(*trait_ref), tcx) } /// Determines whether can we safely cache the result @@ -1248,10 +1269,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_ref, candidate, ); // This may overwrite the cache with the same value. - tcx.selection_cache - .hashmap - .borrow_mut() - .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, candidate)); + tcx.selection_cache.insert(param_env.and(trait_ref), dep_node, candidate); return; } } @@ -1261,11 +1279,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { "insert_candidate_cache(trait_ref={:?}, candidate={:?}) local", trait_ref, candidate, ); - self.infcx - .selection_cache - .hashmap - .borrow_mut() - .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, candidate)); + self.infcx.selection_cache.insert(param_env.and(trait_ref), dep_node, candidate); } fn match_projection_obligation_against_definition_bounds( diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index c7e9b97e2db..db8cdfc5b20 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -456,7 +456,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // // Both of these trigger a special `CoerceUnsized`-related error (E0376) // - // We can take advantage of this fact to avoid performing unecessary work. + // We can take advantage of this fact to avoid performing unnecessary work. // If either `source` or `target` is a type variable, then any applicable impl // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`) // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index dc2172650e5..b3287caa0bf 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -379,17 +379,46 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), - sym::count_code_region => { - (0, vec![tcx.types.u64, tcx.types.u32, tcx.types.u32, tcx.types.u32], tcx.mk_unit()) - } + sym::count_code_region => ( + 0, + vec![ + tcx.types.u64, + tcx.types.u32, + tcx.mk_static_str(), + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + ], + tcx.mk_unit(), + ), sym::coverage_counter_add | sym::coverage_counter_subtract => ( 0, - vec![tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32], + vec![ + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + tcx.mk_static_str(), + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + ], tcx.mk_unit(), ), - sym::coverage_unreachable => (0, vec![tcx.types.u32, tcx.types.u32], tcx.mk_unit()), + sym::coverage_unreachable => ( + 0, + vec![ + tcx.mk_static_str(), + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + tcx.types.u32, + ], + tcx.mk_unit(), + ), other => { struct_span_err!( diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8715dacb324..97df065500a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2231,7 +2231,7 @@ fn from_target_feature( let rust_features = tcx.features(); for item in list { // Only `enable = ...` is accepted in the meta-item list. - if !item.check_name(sym::enable) { + if !item.has_name(sym::enable) { bad_item(item.span()); continue; } @@ -2483,11 +2483,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { no_sanitize_span = Some(attr.span); if let Some(list) = attr.meta_item_list() { for item in list.iter() { - if item.check_name(sym::address) { + if item.has_name(sym::address) { codegen_fn_attrs.no_sanitize |= SanitizerSet::ADDRESS; - } else if item.check_name(sym::memory) { + } else if item.has_name(sym::memory) { codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; - } else if item.check_name(sym::thread) { + } else if item.has_name(sym::thread) { codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD; } else { tcx.sess diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 9ba2545ba63..e203d51f612 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -100,7 +100,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util; use rustc_session::config::EntryFnType; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{symbol::sym, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::{ @@ -194,6 +194,23 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: LocalDefId) { .emit(); error = true; } + + for attr in it.attrs { + if attr.check_name(sym::track_caller) { + tcx.sess + .struct_span_err( + attr.span, + "`main` function is not allowed to be `#[track_caller]`", + ) + .span_label( + main_span, + "`main` function is not allowed to be `#[track_caller]`", + ) + .emit(); + error = true; + } + } + if error { return; } @@ -268,12 +285,29 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: LocalDefId) { tcx.sess, span, E0752, - "start is not allowed to be `async`" + "`start` is not allowed to be `async`" ) - .span_label(span, "start is not allowed to be `async`") + .span_label(span, "`start` is not allowed to be `async`") .emit(); error = true; } + + for attr in it.attrs { + if attr.check_name(sym::track_caller) { + tcx.sess + .struct_span_err( + attr.span, + "`start` is not allowed to be `#[track_caller]`", + ) + .span_label( + start_span, + "`start` is not allowed to be `#[track_caller]`", + ) + .emit(); + error = true; + } + } + if error { return; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5b048372624..2a090d6efa5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -113,7 +113,7 @@ impl Clean<ExternalCrate> for CrateNum { let mut prim = None; for attr in attrs.lists(sym::doc) { if let Some(v) = attr.value_str() { - if attr.check_name(sym::primitive) { + if attr.has_name(sym::primitive) { prim = PrimitiveType::from_symbol(v); if prim.is_some() { break; @@ -168,7 +168,7 @@ impl Clean<ExternalCrate> for CrateNum { let mut keyword = None; for attr in attrs.lists(sym::doc) { if let Some(v) = attr.value_str() { - if attr.check_name(sym::keyword) { + if attr.has_name(sym::keyword) { if v.is_doc_keyword() { keyword = Some(v.to_string()); break; @@ -2157,7 +2157,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> { fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { - a.check_name(sym::doc) + a.has_name(sym::doc) && match a.meta_item_list() { Some(l) => attr::list_contains_name(&l, sym::inline), None => false, @@ -2197,7 +2197,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> { // Don't inline doc(hidden) imports so they can be stripped at a later stage. let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| { - a.check_name(sym::doc) + a.has_name(sym::doc) && match a.meta_item_list() { Some(l) => { attr::list_contains_name(&l, sym::no_inline) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 89549eae2cb..1bea41b6585 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -210,7 +210,7 @@ impl Item { } pub fn is_non_exhaustive(&self) -> bool { - self.attrs.other_attrs.iter().any(|a| a.check_name(sym::non_exhaustive)) + self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) } /// Returns a documentation-level item type from the item. @@ -309,7 +309,7 @@ impl<'a> Iterator for ListAttributesIter<'a> { for attr in &mut self.attrs { if let Some(list) = attr.meta_item_list() { - if attr.check_name(self.name) { + if attr.has_name(self.name) { self.current_list = list.into_iter(); if let Some(nested) = self.current_list.next() { return Some(nested); @@ -345,7 +345,7 @@ pub trait NestedAttributesExt { impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I { fn has_word(self, word: Symbol) -> bool { - self.into_iter().any(|attr| attr.is_word() && attr.check_name(word)) + self.into_iter().any(|attr| attr.is_word() && attr.has_name(word)) } } @@ -425,7 +425,7 @@ impl Attributes { if let ast::MetaItemKind::List(ref nmis) = mi.kind { if nmis.len() == 1 { if let MetaItem(ref cfg_mi) = nmis[0] { - if cfg_mi.check_name(sym::cfg) { + if cfg_mi.has_name(sym::cfg) { if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind { if cfg_nmis.len() == 1 { if let MetaItem(ref content_mi) = cfg_nmis[0] { @@ -447,7 +447,7 @@ impl Attributes { pub fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> { mi.meta_item_list().and_then(|list| { for meta in list { - if meta.check_name(sym::include) { + if meta.has_name(sym::include) { // the actual compiled `#[doc(include="filename")]` gets expanded to // `#[doc(include(file="filename", contents="file contents")]` so we need to // look for that instead @@ -456,11 +456,11 @@ impl Attributes { let mut contents: Option<String> = None; for it in list { - if it.check_name(sym::file) { + if it.has_name(sym::file) { if let Some(name) = it.value_str() { filename = Some(name.to_string()); } - } else if it.check_name(sym::contents) { + } else if it.has_name(sym::contents) { if let Some(docs) = it.value_str() { contents = Some(docs.to_string()); } @@ -482,12 +482,12 @@ impl Attributes { pub fn has_doc_flag(&self, flag: Symbol) -> bool { for attr in &self.other_attrs { - if !attr.check_name(sym::doc) { + if !attr.has_name(sym::doc) { continue; } if let Some(items) = attr.meta_item_list() { - if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) { + if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) { return true; } } @@ -521,7 +521,7 @@ impl Attributes { } None } else { - if attr.check_name(sym::doc) { + if attr.has_name(sym::doc) { if let Some(mi) = attr.meta() { if let Some(cfg_mi) = Attributes::extract_cfg(&mi) { // Extracted #[doc(cfg(...))] @@ -548,7 +548,7 @@ impl Attributes { // treat #[target_feature(enable = "feat")] attributes as if they were // #[doc(cfg(target_feature = "feat"))] attributes as well for attr in attrs.lists(sym::target_feature) { - if attr.check_name(sym::enable) { + if attr.has_name(sym::enable) { if let Some(feat) = attr.value_str() { let meta = attr::mk_name_value_item_str( Ident::with_dummy_span(sym::target_feature), @@ -648,7 +648,7 @@ impl Attributes { pub fn get_doc_aliases(&self) -> FxHashSet<String> { self.other_attrs .lists(sym::doc) - .filter(|a| a.check_name(sym::alias)) + .filter(|a| a.has_name(sym::alias)) .filter_map(|a| a.value_str().map(|s| s.to_string().replace("\"", ""))) .filter(|v| !v.is_empty()) .collect::<FxHashSet<_>>() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 378efa1a1be..5a9e9dda677 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -48,7 +48,7 @@ pub fn extern_location( // external crate e.attrs .lists(sym::doc) - .filter(|a| a.check_name(sym::html_root_url)) + .filter(|a| a.has_name(sym::html_root_url)) .filter_map(|a| a.value_str()) .map(|url| { let mut url = url.to_string(); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 002c5f96710..d5f7ddcbdfb 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -43,13 +43,13 @@ extern crate rustc_trait_selection; extern crate rustc_typeck; extern crate test as testing; #[macro_use] -extern crate log; +extern crate tracing; use std::default::Default; use std::env; -use std::panic; use std::process; +use rustc_errors::ErrorReported; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; use rustc_session::getopts; use rustc_session::{early_error, early_warn}; @@ -82,22 +82,14 @@ struct Output { } pub fn main() { - let thread_stack_size: usize = if cfg!(target_os = "haiku") { - 16_000_000 // 16MB on Haiku - } else { - 32_000_000 // 32MB on other platforms - }; rustc_driver::set_sigpipe_handler(); rustc_driver::install_ice_hook(); rustc_driver::init_env_logger("RUSTDOC_LOG"); - - let res = std::thread::Builder::new() - .stack_size(thread_stack_size) - .spawn(move || get_args().map(|args| main_args(&args)).unwrap_or(1)) - .unwrap() - .join() - .unwrap_or(rustc_driver::EXIT_FAILURE); - process::exit(res); + let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() { + Some(args) => main_args(&args), + _ => Err(ErrorReported), + }); + process::exit(exit_code); } fn get_args() -> Option<Vec<String>> { @@ -418,7 +410,10 @@ fn usage(argv0: &str) { println!("{}", options.usage(&format!("{} [options] <input>", argv0))); } -fn main_args(args: &[String]) -> i32 { +/// A result type used by several functions under `main()`. +type MainResult = Result<(), ErrorReported>; + +fn main_args(args: &[String]) -> MainResult { let mut options = getopts::Options::new(); for option in opts() { (option.apply)(&mut options); @@ -429,24 +424,27 @@ fn main_args(args: &[String]) -> i32 { early_error(ErrorOutputType::default(), &err.to_string()); } }; + + // Note that we discard any distinction between different non-zero exit + // codes from `from_matches` here. let options = match config::Options::from_matches(&matches) { Ok(opts) => opts, - Err(code) => return code, + Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorReported) }, }; - rustc_interface::interface::setup_callbacks_and_run_in_default_thread_pool_with_globals( + rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals( options.edition, + 1, // this runs single-threaded, even in a parallel compiler + &None, move || main_options(options), ) } -fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> i32 { +fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult { match res { - Ok(()) => 0, + Ok(()) => Ok(()), Err(err) => { - if !err.is_empty() { - diag.struct_err(&err).emit(); - } - 1 + diag.struct_err(&err).emit(); + Err(ErrorReported) } } } @@ -457,9 +455,9 @@ fn run_renderer<T: formats::FormatRenderer>( render_info: config::RenderInfo, diag: &rustc_errors::Handler, edition: rustc_span::edition::Edition, -) -> i32 { +) -> MainResult { match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition) { - Ok(_) => rustc_driver::EXIT_SUCCESS, + Ok(_) => Ok(()), Err(e) => { let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); let file = e.file.display().to_string(); @@ -468,17 +466,17 @@ fn run_renderer<T: formats::FormatRenderer>( } else { msg.note(&format!("failed to create or modify \"{}\"", file)).emit() } - rustc_driver::EXIT_FAILURE + Err(ErrorReported) } } } -fn main_options(options: config::Options) -> i32 { +fn main_options(options: config::Options) -> MainResult { let diag = core::new_handler(options.error_format, None, &options.debugging_options); match (options.should_test, options.markdown_input()) { (true, true) => return wrap_return(&diag, markdown::test(options)), - (true, false) => return wrap_return(&diag, test::run(options)), + (true, false) => return test::run(options), (false, true) => { return wrap_return( &diag, @@ -500,44 +498,37 @@ fn main_options(options: config::Options) -> i32 { // compiler all the way through the analysis passes. The rustdoc output is // then generated from the cleaned AST of the crate. This runs all the // plug/cleaning passes. - let result = rustc_driver::catch_fatal_errors(move || { - let crate_name = options.crate_name.clone(); - let crate_version = options.crate_version.clone(); - let output_format = options.output_format; - let (mut krate, renderinfo, renderopts) = core::run_core(options); + let crate_name = options.crate_name.clone(); + let crate_version = options.crate_version.clone(); + let output_format = options.output_format; + let (mut krate, renderinfo, renderopts) = core::run_core(options); - info!("finished with rustc"); + info!("finished with rustc"); - if let Some(name) = crate_name { - krate.name = name - } + if let Some(name) = crate_name { + krate.name = name + } - krate.version = crate_version; + krate.version = crate_version; - let out = Output { krate, renderinfo, renderopts }; + let out = Output { krate, renderinfo, renderopts }; - if show_coverage { - // if we ran coverage, bail early, we don't need to also generate docs at this point - // (also we didn't load in any of the useful passes) - return rustc_driver::EXIT_SUCCESS; - } + if show_coverage { + // if we ran coverage, bail early, we don't need to also generate docs at this point + // (also we didn't load in any of the useful passes) + return Ok(()); + } - let Output { krate, renderinfo, renderopts } = out; - info!("going to format"); - let (error_format, edition, debugging_options) = diag_opts; - let diag = core::new_handler(error_format, None, &debugging_options); - match output_format { - None | Some(config::OutputFormat::Html) => { - run_renderer::<html::render::Context>(krate, renderopts, renderinfo, &diag, edition) - } - Some(config::OutputFormat::Json) => { - run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition) - } + let Output { krate, renderinfo, renderopts } = out; + info!("going to format"); + let (error_format, edition, debugging_options) = diag_opts; + let diag = core::new_handler(error_format, None, &debugging_options); + match output_format { + None | Some(config::OutputFormat::Html) => { + run_renderer::<html::render::Context>(krate, renderopts, renderinfo, &diag, edition) + } + Some(config::OutputFormat::Json) => { + run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition) } - }); - - match result { - Ok(output) => output, - Err(_) => panic::resume_unwind(Box::new(rustc_errors::FatalErrorMarker)), } } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 0fdeefd79e9..3000afde0c2 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -28,7 +28,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { let mut new_items = Vec::new(); for &cnum in cx.tcx.crates().iter() { - for &did in cx.tcx.all_trait_implementations(cnum).iter() { + for &(did, _) in cx.tcx.all_trait_implementations(cnum).iter() { inline::build_impl(cx, did, None, &mut new_items); } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index e8ea7199710..b86a105ff76 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -42,7 +42,7 @@ pub struct TestOptions { pub attrs: Vec<String>, } -pub fn run(options: Options) -> Result<(), String> { +pub fn run(options: Options) -> Result<(), ErrorReported> { let input = config::Input::File(options.input.clone()); let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name; @@ -150,7 +150,7 @@ pub fn run(options: Options) -> Result<(), String> { }); let tests = match tests { Ok(tests) => tests, - Err(ErrorReported) => return Err(String::new()), + Err(ErrorReported) => return Err(ErrorReported), }; test_args.insert(0, "rustdoctest".to_string()); @@ -175,17 +175,17 @@ fn scrape_test_config(krate: &::rustc_hir::Crate<'_>) -> TestOptions { .item .attrs .iter() - .filter(|a| a.check_name(sym::doc)) + .filter(|a| a.has_name(sym::doc)) .flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new)) - .filter(|a| a.check_name(sym::test)) + .filter(|a| a.has_name(sym::test)) .collect(); let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[])); for attr in attrs { - if attr.check_name(sym::no_crate_inject) { + if attr.has_name(sym::no_crate_inject) { opts.no_crate_inject = true; } - if attr.check_name(sym::attr) { + if attr.has_name(sym::attr) { if let Some(l) = attr.meta_item_list() { for item in l { opts.attrs.push(pprust::meta_list_item_to_string(item)); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 735446d235c..cf57ffd0b4b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -165,11 +165,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { ) { debug!("visiting fn"); let macro_kind = item.attrs.iter().find_map(|a| { - if a.check_name(sym::proc_macro) { + if a.has_name(sym::proc_macro) { Some(MacroKind::Bang) - } else if a.check_name(sym::proc_macro_derive) { + } else if a.has_name(sym::proc_macro_derive) { Some(MacroKind::Derive) - } else if a.check_name(sym::proc_macro_attribute) { + } else if a.has_name(sym::proc_macro_attribute) { Some(MacroKind::Attr) } else { None @@ -189,7 +189,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let mut helpers = Vec::new(); for mi in item.attrs.lists(sym::proc_macro_derive) { - if !mi.check_name(sym::attributes) { + if !mi.has_name(sym::attributes) { continue; } @@ -419,8 +419,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // anything as it will probably be stripped anyway. if item.vis.node.is_pub() && self.inside_public_path { let please_inline = item.attrs.iter().any(|item| match item.meta_item_list() { - Some(ref list) if item.check_name(sym::doc) => { - list.iter().any(|i| i.check_name(sym::inline)) + Some(ref list) if item.has_name(sym::doc) => { + list.iter().any(|i| i.has_name(sym::inline)) } _ => false, }); diff --git a/src/test/assembly/asm/aarch64-modifiers.rs b/src/test/assembly/asm/aarch64-modifiers.rs index c2484e9b6d0..150997ee807 100644 --- a/src/test/assembly/asm/aarch64-modifiers.rs +++ b/src/test/assembly/asm/aarch64-modifiers.rs @@ -2,6 +2,7 @@ // assembly-output: emit-asm // compile-flags: -O // compile-flags: --target aarch64-unknown-linux-gnu +// needs-llvm-components: aarch64 #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/aarch64-types.rs b/src/test/assembly/asm/aarch64-types.rs index ce2f0082a06..b78a8cbb559 100644 --- a/src/test/assembly/asm/aarch64-types.rs +++ b/src/test/assembly/asm/aarch64-types.rs @@ -1,6 +1,7 @@ // no-system-llvm // assembly-output: emit-asm // compile-flags: --target aarch64-unknown-linux-gnu +// needs-llvm-components: aarch64 #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/arm-modifiers.rs b/src/test/assembly/asm/arm-modifiers.rs index b71503d0a53..ad4ab63f265 100644 --- a/src/test/assembly/asm/arm-modifiers.rs +++ b/src/test/assembly/asm/arm-modifiers.rs @@ -3,6 +3,7 @@ // compile-flags: -O // compile-flags: --target armv7-unknown-linux-gnueabihf // compile-flags: -C target-feature=+neon +// needs-llvm-components: arm #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/arm-types.rs b/src/test/assembly/asm/arm-types.rs index 1e338f56c4d..07e25a38e45 100644 --- a/src/test/assembly/asm/arm-types.rs +++ b/src/test/assembly/asm/arm-types.rs @@ -2,6 +2,7 @@ // assembly-output: emit-asm // compile-flags: --target armv7-unknown-linux-gnueabihf // compile-flags: -C target-feature=+neon +// needs-llvm-components: arm #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/hexagon-types.rs b/src/test/assembly/asm/hexagon-types.rs index ba2d8a363cd..b6b3b54cd71 100644 --- a/src/test/assembly/asm/hexagon-types.rs +++ b/src/test/assembly/asm/hexagon-types.rs @@ -1,6 +1,7 @@ // no-system-llvm // assembly-output: emit-asm // compile-flags: --target hexagon-unknown-linux-musl +// needs-llvm-components: hexagon #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/nvptx-types.rs b/src/test/assembly/asm/nvptx-types.rs index 4ee79d1bcc8..77fd5141357 100644 --- a/src/test/assembly/asm/nvptx-types.rs +++ b/src/test/assembly/asm/nvptx-types.rs @@ -2,6 +2,7 @@ // assembly-output: emit-asm // compile-flags: --target nvptx64-nvidia-cuda // compile-flags: --crate-type cdylib +// needs-llvm-components: nvptx #![feature(no_core, lang_items, rustc_attrs)] #![no_core] diff --git a/src/test/assembly/asm/riscv-modifiers.rs b/src/test/assembly/asm/riscv-modifiers.rs index 8c816e3220b..b6735153b5d 100644 --- a/src/test/assembly/asm/riscv-modifiers.rs +++ b/src/test/assembly/asm/riscv-modifiers.rs @@ -3,6 +3,7 @@ // compile-flags: -O // compile-flags: --target riscv64gc-unknown-linux-gnu // compile-flags: -C target-feature=+f +// needs-llvm-components: riscv #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/riscv-types.rs b/src/test/assembly/asm/riscv-types.rs index 449213471cc..0ff0bf1f949 100644 --- a/src/test/assembly/asm/riscv-types.rs +++ b/src/test/assembly/asm/riscv-types.rs @@ -4,6 +4,7 @@ //[riscv64] compile-flags: --target riscv64imac-unknown-none-elf //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf // compile-flags: -C target-feature=+d +// needs-llvm-components: riscv #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs index 7c61b780990..1c0b77ad9c7 100644 --- a/src/test/codegen/abi-efiapi.rs +++ b/src/test/codegen/abi-efiapi.rs @@ -1,12 +1,14 @@ // Checks if the correct annotation for the efiapi ABI is passed to llvm. -// revisions:x86_64 i686 arm - +// revisions:x86_64 i686 aarch64 arm riscv // min-llvm-version: 9.0 +// needs-llvm-components: aarch64 arm riscv //[x86_64] compile-flags: --target x86_64-unknown-uefi //[i686] compile-flags: --target i686-unknown-linux-musl +//[aarch64] compile-flags: --target aarch64-unknown-none //[arm] compile-flags: --target armv7r-none-eabi +//[riscv] compile-flags: --target riscv64gc-unknown-none-elf // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] @@ -22,6 +24,8 @@ trait Copy { } //x86_64: define win64cc void @has_efiapi //i686: define void @has_efiapi +//aarch64: define void @has_efiapi //arm: define void @has_efiapi +//riscv: define void @has_efiapi #[no_mangle] pub extern "efiapi" fn has_efiapi() {} diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs index 7759d9603a5..6d25ca56f14 100644 --- a/src/test/codegen/avr/avr-func-addrspace.rs +++ b/src/test/codegen/avr/avr-func-addrspace.rs @@ -1,4 +1,5 @@ // compile-flags: -O --target=avr-unknown-unknown --crate-type=rlib +// needs-llvm-components: avr // This test validates that function pointers can be stored in global variables // and called upon. It ensures that Rust emits function pointers in the correct diff --git a/src/test/codegen/wasm_casts_trapping.rs b/src/test/codegen/wasm_casts_trapping.rs index b7f8522fdfb..ed51faa7be1 100644 --- a/src/test/codegen/wasm_casts_trapping.rs +++ b/src/test/codegen/wasm_casts_trapping.rs @@ -5,72 +5,72 @@ // CHECK-LABEL: @cast_f64_i64 #[no_mangle] pub fn cast_f64_i64(a: f64) -> i64 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptosi double {{.*}} to i64 - // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK-NOT: fptosi double {{.*}} to i64 + // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f64_i32 #[no_mangle] pub fn cast_f64_i32(a: f64) -> i32 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptosi double {{.*}} to i32 - // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK-NOT: fptosi double {{.*}} to i32 + // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f32_i64 #[no_mangle] pub fn cast_f32_i64(a: f32) -> i64 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptosi float {{.*}} to i64 - // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK-NOT: fptosi float {{.*}} to i64 + // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f32_i32 #[no_mangle] pub fn cast_f32_i32(a: f32) -> i32 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptosi float {{.*}} to i32 - // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK-NOT: fptosi float {{.*}} to i32 + // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f64_u64 #[no_mangle] pub fn cast_f64_u64(a: f64) -> u64 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptoui double {{.*}} to i64 - // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK-NOT: fptoui double {{.*}} to i64 + // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f64_u32 #[no_mangle] pub fn cast_f64_u32(a: f64) -> u32 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptoui double {{.*}} to i32 - // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK-NOT: fptoui double {{.*}} to i32 + // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f32_u64 #[no_mangle] pub fn cast_f32_u64(a: f32) -> u64 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptoui float {{.*}} to i64 - // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK-NOT: fptoui float {{.*}} to i64 + // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } // CHECK-LABEL: @cast_f32_u32 #[no_mangle] pub fn cast_f32_u32(a: f32) -> u32 { - // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} - // CHECK: fptoui float {{.*}} to i32 - // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK-NOT: fptoui float {{.*}} to i32 + // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}} + // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}} a as _ } diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs index 8ab8a2f9c1c..87bc79ea794 100644 --- a/src/test/debuginfo/rc_arc.rs +++ b/src/test/debuginfo/rc_arc.rs @@ -1,3 +1,4 @@ +// ignore-windows pretty-printers are not loaded // compile-flags:-g // min-gdb-version: 8.1 diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff index 96df5c6a518..9ca6f93c9bc 100644 --- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -2,58 +2,76 @@ + // MIR for `bar` after InstrumentCoverage fn bar() -> bool { - let mut _0: bool; // return place in scope 0 at $DIR/instrument_coverage.rs:18:13: 18:17 -+ let mut _1: (); // in scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18 + let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17 ++ let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18 bb0: { -+ StorageLive(_1); // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18 -+ _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const 529_u32, const 541_u32) -> bb2; // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18 ++ StorageLive(_1); // scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18 ++ _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const "/the/src/instrument_coverage.rs", const 19_u32, const 18_u32, const 21_u32, const 2_u32) -> bb2; // scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18 + // ty::Const -+ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region} ++ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region} + // + val: Value(Scalar(<ZST>)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18 -+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) } ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) } + // ty::Const + // + ty: u64 + // + val: Value(Scalar(0x8dabe565aaa2aefd)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18 ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 + // + literal: Const { ty: u64, val: Value(Scalar(0x8dabe565aaa2aefd)) } + // ty::Const + // + ty: u32 + // + val: Value(Scalar(0x00000000)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18 ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 + // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) } + // ty::Const ++ // + ty: &str ++ // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) ++ // mir::Constant ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 ++ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) } ++ // ty::Const ++ // + ty: u32 ++ // + val: Value(Scalar(0x00000013)) ++ // mir::Constant ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000013)) } ++ // ty::Const ++ // + ty: u32 ++ // + val: Value(Scalar(0x00000012)) ++ // mir::Constant ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000012)) } ++ // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x00000211)) ++ // + val: Value(Scalar(0x00000015)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000211)) } ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000015)) } + // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x0000021d)) ++ // + val: Value(Scalar(0x00000002)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000021d)) } ++ // + span: /the/src/instrument_coverage.rs:19:18: 19:18 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) } + } + + bb1 (cleanup): { -+ resume; // scope 0 at $DIR/instrument_coverage.rs:18:1: 20:2 ++ resume; // scope 0 at /the/src/instrument_coverage.rs:19:1: 21:2 + } + + bb2: { -+ StorageDead(_1); // scope 0 at $DIR/instrument_coverage.rs:19:5: 19:9 - _0 = const true; // scope 0 at $DIR/instrument_coverage.rs:19:5: 19:9 ++ StorageDead(_1); // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9 + _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9 // ty::Const // + ty: bool // + val: Value(Scalar(0x01)) // mir::Constant - // + span: $DIR/instrument_coverage.rs:19:5: 19:9 + // + span: /the/src/instrument_coverage.rs:20:5: 20:9 // + literal: Const { ty: bool, val: Value(Scalar(0x01)) } - return; // scope 0 at $DIR/instrument_coverage.rs:20:2: 20:2 + return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 } } diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 1bcc98de8d4..3f47aa13bf9 100644 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -2,99 +2,117 @@ + // MIR for `main` after InstrumentCoverage fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 - let mut _1: (); // in scope 0 at $DIR/instrument_coverage.rs:9:1: 15:2 - let mut _2: bool; // in scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17 - let mut _3: !; // in scope 0 at $DIR/instrument_coverage.rs:11:18: 13:10 -+ let mut _4: (); // in scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 + let mut _0: (); // return place in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11 + let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2 + let mut _2: bool; // in scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 + let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10 ++ let mut _4: (); // in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11 bb0: { -- falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6 -+ StorageLive(_4); // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 -+ _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const 425_u32, const 493_u32) -> bb7; // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 +- falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 ++ StorageLive(_4); // scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11 ++ _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const "/the/src/instrument_coverage.rs", const 10_u32, const 11_u32, const 16_u32, const 2_u32) -> bb7; // scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11 + // ty::Const -+ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region} ++ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region} + // + val: Value(Scalar(<ZST>)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11 -+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) } ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) } + // ty::Const + // + ty: u64 + // + val: Value(Scalar(0xde1b3f75a72fc7f7)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11 ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 + // + literal: Const { ty: u64, val: Value(Scalar(0xde1b3f75a72fc7f7)) } + // ty::Const + // + ty: u32 + // + val: Value(Scalar(0x00000000)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11 ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 + // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) } + // ty::Const ++ // + ty: &str ++ // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) ++ // mir::Constant ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 ++ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) } ++ // ty::Const ++ // + ty: u32 ++ // + val: Value(Scalar(0x0000000a)) ++ // mir::Constant ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x0000000a)) } ++ // ty::Const ++ // + ty: u32 ++ // + val: Value(Scalar(0x0000000b)) ++ // mir::Constant ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x0000000b)) } ++ // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x000001a9)) ++ // + val: Value(Scalar(0x00000010)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x000001a9)) } ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000010)) } + // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x000001ed)) ++ // + val: Value(Scalar(0x00000002)) + // mir::Constant -+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x000001ed)) } ++ // + span: /the/src/instrument_coverage.rs:10:11: 10:11 ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) } } bb1: { - StorageLive(_2); // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17 - _2 = const bar() -> [return: bb3, unwind: bb2]; // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17 + StorageLive(_2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 + _2 = const bar() -> [return: bb3, unwind: bb2]; // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 // ty::Const // + ty: fn() -> bool {bar} // + val: Value(Scalar(<ZST>)) // mir::Constant - // + span: $DIR/instrument_coverage.rs:11:12: 11:15 + // + span: /the/src/instrument_coverage.rs:12:12: 12:15 // + literal: Const { ty: fn() -> bool {bar}, val: Value(Scalar(<ZST>)) } } bb2 (cleanup): { - resume; // scope 0 at $DIR/instrument_coverage.rs:9:1: 15:2 + resume; // scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2 } bb3: { - FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17 - switchInt(_2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10 + FakeRead(ForMatchedPlace, _2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 + switchInt(_2) -> [false: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb4: { - falseEdge -> [real: bb6, imaginary: bb5]; // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10 + falseEdge -> [real: bb6, imaginary: bb5]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb5: { - _1 = const (); // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10 + _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 // ty::Const // + ty: () // + val: Value(Scalar(<ZST>)) // mir::Constant - // + span: $DIR/instrument_coverage.rs:11:9: 13:10 + // + span: /the/src/instrument_coverage.rs:12:9: 14:10 // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - StorageDead(_2); // scope 0 at $DIR/instrument_coverage.rs:14:5: 14:6 - goto -> bb0; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6 + StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 + goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } bb6: { - _0 = const (); // scope 0 at $DIR/instrument_coverage.rs:12:13: 12:18 + _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18 // ty::Const // + ty: () // + val: Value(Scalar(<ZST>)) // mir::Constant - // + span: $DIR/instrument_coverage.rs:12:13: 12:18 + // + span: /the/src/instrument_coverage.rs:13:13: 13:18 // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - StorageDead(_2); // scope 0 at $DIR/instrument_coverage.rs:14:5: 14:6 - return; // scope 0 at $DIR/instrument_coverage.rs:15:2: 15:2 + StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 + return; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 + } + + bb7: { -+ StorageDead(_4); // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6 -+ falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6 ++ StorageDead(_4); // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 ++ falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } } diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs index 4770ec9b66e..430573c7c05 100644 --- a/src/test/mir-opt/instrument_coverage.rs +++ b/src/test/mir-opt/instrument_coverage.rs @@ -3,7 +3,8 @@ // intrinsics, during codegen. // needs-profiler-support -// compile-flags: -Zinstrument-coverage +// ignore-windows +// compile-flags: -Zinstrument-coverage --remap-path-prefix={{src-base}}=/the/src // EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff // EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff fn main() { @@ -18,3 +19,18 @@ fn main() { fn bar() -> bool { true } + +// Note that the MIR with injected coverage intrinsics includes references to source locations, +// including the source file absolute path. Typically, MIR pretty print output with file +// references are safe because the file prefixes are substituted with `$DIR`, but in this case +// the file references are encoded as function arguments, with an `Operand` type representation +// (`Slice` `Allocation` interned byte array) that cannot be normalized by simple substitution. +// +// The first workaround is to use the `SourceMap`-supported `--remap-path-prefix` option; however, +// the implementation of the `--remap-path-prefix` option currently joins the new prefix and the +// remaining source path with an OS-specific path separator (`\` on Windows). This difference still +// shows up in the byte array representation of the path, causing Windows tests to fail to match +// blessed results baselined with a `/` path separator. +// +// Since this `mir-opt` test does not have any significant platform dependencies, other than the +// path separator differences, the final workaround is to disable testing on Windows. diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index 9317b36ba49..2bfcdd75e15 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -73,7 +73,6 @@ fn f() { */ - /* */ /* @@ -81,7 +80,6 @@ fn f() { Space 6+2: compare A Ogham Space Mark 6+2: compare B */ - /* */ /* diff --git a/src/test/pretty/issue-74745.rs b/src/test/pretty/issue-74745.rs new file mode 100644 index 00000000000..e255cd6caa8 --- /dev/null +++ b/src/test/pretty/issue-74745.rs @@ -0,0 +1,5 @@ +// ignore-tidy-trailing-newlines +// pretty-compare-only + +/* +*/ \ No newline at end of file diff --git a/src/test/ui/allocator/custom.rs b/src/test/ui/allocator/custom.rs index 184e4706a4c..a6c2317c736 100644 --- a/src/test/ui/allocator/custom.rs +++ b/src/test/ui/allocator/custom.rs @@ -4,10 +4,11 @@ // no-prefer-dynamic #![feature(allocator_api)] +#![feature(slice_ptr_get)] extern crate helper; -use std::alloc::{self, AllocInit, AllocRef, Global, Layout, System}; +use std::alloc::{self, AllocRef, Global, Layout, System}; use std::sync::atomic::{AtomicUsize, Ordering}; static HITS: AtomicUsize = AtomicUsize::new(0); @@ -37,10 +38,10 @@ fn main() { unsafe { let layout = Layout::from_size_align(4, 2).unwrap(); - let memory = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap(); - helper::work_with(&memory.ptr); + let memory = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&memory); assert_eq!(HITS.load(Ordering::SeqCst), n + 1); - Global.dealloc(memory.ptr, layout); + Global.dealloc(memory.as_non_null_ptr(), layout); assert_eq!(HITS.load(Ordering::SeqCst), n + 2); let s = String::with_capacity(10); @@ -49,10 +50,10 @@ fn main() { drop(s); assert_eq!(HITS.load(Ordering::SeqCst), n + 4); - let memory = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap(); + let memory = System.alloc(layout.clone()).unwrap(); assert_eq!(HITS.load(Ordering::SeqCst), n + 4); - helper::work_with(&memory.ptr); - System.dealloc(memory.ptr, layout); + helper::work_with(&memory); + System.dealloc(memory.as_non_null_ptr(), layout); assert_eq!(HITS.load(Ordering::SeqCst), n + 4); } } diff --git a/src/test/ui/allocator/xcrate-use.rs b/src/test/ui/allocator/xcrate-use.rs index 7de1ab7a553..a1446b3664d 100644 --- a/src/test/ui/allocator/xcrate-use.rs +++ b/src/test/ui/allocator/xcrate-use.rs @@ -5,11 +5,12 @@ // no-prefer-dynamic #![feature(allocator_api)] +#![feature(slice_ptr_get)] extern crate custom; extern crate helper; -use std::alloc::{AllocInit, AllocRef, Global, Layout, System}; +use std::alloc::{AllocRef, Global, Layout, System}; use std::sync::atomic::{AtomicUsize, Ordering}; #[global_allocator] @@ -20,16 +21,16 @@ fn main() { let n = GLOBAL.0.load(Ordering::SeqCst); let layout = Layout::from_size_align(4, 2).unwrap(); - let memory = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap(); - helper::work_with(&memory.ptr); + let memory = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&memory); assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); - Global.dealloc(memory.ptr, layout); + Global.dealloc(memory.as_non_null_ptr(), layout); assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); - let memory = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap(); + let memory = System.alloc(layout.clone()).unwrap(); assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); - helper::work_with(&memory.ptr); - System.dealloc(memory.ptr, layout); + helper::work_with(&memory); + System.dealloc(memory.as_non_null_ptr(), layout); assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); } } diff --git a/src/test/ui/async-await/issue-68523-start.rs b/src/test/ui/async-await/issue-68523-start.rs index 5988dffd68f..2ced88a16cc 100644 --- a/src/test/ui/async-await/issue-68523-start.rs +++ b/src/test/ui/async-await/issue-68523-start.rs @@ -4,6 +4,6 @@ #[start] pub async fn start(_: isize, _: *const *const u8) -> isize { -//~^ ERROR start is not allowed to be `async` +//~^ ERROR `start` is not allowed to be `async` 0 } diff --git a/src/test/ui/async-await/issue-68523-start.stderr b/src/test/ui/async-await/issue-68523-start.stderr index e471945900e..3a0a3b5dece 100644 --- a/src/test/ui/async-await/issue-68523-start.stderr +++ b/src/test/ui/async-await/issue-68523-start.stderr @@ -1,8 +1,8 @@ -error[E0752]: start is not allowed to be `async` +error[E0752]: `start` is not allowed to be `async` --> $DIR/issue-68523-start.rs:6:1 | LL | pub async fn start(_: isize, _: *const *const u8) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ start is not allowed to be `async` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `start` is not allowed to be `async` error: aborting due to previous error diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs index cd635c6a722..876d8b079a1 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -9,13 +9,13 @@ #[cfg_attr(all(), deprecated, must_use)] struct MustUseDeprecated {} -impl MustUseDeprecated { //~ warning: use of deprecated item - fn new() -> MustUseDeprecated { //~ warning: use of deprecated item - MustUseDeprecated {} //~ warning: use of deprecated item +impl MustUseDeprecated { //~ warning: use of deprecated + fn new() -> MustUseDeprecated { //~ warning: use of deprecated + MustUseDeprecated {} //~ warning: use of deprecated } } fn main() { - MustUseDeprecated::new(); //~ warning: use of deprecated item + MustUseDeprecated::new(); //~ warning: use of deprecated //~| warning: unused `MustUseDeprecated` that must be used } diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr index d7b5d2d263a..21b3a6f1f33 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:12:6 | LL | impl MustUseDeprecated { @@ -6,19 +6,19 @@ LL | impl MustUseDeprecated { | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:19:5 | LL | MustUseDeprecated::new(); | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:13:17 | LL | fn new() -> MustUseDeprecated { | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:14:9 | LL | MustUseDeprecated {} diff --git a/src/test/ui/const-generics/issues/issue-64494.rs b/src/test/ui/const-generics/issues/issue-64494.rs new file mode 100644 index 00000000000..4c755530b99 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-64494.rs @@ -0,0 +1,19 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait Foo { + const VAL: usize; +} + +trait MyTrait {} + +trait True {} +struct Is<const T: bool>; +impl True for Is<{true}> {} + +impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} +//~^ ERROR constant expression depends on a generic parameter +impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} +//~^ ERROR constant expression depends on a generic parameter + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-64494.stderr b/src/test/ui/const-generics/issues/issue-64494.stderr new file mode 100644 index 00000000000..30dca169643 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-64494.stderr @@ -0,0 +1,18 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-64494.rs:14:53 + | +LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/issue-64494.rs:16:53 + | +LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/issues/issue-72787.rs b/src/test/ui/const-generics/issues/issue-72787.rs new file mode 100644 index 00000000000..a368c226ec3 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-72787.rs @@ -0,0 +1,32 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +pub struct IsLessOrEqual<const LHS: u32, const RHS: u32>; +pub struct Condition<const CONDITION: bool>; +pub trait True {} + +impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where + Condition<{ LHS <= RHS }>: True +//~^ Error constant expression depends on a generic parameter +{ +} +impl True for Condition<true> {} + +struct S<const I: u32, const J: u32>; +impl<const I: u32, const J: u32> S<I, J> +where + IsLessOrEqual<I, 8>: True, + IsLessOrEqual<J, 8>: True, + IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, +//~^ Error constant expression depends on a generic parameter +//~| Error constant expression depends on a generic parameter +//~| Error constant expression depends on a generic parameter +//~| Error constant expression depends on a generic parameter + // Condition<{ 8 - I <= 8 - J }>: True, +{ + fn print() { + println!("I {} J {}", I, J); + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-72787.stderr b/src/test/ui/const-generics/issues/issue-72787.stderr new file mode 100644 index 00000000000..ed892e46bbb --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-72787.stderr @@ -0,0 +1,42 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-72787.rs:9:32 + | +LL | Condition<{ LHS <= RHS }>: True + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/issue-72787.rs:20:42 + | +LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/issue-72787.rs:20:42 + | +LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/issue-72787.rs:20:42 + | +LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/issue-72787.rs:20:42 + | +LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs index c6b794de195..51e1af359cd 100644 --- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs +++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs @@ -10,7 +10,7 @@ // const-evaluator computes a value that *does* meet the conditions for // structural-match, but the const expression itself has abstractions (like // calls to const functions) that may fit better with a type-based analysis -// rather than a committment to a specific value. +// rather than a commitment to a specific value. #![warn(indirect_structural_match)] diff --git a/src/test/ui/consts/issue-73976-polymorphic.rs b/src/test/ui/consts/issue-73976-polymorphic.rs index 518036c9dbe..b3d8610ff51 100644 --- a/src/test/ui/consts/issue-73976-polymorphic.rs +++ b/src/test/ui/consts/issue-73976-polymorphic.rs @@ -1,5 +1,5 @@ // This test is from #73976. We previously did not check if a type is monomorphized -// before calculating its type id, which leads to the bizzare behaviour below that +// before calculating its type id, which leads to the bizarre behaviour below that // TypeId of a generic type does not match itself. // // This test case should either run-pass or be rejected at compile time. diff --git a/src/test/ui/consts/unsizing-cast-non-null.rs b/src/test/ui/consts/unsizing-cast-non-null.rs new file mode 100644 index 00000000000..67d9f6baca5 --- /dev/null +++ b/src/test/ui/consts/unsizing-cast-non-null.rs @@ -0,0 +1,10 @@ +// Regression test for #75118. + +use std::ptr::NonNull; + +pub const fn dangling_slice<T>() -> NonNull<[T]> { + NonNull::<[T; 0]>::dangling() + //~^ ERROR: unsizing casts are only allowed for references right now +} + +fn main() {} diff --git a/src/test/ui/consts/unsizing-cast-non-null.stderr b/src/test/ui/consts/unsizing-cast-non-null.stderr new file mode 100644 index 00000000000..6575355daad --- /dev/null +++ b/src/test/ui/consts/unsizing-cast-non-null.stderr @@ -0,0 +1,12 @@ +error[E0723]: unsizing casts are only allowed for references right now + --> $DIR/unsizing-cast-non-null.rs:6:5 + | +LL | NonNull::<[T; 0]>::dangling() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/deprecation/atomic_initializers.fixed b/src/test/ui/deprecation/atomic_initializers.fixed index d8485ed7da1..4fb0aeeb573 100644 --- a/src/test/ui/deprecation/atomic_initializers.fixed +++ b/src/test/ui/deprecation/atomic_initializers.fixed @@ -6,6 +6,6 @@ use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; #[allow(dead_code)] static FOO: AtomicIsize = AtomicIsize::new(0); -//~^ WARN use of deprecated item +//~^ WARN use of deprecated constant fn main() {} diff --git a/src/test/ui/deprecation/atomic_initializers.rs b/src/test/ui/deprecation/atomic_initializers.rs index b15a1bbfd92..1dcfd36d7d5 100644 --- a/src/test/ui/deprecation/atomic_initializers.rs +++ b/src/test/ui/deprecation/atomic_initializers.rs @@ -6,6 +6,6 @@ use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; #[allow(dead_code)] static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; -//~^ WARN use of deprecated item +//~^ WARN use of deprecated constant fn main() {} diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr index 75baf4a1bf9..eaf5c61b440 100644 --- a/src/test/ui/deprecation/atomic_initializers.stderr +++ b/src/test/ui/deprecation/atomic_initializers.stderr @@ -1,8 +1,8 @@ -warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred +warning: use of deprecated constant `std::sync::atomic::ATOMIC_ISIZE_INIT`: the `new` function is now preferred --> $DIR/atomic_initializers.rs:8:27 | LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; - | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated item: `AtomicIsize::new(0)` + | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated constant: `AtomicIsize::new(0)` | = note: `#[warn(deprecated)]` on by default diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs index bfeab49548f..53826183d06 100644 --- a/src/test/ui/deprecation/deprecation-in-future.rs +++ b/src/test/ui/deprecation/deprecation-in-future.rs @@ -7,7 +7,7 @@ pub fn deprecated_future() {} fn test() { deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated - //~^ WARNING use of deprecated item 'deprecated_future': text [deprecated] + //~^ WARNING use of deprecated function `deprecated_future`: text [deprecated] } fn main() {} diff --git a/src/test/ui/deprecation/deprecation-in-future.stderr b/src/test/ui/deprecation/deprecation-in-future.stderr index 3040dcd9939..6561ec74349 100644 --- a/src/test/ui/deprecation/deprecation-in-future.stderr +++ b/src/test/ui/deprecation/deprecation-in-future.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'deprecated_future': text +warning: use of deprecated function `deprecated_future`: text --> $DIR/deprecation-in-future.rs:9:5 | LL | deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated diff --git a/src/test/ui/deprecation/deprecation-lint-2.rs b/src/test/ui/deprecation/deprecation-lint-2.rs index 2aa0d0c64d2..16ed6d4ecd6 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.rs +++ b/src/test/ui/deprecation/deprecation-lint-2.rs @@ -1,5 +1,5 @@ // aux-build:deprecation-lint.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] diff --git a/src/test/ui/deprecation/deprecation-lint-2.stderr b/src/test/ui/deprecation/deprecation-lint-2.stderr index 65152a2f9ab..b81d4bf402a 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.stderr +++ b/src/test/ui/deprecation/deprecation-lint-2.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'deprecation_lint::deprecated': text +error: use of deprecated function `deprecation_lint::deprecated`: text --> $DIR/deprecation-lint-2.rs:12:5 | LL | macro_test!(); diff --git a/src/test/ui/deprecation/deprecation-lint-3.rs b/src/test/ui/deprecation/deprecation-lint-3.rs index ae2dd7aac81..e6e1587daeb 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.rs +++ b/src/test/ui/deprecation/deprecation-lint-3.rs @@ -1,5 +1,5 @@ // aux-build:deprecation-lint.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] #![allow(warnings)] diff --git a/src/test/ui/deprecation/deprecation-lint-3.stderr b/src/test/ui/deprecation/deprecation-lint-3.stderr index b450f74d7f3..6f7cd9be2dd 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.stderr +++ b/src/test/ui/deprecation/deprecation-lint-3.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint-3.rs:13:5 | LL | macro_test_arg_nested!(deprecated_text); diff --git a/src/test/ui/deprecation/deprecation-lint-nested.rs b/src/test/ui/deprecation/deprecation-lint-nested.rs index ee6f0a22363..589522cdbdf 100644 --- a/src/test/ui/deprecation/deprecation-lint-nested.rs +++ b/src/test/ui/deprecation/deprecation-lint-nested.rs @@ -52,19 +52,19 @@ mod loud { #[deprecated] const DEPRECATED_CONST: u8 = 1; - struct Foo(DeprecatedType); //~ ERROR use of deprecated item + struct Foo(DeprecatedType); //~ ERROR use of deprecated type alias - impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated item + impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated trait impl Foo { - fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated item - deprecated_fn(); //~ ERROR use of deprecated item + fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated trait + deprecated_fn(); //~ ERROR use of deprecated function } } fn foo() -> u8 { - DEPRECATED_STATIC + //~ ERROR use of deprecated item - DEPRECATED_CONST //~ ERROR use of deprecated item + DEPRECATED_STATIC + //~ ERROR use of deprecated static + DEPRECATED_CONST //~ ERROR use of deprecated const } } diff --git a/src/test/ui/deprecation/deprecation-lint-nested.stderr b/src/test/ui/deprecation/deprecation-lint-nested.stderr index b71f90014fe..47607b8cc7c 100644 --- a/src/test/ui/deprecation/deprecation-lint-nested.stderr +++ b/src/test/ui/deprecation/deprecation-lint-nested.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'loud::DeprecatedType' +error: use of deprecated type alias `loud::DeprecatedType` --> $DIR/deprecation-lint-nested.rs:55:16 | LL | struct Foo(DeprecatedType); @@ -10,31 +10,31 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated item 'loud::DeprecatedTrait' +error: use of deprecated trait `loud::DeprecatedTrait` --> $DIR/deprecation-lint-nested.rs:57:10 | LL | impl DeprecatedTrait for Foo {} | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::DEPRECATED_STATIC' +error: use of deprecated static `loud::DEPRECATED_STATIC` --> $DIR/deprecation-lint-nested.rs:66:9 | LL | DEPRECATED_STATIC + | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::DEPRECATED_CONST' +error: use of deprecated constant `loud::DEPRECATED_CONST` --> $DIR/deprecation-lint-nested.rs:67:9 | LL | DEPRECATED_CONST | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::DeprecatedTrait' +error: use of deprecated trait `loud::DeprecatedTrait` --> $DIR/deprecation-lint-nested.rs:60:19 | LL | fn bar<T: DeprecatedTrait>() { | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::deprecated_fn' +error: use of deprecated function `loud::deprecated_fn` --> $DIR/deprecation-lint-nested.rs:61:13 | LL | deprecated_fn(); diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs index 26271395005..1932344fc57 100644 --- a/src/test/ui/deprecation/deprecation-lint.rs +++ b/src/test/ui/deprecation/deprecation-lint.rs @@ -14,86 +14,86 @@ mod cross_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated' - foo.method_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - - deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text - foo.method_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - - let _ = DeprecatedStruct { //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedStruct::i': text + deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated` + foo.method_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + + deprecated_text(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text + foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + + let _ = DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text }; - let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedUnitStruct': text + let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text - let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'deprecation_lint::Enum::DeprecatedVariant': text + let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text - let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTupleStruct': text + let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text - let _ = nested::DeprecatedStruct { //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedStruct::i': text + let _ = nested::DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text }; - let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedUnitStruct': text + let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text - let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'deprecation_lint::nested::Enum::DeprecatedVariant': text + let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text - let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedTupleStruct': text + let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text // At the moment, the lint checker only checks stability in // in the arguments of macros. // Eventually, we will want to lint the contents of the // macro in the module *defining* it. Also, stability levels // on macros themselves are not yet linted. - macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text - macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text + macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text + macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text } fn test_method_object(foo: &Trait) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text } struct S; - impl DeprecatedTrait for S {} //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTrait': text - trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTrait': text + impl DeprecatedTrait for S {} //~ ERROR use of deprecated trait `deprecation_lint::DeprecatedTrait`: text + trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated trait `deprecation_lint::DeprecatedTrait`: text pub fn foo() { let x = Stable { override2: 3, - //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text }; let _ = x.override2; - //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text let Stable { override2: _ - //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text } = x; // all fine let Stable { .. } = x; @@ -101,56 +101,56 @@ mod cross_crate { let x = Stable2(1, 2, 3); let _ = x.2; - //~^ ERROR use of deprecated item 'deprecation_lint::Stable2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable2::2`: text let Stable2(_, _, _) - //~^ ERROR use of deprecated item 'deprecation_lint::Stable2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable2::2`: text = x; // all fine let Stable2(..) = x; let x = Deprecated { - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text inherit: 1, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text }; let _ = x.inherit; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text let Deprecated { - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text inherit: _, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text } = x; let Deprecated - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text let _ = x.0; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::0': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::0`: text let _ = x.1; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::1': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::1`: text let _ = x.2; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::2`: text let Deprecated2 - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text (_, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::0': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::0`: text _, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::1': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::1`: text _) - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::2`: text = x; let Deprecated2 - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text // the patterns are all fine: (..) = x; } @@ -160,7 +160,7 @@ mod inheritance { use deprecation_lint::*; fn test_inheritance() { - deprecated_mod::deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_mod::deprecated': text + deprecated_mod::deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text } } @@ -243,65 +243,65 @@ mod this_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ ERROR use of deprecated item 'this_crate::deprecated' - foo.method_deprecated(); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - - deprecated_text(); //~ ERROR use of deprecated item 'this_crate::deprecated_text': text - foo.method_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + deprecated(); //~ ERROR use of deprecated function `this_crate::deprecated` + foo.method_deprecated(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + + deprecated_text(); //~ ERROR use of deprecated function `this_crate::deprecated_text`: text + foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text // Future deprecations are only permitted for rustc_deprecated. - deprecated_future(); //~ ERROR use of deprecated item - deprecated_future_text(); //~ ERROR use of deprecated item + deprecated_future(); //~ ERROR use of deprecated function + deprecated_future_text(); //~ ERROR use of deprecated function let _ = DeprecatedStruct { - //~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text + //~^ ERROR use of deprecated struct `this_crate::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `this_crate::DeprecatedStruct::i`: text }; - let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item 'this_crate::DeprecatedUnitStruct': text + let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text - let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'this_crate::Enum::DeprecatedVariant': text + let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text - let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'this_crate::DeprecatedTupleStruct': text + let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text let _ = nested::DeprecatedStruct { - //~^ ERROR use of deprecated item 'this_crate::nested::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedStruct::i': text + //~^ ERROR use of deprecated struct `this_crate::nested::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text }; - let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedUnitStruct': text + let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text - let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'this_crate::nested::Enum::DeprecatedVariant': text + let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text - let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedTupleStruct': text + let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text } fn test_method_object(foo: &Trait) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text } #[deprecated(since = "1.0.0", note = "text")] @@ -314,7 +314,7 @@ mod this_crate { let _ = || { #[deprecated] fn bar() { } - bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' + bar(); //~ ERROR use of deprecated function `this_crate::test_fn_closure_body::{{closure}}#0::bar` }; } @@ -333,9 +333,9 @@ mod this_crate { struct S; - impl DeprecatedTrait for S { } //~ ERROR use of deprecated item 'this_crate::DeprecatedTrait': text + impl DeprecatedTrait for S { } //~ ERROR use of deprecated trait `this_crate::DeprecatedTrait`: text - trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item 'this_crate::DeprecatedTrait': text + trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated trait `this_crate::DeprecatedTrait`: text } mod this_crate2 { @@ -361,15 +361,15 @@ mod this_crate2 { pub fn foo() { let x = Stable { override2: 3, - //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text + //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text }; let _ = x.override2; - //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text + //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text let Stable { override2: _ - //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text + //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text } = x; // all fine let Stable { .. } = x; @@ -377,57 +377,57 @@ mod this_crate2 { let x = Stable2(1, 2, 3); let _ = x.2; - //~^ ERROR use of deprecated item 'this_crate2::Stable2::2': text + //~^ ERROR use of deprecated field `this_crate2::Stable2::2`: text let Stable2(_, _, _) - //~^ ERROR use of deprecated item 'this_crate2::Stable2::2': text + //~^ ERROR use of deprecated field `this_crate2::Stable2::2`: text = x; // all fine let Stable2(..) = x; let x = Deprecated { - //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text + //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text inherit: 1, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text }; let _ = x.inherit; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text let Deprecated { - //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text + //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text inherit: _, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text } = x; let Deprecated - //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text + //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text // the patterns are all fine: { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text + //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text let _ = x.0; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::0': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::0`: text let _ = x.1; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::1': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::1`: text let _ = x.2; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::2': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::2`: text let Deprecated2 - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text + //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text (_, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::0': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::0`: text _, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::1': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::1`: text _) - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::2': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::2`: text = x; let Deprecated2 - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text + //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text // the patterns are all fine: (..) = x; } diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr index 362a901d77d..03a2ec7edc9 100644 --- a/src/test/ui/deprecation/deprecation-lint.stderr +++ b/src/test/ui/deprecation/deprecation-lint.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'deprecation_lint::deprecated': text +error: use of deprecated function `deprecation_lint::deprecated`: text --> $DIR/deprecation-lint.rs:17:9 | LL | deprecated(); @@ -10,727 +10,727 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:22:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:24:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:26:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:31:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:33:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedStruct': text +error: use of deprecated struct `deprecation_lint::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:35:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedUnitStruct': text +error: use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:39:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Enum::DeprecatedVariant': text +error: use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:41:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedTupleStruct': text +error: use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:43:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedStruct': text +error: use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:45:17 | LL | let _ = nested::DeprecatedStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedUnitStruct': text +error: use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:49:17 | LL | let _ = nested::DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::Enum::DeprecatedVariant': text +error: use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:51:17 | -LL | let _ = nested::Enum::DeprecatedVariant; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::Enum::DeprecatedVariant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedTupleStruct': text +error: use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:53:17 | -LL | let _ = nested::DeprecatedTupleStruct (1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::DeprecatedTupleStruct (1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:60:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:61:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:66:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:68:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:70:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:72:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedTrait': text +error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:82:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedTrait': text +error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:83:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated': text +error: use of deprecated struct `deprecation_lint::Deprecated`: text --> $DIR/deprecation-lint.rs:114:17 | LL | let x = Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated': text +error: use of deprecated struct `deprecation_lint::Deprecated`: text --> $DIR/deprecation-lint.rs:123:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated': text +error: use of deprecated struct `deprecation_lint::Deprecated`: text --> $DIR/deprecation-lint.rs:129:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2': text +error: use of deprecated struct `deprecation_lint::Deprecated2`: text --> $DIR/deprecation-lint.rs:133:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2': text +error: use of deprecated struct `deprecation_lint::Deprecated2`: text --> $DIR/deprecation-lint.rs:143:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2': text +error: use of deprecated struct `deprecation_lint::Deprecated2`: text --> $DIR/deprecation-lint.rs:152:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_mod::deprecated': text +error: use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text --> $DIR/deprecation-lint.rs:163:9 | LL | deprecated_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated': text +error: use of deprecated function `this_crate::deprecated`: text --> $DIR/deprecation-lint.rs:246:9 | LL | deprecated(); | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:251:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:253:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated_text': text +error: use of deprecated function `this_crate::deprecated_text`: text --> $DIR/deprecation-lint.rs:255:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:260:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:262:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated_future': text +error: use of deprecated function `this_crate::deprecated_future`: text --> $DIR/deprecation-lint.rs:265:9 | LL | deprecated_future(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated_future_text': text +error: use of deprecated function `this_crate::deprecated_future_text`: text --> $DIR/deprecation-lint.rs:266:9 | LL | deprecated_future_text(); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedStruct': text +error: use of deprecated struct `this_crate::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:268:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedUnitStruct': text +error: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:273:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text +error: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:275:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedTupleStruct': text +error: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:277:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedStruct': text +error: use of deprecated struct `this_crate::nested::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:279:17 | LL | let _ = nested::DeprecatedStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedUnitStruct': text +error: use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:284:17 | LL | let _ = nested::DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::Enum::DeprecatedVariant': text +error: use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:286:17 | -LL | let _ = nested::Enum::DeprecatedVariant; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::Enum::DeprecatedVariant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedTupleStruct': text +error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:288:17 | -LL | let _ = nested::DeprecatedTupleStruct (1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::DeprecatedTupleStruct (1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:293:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:295:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:297:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:299:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' +error: use of deprecated function `this_crate::test_fn_closure_body::{{closure}}#0::bar` --> $DIR/deprecation-lint.rs:317:13 | LL | bar(); | ^^^ -error: use of deprecated item 'this_crate::DeprecatedTrait': text +error: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:336:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedTrait': text +error: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:338:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated': text +error: use of deprecated struct `this_crate2::Deprecated`: text --> $DIR/deprecation-lint.rs:390:17 | LL | let x = Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated': text +error: use of deprecated struct `this_crate2::Deprecated`: text --> $DIR/deprecation-lint.rs:399:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated': text +error: use of deprecated struct `this_crate2::Deprecated`: text --> $DIR/deprecation-lint.rs:405:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2': text +error: use of deprecated tuple struct `this_crate2::Deprecated2`: text --> $DIR/deprecation-lint.rs:410:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2': text +error: use of deprecated tuple struct `this_crate2::Deprecated2`: text --> $DIR/deprecation-lint.rs:420:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2': text +error: use of deprecated tuple struct `this_crate2::Deprecated2`: text --> $DIR/deprecation-lint.rs:429:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:18:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:19:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:20:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:21:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:23:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:27:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:28:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:29:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:30:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:32:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedStruct::i': text +error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:36:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedStruct::i': text +error: use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:46:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:65:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:67:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:69:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:71:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:76:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:77:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable::override2': text +error: use of deprecated field `deprecation_lint::Stable::override2`: text --> $DIR/deprecation-lint.rs:87:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable::override2': text +error: use of deprecated field `deprecation_lint::Stable::override2`: text --> $DIR/deprecation-lint.rs:91:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable::override2': text +error: use of deprecated field `deprecation_lint::Stable::override2`: text --> $DIR/deprecation-lint.rs:95:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable2::2': text +error: use of deprecated field `deprecation_lint::Stable2::2`: text --> $DIR/deprecation-lint.rs:103:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'deprecation_lint::Stable2::2': text +error: use of deprecated field `deprecation_lint::Stable2::2`: text --> $DIR/deprecation-lint.rs:108:20 | LL | _) | ^ -error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text +error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:116:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text +error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:120:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text +error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:125:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::0': text +error: use of deprecated field `deprecation_lint::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:136:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::1': text +error: use of deprecated field `deprecation_lint::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:138:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::2': text +error: use of deprecated field `deprecation_lint::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:140:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::0': text +error: use of deprecated field `deprecation_lint::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:145:14 | LL | (_, | ^ -error: use of deprecated item 'deprecation_lint::Deprecated2::1': text +error: use of deprecated field `deprecation_lint::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:147:14 | LL | _, | ^ -error: use of deprecated item 'deprecation_lint::Deprecated2::2': text +error: use of deprecated field `deprecation_lint::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:149:14 | LL | _) | ^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:247:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:248:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:249:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:250:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:252:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:256:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:257:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:258:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:259:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:261:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedStruct::i': text +error: use of deprecated field `this_crate::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:270:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedStruct::i': text +error: use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:281:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:292:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:294:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:296:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:298:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:303:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:304:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable::override2': text +error: use of deprecated field `this_crate2::Stable::override2`: text --> $DIR/deprecation-lint.rs:363:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable::override2': text +error: use of deprecated field `this_crate2::Stable::override2`: text --> $DIR/deprecation-lint.rs:367:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable::override2': text +error: use of deprecated field `this_crate2::Stable::override2`: text --> $DIR/deprecation-lint.rs:371:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable2::2': text +error: use of deprecated field `this_crate2::Stable2::2`: text --> $DIR/deprecation-lint.rs:379:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate2::Stable2::2': text +error: use of deprecated field `this_crate2::Stable2::2`: text --> $DIR/deprecation-lint.rs:384:20 | LL | _) | ^ -error: use of deprecated item 'this_crate2::Deprecated::inherit': text +error: use of deprecated field `this_crate2::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:392:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated::inherit': text +error: use of deprecated field `this_crate2::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:396:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated::inherit': text +error: use of deprecated field `this_crate2::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:401:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2::0': text +error: use of deprecated field `this_crate2::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:413:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'this_crate2::Deprecated2::1': text +error: use of deprecated field `this_crate2::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:415:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'this_crate2::Deprecated2::2': text +error: use of deprecated field `this_crate2::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:417:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate2::Deprecated2::0': text +error: use of deprecated field `this_crate2::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:422:14 | LL | (_, | ^ -error: use of deprecated item 'this_crate2::Deprecated2::1': text +error: use of deprecated field `this_crate2::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:424:14 | LL | _, | ^ -error: use of deprecated item 'this_crate2::Deprecated2::2': text +error: use of deprecated field `this_crate2::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:426:14 | LL | _) diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs index a19363c5129..6a619bcc49c 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs @@ -11,5 +11,5 @@ pub struct S; fn main() { - let _ = S; //~ ERROR use of item 'S' that will be deprecated in future version 99.99.99: effectively never + let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never } diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr index 4aff11ad66f..e4f50d10dad 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr @@ -1,4 +1,4 @@ -error: use of item 'S' that will be deprecated in future version 99.99.99: effectively never +error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never --> $DIR/rustc_deprecation-in-future.rs:14:13 | LL | let _ = S; diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr index b60d420b546..8a7cb1def90 100644 --- a/src/test/ui/deprecation/suggestion.stderr +++ b/src/test/ui/deprecation/suggestion.stderr @@ -1,8 +1,8 @@ -error: use of deprecated item 'Foo::deprecated': replaced by `replacement` +error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement` --> $DIR/suggestion.rs:27:9 | LL | foo.deprecated(); - | ^^^^^^^^^^ help: replace the use of the deprecated item: `replacement` + | ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement` | note: the lint level is defined here --> $DIR/suggestion.rs:7:9 diff --git a/src/test/ui/issues/issue-17337.rs b/src/test/ui/issues/issue-17337.rs index 65f2f8fc5ac..3fd81401e00 100644 --- a/src/test/ui/issues/issue-17337.rs +++ b/src/test/ui/issues/issue-17337.rs @@ -13,5 +13,5 @@ impl Foo { fn main() { Foo - .foo(); //~ ERROR use of deprecated item + .foo(); //~ ERROR use of deprecated } diff --git a/src/test/ui/issues/issue-17337.stderr b/src/test/ui/issues/issue-17337.stderr index 4a8116b1ffd..34c2eb05fff 100644 --- a/src/test/ui/issues/issue-17337.stderr +++ b/src/test/ui/issues/issue-17337.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'Foo::foo': text +error: use of deprecated associated function `Foo::foo`: text --> $DIR/issue-17337.rs:16:6 | LL | .foo(); diff --git a/src/test/ui/issues/issue-37131.rs b/src/test/ui/issues/issue-37131.rs index aa3b6ea86bb..ac2d1d1ed8b 100644 --- a/src/test/ui/issues/issue-37131.rs +++ b/src/test/ui/issues/issue-37131.rs @@ -3,6 +3,7 @@ // compile-flags: --target=thumbv6m-none-eabi // ignore-arm +// needs-llvm-components: arm // error-pattern:target may not be installed fn main() { } diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs index 9449376513f..ddb070ddf9f 100644 --- a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs +++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs @@ -1,6 +1,7 @@ //~ ERROR 1:1: 1:1: can't find crate for `core` [E0463] // compile-flags: --target thumbv7em-none-eabihf +// needs-llvm-components: arm #![deny(unsafe_code)] #![deny(warnings)] #![no_std] diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs index 1d5eabd6170..f713dee507f 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs @@ -1,5 +1,3 @@ -#![feature(inner_deref)] - fn main() { let _result = &Ok(42).as_deref(); //~^ ERROR no method named `as_deref` found diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr index f33e9c7823e..96524c30959 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `as_deref` found for enum `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-as_deref.rs:4:27 + --> $DIR/result-as_deref.rs:2:27 | LL | let _result = &Ok(42).as_deref(); | ^^^^^^^^ help: there is an associated function with a similar name: `as_ref` diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs deleted file mode 100644 index 104aa3bcadf..00000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Err(41).as_deref_err(); -//~^ ERROR no method named `as_deref_err` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr deleted file mode 100644 index 68ebfab95c4..00000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0599]: no method named `as_deref_err` found for enum `std::result::Result<_, {integer}>` in the current scope - --> $DIR/result-as_deref_err.rs:4:28 - | -LL | let _result = &Err(41).as_deref_err(); - | ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_mut` - | - = note: the method `as_deref_err` exists but the following trait bounds were not satisfied: - `{integer}: std::ops::Deref` - `<{integer} as std::ops::Deref>::Target = _` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs index c897ab3531f..3af7033dd5d 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs @@ -1,5 +1,3 @@ -#![feature(inner_deref)] - fn main() { let _result = &mut Ok(42).as_deref_mut(); //~^ ERROR no method named `as_deref_mut` found diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr index d2ba1049b76..73266bc7f68 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr @@ -1,8 +1,8 @@ error[E0599]: no method named `as_deref_mut` found for enum `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-as_deref_mut.rs:4:31 + --> $DIR/result-as_deref_mut.rs:2:31 | LL | let _result = &mut Ok(42).as_deref_mut(); - | ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_err` + | ^^^^^^^^^^^^ method not found in `std::result::Result<{integer}, _>` | = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied: `{integer}: std::ops::DerefMut` diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs deleted file mode 100644 index b7849ecb6d2..00000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &mut Err(41).as_deref_mut_err(); -//~^ ERROR no method named `as_deref_mut_err` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr deleted file mode 100644 index d724ae5c74b..00000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0599]: no method named `as_deref_mut_err` found for enum `std::result::Result<_, {integer}>` in the current scope - --> $DIR/result-as_deref_mut_err.rs:4:32 - | -LL | let _result = &mut Err(41).as_deref_mut_err(); - | ^^^^^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_mut` - | - = note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied: - `{integer}: std::ops::DerefMut` - `<{integer} as std::ops::Deref>::Target = _` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs index d38eb826678..e6a9451a060 100644 --- a/src/test/ui/issues/issue-50993.rs +++ b/src/test/ui/issues/issue-50993.rs @@ -1,4 +1,5 @@ // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf +// needs-llvm-components: arm // build-pass // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` diff --git a/src/test/ui/issues/issue-72574-1.rs b/src/test/ui/issues/issue-72574-1.rs index efbb0bfb150..1b80a21793a 100644 --- a/src/test/ui/issues/issue-72574-1.rs +++ b/src/test/ui/issues/issue-72574-1.rs @@ -6,3 +6,5 @@ fn main() { } } //~^^^^ ERROR `_x @` is not allowed in a tuple +//~| ERROR: `..` patterns are not allowed here +//~| ERROR: mismatched types diff --git a/src/test/ui/issues/issue-72574-1.stderr b/src/test/ui/issues/issue-72574-1.stderr index 329f7d008d4..92ebb45e88d 100644 --- a/src/test/ui/issues/issue-72574-1.stderr +++ b/src/test/ui/issues/issue-72574-1.stderr @@ -10,5 +10,25 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining LL | (_a, ..) => {} | ^^ -error: aborting due to previous error +error: `..` patterns are not allowed here + --> $DIR/issue-72574-1.rs:4:19 + | +LL | (_a, _x @ ..) => {} + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0308]: mismatched types + --> $DIR/issue-72574-1.rs:4:9 + | +LL | match x { + | - this expression has type `({integer}, {integer}, {integer})` +LL | (_a, _x @ ..) => {} + | ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements + | + = note: expected tuple `({integer}, {integer}, {integer})` + found tuple `(_, _)` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-72574-2.rs b/src/test/ui/issues/issue-72574-2.rs index 0c8f6fcc508..0ad2db848b2 100644 --- a/src/test/ui/issues/issue-72574-2.rs +++ b/src/test/ui/issues/issue-72574-2.rs @@ -8,3 +8,5 @@ fn main() { } } //~^^^^ ERROR `_x @` is not allowed in a tuple struct +//~| ERROR: `..` patterns are not allowed here +//~| ERROR: this pattern has 2 fields, but the corresponding tuple struct has 3 fields diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr index 6faa57bcca6..0a9c868af7a 100644 --- a/src/test/ui/issues/issue-72574-2.stderr +++ b/src/test/ui/issues/issue-72574-2.stderr @@ -10,5 +10,23 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining LL | Binder(_a, ..) => {} | ^^ -error: aborting due to previous error +error: `..` patterns are not allowed here + --> $DIR/issue-72574-2.rs:6:25 + | +LL | Binder(_a, _x @ ..) => {} + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields + --> $DIR/issue-72574-2.rs:6:9 + | +LL | struct Binder(i32, i32, i32); + | ----------------------------- tuple struct defined here +... +LL | Binder(_a, _x @ ..) => {} + | ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2 + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0023`. diff --git a/src/test/ui/issues/issue-74539.rs b/src/test/ui/issues/issue-74539.rs deleted file mode 100644 index 75632d11c1d..00000000000 --- a/src/test/ui/issues/issue-74539.rs +++ /dev/null @@ -1,12 +0,0 @@ -enum E { - A(u8, u8), -} - -fn main() { - let e = E::A(2, 3); - match e { - E::A(x @ ..) => { //~ ERROR `x @` is not allowed in a tuple - x //~ ERROR cannot find value `x` in this scope - } - }; -} diff --git a/src/test/ui/issues/issue-74539.stderr b/src/test/ui/issues/issue-74539.stderr deleted file mode 100644 index 94526dcd7cb..00000000000 --- a/src/test/ui/issues/issue-74539.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-74539.rs:9:13 - | -LL | x - | ^ help: a local variable with a similar name exists: `e` - -error: `x @` is not allowed in a tuple struct - --> $DIR/issue-74539.rs:8:14 - | -LL | E::A(x @ ..) => { - | ^^^^^^ this is only allowed in slice patterns - | - = help: remove this and bind each tuple field independently -help: if you don't need to use the contents of x, discard the tuple's remaining fields - | -LL | E::A(..) => { - | ^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/issues/issue-75704.rs b/src/test/ui/issues/issue-75704.rs new file mode 100644 index 00000000000..aed7ddbcb8c --- /dev/null +++ b/src/test/ui/issues/issue-75704.rs @@ -0,0 +1,7 @@ +// Caused an infinite loop during SimlifyCfg MIR transform previously. +// +// build-pass + +fn main() { + loop { continue; } +} diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs new file mode 100644 index 00000000000..8064c3a88d1 --- /dev/null +++ b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs @@ -0,0 +1,26 @@ +#![feature(generator_trait)] +#![feature(generators)] +#![deny(unused_braces, unused_parens)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut x = |_| { + while let Some(_) = (yield) {} + while let Some(_) = {yield} {} + + // Only warn these cases + while let Some(_) = ({yield}) {} //~ ERROR: unnecessary parentheses + while let Some(_) = ((yield)) {} //~ ERROR: unnecessary parentheses + {{yield}}; //~ ERROR: unnecessary braces + {( yield )}; //~ ERROR: unnecessary parentheses + while let Some(_) = {(yield)} {} //~ ERROR: unnecessary parentheses + while let Some(_) = {{yield}} {} //~ ERROR: unnecessary braces + + // FIXME: It'd be great if we could also warn them. + ((yield)); + ({ yield }); + }; + let _ = Pin::new(&mut x).resume(Some(5)); +} diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr new file mode 100644 index 00000000000..3f6260dc6e1 --- /dev/null +++ b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr @@ -0,0 +1,50 @@ +error: unnecessary parentheses around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29 + | +LL | while let Some(_) = ({yield}) {} + | ^^^^^^^^^ help: remove these parentheses + | +note: the lint level is defined here + --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24 + | +LL | #![deny(unused_braces, unused_parens)] + | ^^^^^^^^^^^^^ + +error: unnecessary parentheses around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29 + | +LL | while let Some(_) = ((yield)) {} + | ^^^^^^^^^ help: remove these parentheses + +error: unnecessary braces around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10 + | +LL | {{yield}}; + | ^^^^^^^ help: remove these braces + | +note: the lint level is defined here + --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9 + | +LL | #![deny(unused_braces, unused_parens)] + | ^^^^^^^^^^^^^ + +error: unnecessary parentheses around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10 + | +LL | {( yield )}; + | ^^^^^^^^^ help: remove these parentheses + +error: unnecessary parentheses around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:18:30 + | +LL | while let Some(_) = {(yield)} {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary braces around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:19:30 + | +LL | while let Some(_) = {{yield}} {} + | ^^^^^^^ help: remove these braces + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs b/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs index 4f90bd98c63..034499145b7 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs @@ -23,7 +23,7 @@ struct _ヒb; struct __χa; //~^ ERROR type `__χa` should have an upper camel case name -// Besides this, we cannot have two continous underscores in the middle. +// Besides this, we cannot have two continuous underscores in the middle. struct 对__否; //~^ ERROR type `对__否` should have an upper camel case name diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs b/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs index 813e0ea5c57..0b52a5fde35 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs @@ -18,7 +18,7 @@ fn 编程() {} fn Ц() {} //~^ ERROR function `Ц` should have a snake case name -// besides this, you cannot use continous underscores in the middle +// besides this, you cannot use continuous underscores in the middle fn 分__隔() {} //~^ ERROR function `分__隔` should have a snake case name diff --git a/src/test/ui/lint/lint-output-format-2.rs b/src/test/ui/lint/lint-output-format-2.rs index 521472d99b1..985166e095d 100644 --- a/src/test/ui/lint/lint-output-format-2.rs +++ b/src/test/ui/lint/lint-output-format-2.rs @@ -5,11 +5,11 @@ extern crate lint_output_format; use lint_output_format::{foo, bar}; -//~^ WARNING use of deprecated item 'lint_output_format::foo': text +//~^ WARNING use of deprecated function `lint_output_format::foo`: text fn main() { let _x = foo(); - //~^ WARNING use of deprecated item 'lint_output_format::foo': text + //~^ WARNING use of deprecated function `lint_output_format::foo`: text let _y = bar(); } diff --git a/src/test/ui/lint/lint-output-format-2.stderr b/src/test/ui/lint/lint-output-format-2.stderr index a95fd69fb01..a36dbd61fdc 100644 --- a/src/test/ui/lint/lint-output-format-2.stderr +++ b/src/test/ui/lint/lint-output-format-2.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'lint_output_format::foo': text +warning: use of deprecated function `lint_output_format::foo`: text --> $DIR/lint-output-format-2.rs:7:26 | LL | use lint_output_format::{foo, bar}; @@ -6,7 +6,7 @@ LL | use lint_output_format::{foo, bar}; | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'lint_output_format::foo': text +warning: use of deprecated function `lint_output_format::foo`: text --> $DIR/lint-output-format-2.rs:12:14 | LL | let _x = foo(); diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 4b407a29f64..a6fde11495c 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -22,41 +22,41 @@ mod cross_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ WARN use of deprecated item 'lint_stability::deprecated' - foo.method_deprecated(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - - deprecated_text(); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text - foo.method_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - - deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable' - foo.method_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable' - Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable' - <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable' - foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - - deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable_text': text - foo.method_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text + deprecated(); //~ WARN use of deprecated function `lint_stability::deprecated` + foo.method_deprecated(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + + deprecated_text(); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text + foo.method_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + + deprecated_unstable(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable` + foo.method_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` + Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` + <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` + foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + + deprecated_unstable_text(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text + foo.method_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text + Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text + <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text unstable(); foo.method_unstable(); @@ -96,38 +96,38 @@ mod cross_crate { struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable); struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); - //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text + //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text + //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text type A = dyn TraitWithAssociatedTypes< TypeUnstable = u8, TypeDeprecated = u16, - //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' - //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' - //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' + //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated` + //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated` + //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated` >; - let _ = DeprecatedStruct { //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct' - i: 0 //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct::i' + let _ = DeprecatedStruct { //~ WARN use of deprecated struct `lint_stability::DeprecatedStruct` + i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedStruct::i` }; let _ = DeprecatedUnstableStruct { - //~^ WARN use of deprecated item 'lint_stability::DeprecatedUnstableStruct' - i: 0 //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i' + //~^ WARN use of deprecated struct `lint_stability::DeprecatedUnstableStruct` + i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedUnstableStruct::i` }; let _ = UnstableStruct { i: 0 }; let _ = StableStruct { i: 0 }; - let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item 'lint_stability::DeprecatedUnitStruct' - let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct' + let _ = DeprecatedUnitStruct; //~ WARN use of deprecated struct `lint_stability::DeprecatedUnitStruct` + let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct` let _ = UnstableUnitStruct; let _ = StableUnitStruct; - let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item 'lint_stability::Enum::DeprecatedVariant' - let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant' + let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated variant `lint_stability::Enum::DeprecatedVariant` + let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant` let _ = Enum::UnstableVariant; let _ = Enum::StableVariant; - let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item 'lint_stability::DeprecatedTupleStruct' - let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct' + let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated struct `lint_stability::DeprecatedTupleStruct` + let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct` let _ = UnstableTupleStruct (1); let _ = StableTupleStruct (1); @@ -136,28 +136,28 @@ mod cross_crate { // Eventually, we will want to lint the contents of the // macro in the module *defining* it. Also, stability levels // on macros themselves are not yet linted. - macro_test_arg!(deprecated_text()); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text - macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable_text': text - macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text + macro_test_arg!(deprecated_text()); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text + macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text + macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text foo.trait_unstable(); Trait::trait_unstable(&foo); <Foo>::trait_unstable(&foo); @@ -173,10 +173,10 @@ mod cross_crate { } fn test_method_object(foo: &dyn Trait) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text foo.trait_unstable(); foo.trait_unstable_text(); foo.trait_stable(); @@ -185,9 +185,9 @@ mod cross_crate { struct S; impl UnstableTrait for S { } - impl DeprecatedTrait for S {} //~ WARN use of deprecated item 'lint_stability::DeprecatedTrait': text + impl DeprecatedTrait for S {} //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text trait LocalTrait : UnstableTrait { } - trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated item 'lint_stability::DeprecatedTrait': text + trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text impl Trait for S { fn trait_stable(&self) {} @@ -206,7 +206,7 @@ mod inheritance { stable_mod::unstable(); stable_mod::stable(); - unstable_mod::deprecated(); //~ WARN use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text + unstable_mod::deprecated(); //~ WARN use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text unstable_mod::unstable(); let _ = Unstable::UnstableVariant; @@ -328,23 +328,23 @@ mod this_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ WARN use of deprecated item 'this_crate::deprecated' - foo.method_deprecated(); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - - deprecated_text(); //~ WARN use of deprecated item 'this_crate::deprecated_text': text - foo.method_deprecated_text(); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + deprecated(); //~ WARN use of deprecated function `this_crate::deprecated` + foo.method_deprecated(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + + deprecated_text(); //~ WARN use of deprecated function `this_crate::deprecated_text`: text + foo.method_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text unstable(); foo.method_unstable(); @@ -383,34 +383,34 @@ mod this_crate { <Foo as Trait>::trait_stable_text(&foo); let _ = DeprecatedStruct { - //~^ WARN use of deprecated item 'this_crate::DeprecatedStruct' - i: 0 //~ WARN use of deprecated item 'this_crate::DeprecatedStruct::i' + //~^ WARN use of deprecated struct `this_crate::DeprecatedStruct` + i: 0 //~ WARN use of deprecated field `this_crate::DeprecatedStruct::i` }; let _ = UnstableStruct { i: 0 }; let _ = StableStruct { i: 0 }; - let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item 'this_crate::DeprecatedUnitStruct' + let _ = DeprecatedUnitStruct; //~ WARN use of deprecated unit struct `this_crate::DeprecatedUnitStruct` let _ = UnstableUnitStruct; let _ = StableUnitStruct; - let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item 'this_crate::Enum::DeprecatedVariant' + let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated unit variant `this_crate::Enum::DeprecatedVariant` let _ = Enum::UnstableVariant; let _ = Enum::StableVariant; - let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item 'this_crate::DeprecatedTupleStruct' + let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated tuple struct `this_crate::DeprecatedTupleStruct` let _ = UnstableTupleStruct (1); let _ = StableTupleStruct (1); } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text foo.trait_unstable(); Trait::trait_unstable(&foo); <Foo>::trait_unstable(&foo); @@ -426,8 +426,8 @@ mod this_crate { } fn test_method_object(foo: &dyn Trait) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text foo.trait_unstable(); foo.trait_unstable_text(); foo.trait_stable(); @@ -437,7 +437,7 @@ mod this_crate { #[rustc_deprecated(since = "1.0.0", reason = "text")] fn test_fn_body() { fn fn_in_body() {} - fn_in_body(); //~ WARN use of deprecated item 'this_crate::test_fn_body::fn_in_body': text + fn_in_body(); //~ WARN use of deprecated function `this_crate::test_fn_body::fn_in_body`: text } impl MethodTester { @@ -445,7 +445,7 @@ mod this_crate { #[rustc_deprecated(since = "1.0.0", reason = "text")] fn test_method_body(&self) { fn fn_in_body() {} - fn_in_body(); //~ WARN use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text + fn_in_body(); //~ WARN use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text } } @@ -457,9 +457,9 @@ mod this_crate { struct S; - impl DeprecatedTrait for S { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait' + impl DeprecatedTrait for S { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait` - trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait' + trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait` } fn main() {} diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index 801e04a7f4f..d8dd83b0d06 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'lint_stability::deprecated': text +warning: use of deprecated function `lint_stability::deprecated`: text --> $DIR/lint-stability-deprecated.rs:25:9 | LL | deprecated(); @@ -10,643 +10,643 @@ note: the lint level is defined here LL | #![warn(deprecated)] | ^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:30:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:32:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_text': text +warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:34:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:39:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:41:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_unstable': text +warning: use of deprecated function `lint_stability::deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:43:9 | LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:48:9 | -LL | Trait::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:50:9 | -LL | <Foo as Trait>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text +warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:52:9 | LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:57:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:59:9 | LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text --> $DIR/lint-stability-deprecated.rs:109:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnstableStruct`: text --> $DIR/lint-stability-deprecated.rs:112:17 | LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnitStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnitStruct`: text --> $DIR/lint-stability-deprecated.rs:119:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct`: text --> $DIR/lint-stability-deprecated.rs:120:17 | LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Enum::DeprecatedVariant': text +warning: use of deprecated variant `lint_stability::Enum::DeprecatedVariant`: text --> $DIR/lint-stability-deprecated.rs:124:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant': text +warning: use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`: text --> $DIR/lint-stability-deprecated.rs:125:17 | LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedTupleStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:129:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:130:17 | LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_text': text +warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:139:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text +warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:140:25 | LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_text': text +warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:141:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:146:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:148:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:150:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:152:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:154:9 | -LL | Trait::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:156:9 | -LL | <Foo as Trait>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:158:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:160:9 | LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedTrait': text +warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:188:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedTrait': text +warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:190:25 | LL | trait LocalTrait2 : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text +warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text --> $DIR/lint-stability-deprecated.rs:209:9 | LL | unstable_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::deprecated': text +warning: use of deprecated function `this_crate::deprecated`: text --> $DIR/lint-stability-deprecated.rs:331:9 | LL | deprecated(); | ^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:336:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:338:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::deprecated_text': text +warning: use of deprecated function `this_crate::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:340:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:345:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:347:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedStruct': text +warning: use of deprecated struct `this_crate::DeprecatedStruct`: text --> $DIR/lint-stability-deprecated.rs:385:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedUnitStruct': text +warning: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text --> $DIR/lint-stability-deprecated.rs:392:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text +warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text --> $DIR/lint-stability-deprecated.rs:396:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedTupleStruct': text +warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:400:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:407:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:409:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:411:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:413:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::test_fn_body::fn_in_body': text +warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text --> $DIR/lint-stability-deprecated.rs:440:9 | LL | fn_in_body(); | ^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedTrait': text +warning: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:460:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedTrait': text +warning: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:462:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text +warning: use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text --> $DIR/lint-stability-deprecated.rs:448:13 | LL | fn_in_body(); | ^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:98:48 | LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:26:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:27:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:28:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:29:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:31:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:35:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:36:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:37:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:38:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:40:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:44:13 | -LL | foo.method_deprecated_unstable(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_unstable(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:45:9 | -LL | Foo::method_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:46:9 | -LL | <Foo>::method_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:47:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:49:9 | -LL | <Foo>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:53:13 | LL | ... foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:54:9 | LL | ... Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:55:9 | LL | ... <Foo>::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:56:13 | -LL | foo.trait_deprecated_unstable_text(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.trait_deprecated_unstable_text(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:58:9 | LL | ... <Foo>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text +warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text --> $DIR/lint-stability-deprecated.rs:110:13 | LL | i: 0 | ^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i': text +warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: text --> $DIR/lint-stability-deprecated.rs:114:13 | LL | i: 0 | ^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:145:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:147:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:149:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:151:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:153:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:155:9 | -LL | <Foo>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:157:13 | -LL | foo.trait_deprecated_unstable_text(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.trait_deprecated_unstable_text(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:159:9 | LL | ... <Foo>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:177:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:178:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:179:13 | -LL | foo.trait_deprecated_unstable_text(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.trait_deprecated_unstable_text(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:332:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:333:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:334:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:335:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:337:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:341:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:342:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:343:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:344:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:346:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedStruct::i': text +warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text --> $DIR/lint-stability-deprecated.rs:387:13 | LL | i: 0 | ^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:406:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:408:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:410:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:412:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:429:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:430:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:98:48 | LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.rs b/src/test/ui/lint/lint-stability-fields-deprecated.rs index 50e3970c7f0..14c6383806f 100644 --- a/src/test/ui/lint/lint-stability-fields-deprecated.rs +++ b/src/test/ui/lint/lint-stability-fields-deprecated.rs @@ -16,19 +16,19 @@ mod cross_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; // all fine let Stable { .. } = x; @@ -38,12 +38,12 @@ mod cross_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable2(_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; // all fine let Stable2(..) = x; @@ -53,19 +53,19 @@ mod cross_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Unstable @@ -78,13 +78,13 @@ mod cross_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable2 (_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Unstable2 // the patterns are all fine: @@ -92,58 +92,58 @@ mod cross_crate { let x = Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: 1, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: 2, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Deprecated - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct // the patterns are all fine: { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct let _ = x.0; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct (_, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct // the patterns are all fine: (..) = x; } @@ -203,19 +203,19 @@ mod this_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; // all fine let Stable { .. } = x; @@ -225,12 +225,12 @@ mod this_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable2(_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; // all fine let Stable2(..) = x; @@ -240,19 +240,19 @@ mod this_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Unstable @@ -265,13 +265,13 @@ mod this_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable2 (_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Unstable2 // the patterns are all fine: @@ -279,58 +279,58 @@ mod this_crate { let x = Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: 1, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: 2, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Deprecated - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct // the patterns are all fine: { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated tuple struct let _ = x.0; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated tuple struct (_, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated tuple struct // the patterns are all fine: (..) = x; } diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.stderr b/src/test/ui/lint/lint-stability-fields-deprecated.stderr index 5210fb690e9..ec786786023 100644 --- a/src/test/ui/lint/lint-stability-fields-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-fields-deprecated.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:94:17 | LL | let x = Deprecated { @@ -10,367 +10,367 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:111:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:121:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:126:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:136:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:145:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated': text +error: use of deprecated struct `this_crate::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:281:17 | LL | let x = Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated': text +error: use of deprecated struct `this_crate::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:298:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated': text +error: use of deprecated struct `this_crate::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:308:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2': text +error: use of deprecated tuple struct `this_crate::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:313:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2': text +error: use of deprecated tuple struct `this_crate::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:323:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2': text +error: use of deprecated tuple struct `this_crate::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:332:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:18:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:24:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:30:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:40:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:45:20 | LL | _) | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:55:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:61:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:67:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:80:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:86:14 | LL | _) | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:96:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:98:13 | LL | override1: 2, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:100:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:104:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:106:17 | LL | let _ = x.override1; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:108:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:113:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:115:13 | LL | override1: _, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:117:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::0': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:129:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:131:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:133:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::0': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:138:14 | LL | (_, | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:140:14 | LL | _, | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:142:14 | LL | _) | ^ -error: use of deprecated item 'this_crate::Stable::override2': text +error: use of deprecated field `this_crate::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:205:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Stable::override2': text +error: use of deprecated field `this_crate::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:211:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Stable::override2': text +error: use of deprecated field `this_crate::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:217:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Stable2::2': text +error: use of deprecated field `this_crate::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:227:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate::Stable2::2': text +error: use of deprecated field `this_crate::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:232:20 | LL | _) | ^ -error: use of deprecated item 'this_crate::Unstable::override2': text +error: use of deprecated field `this_crate::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:242:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Unstable::override2': text +error: use of deprecated field `this_crate::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:248:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Unstable::override2': text +error: use of deprecated field `this_crate::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:254:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Unstable2::2': text +error: use of deprecated field `this_crate::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:267:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate::Unstable2::2': text +error: use of deprecated field `this_crate::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:273:14 | LL | _) | ^ -error: use of deprecated item 'this_crate::Deprecated::inherit': text +error: use of deprecated field `this_crate::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:283:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override1': text +error: use of deprecated field `this_crate::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:285:13 | LL | override1: 2, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override2': text +error: use of deprecated field `this_crate::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:287:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::inherit': text +error: use of deprecated field `this_crate::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:291:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override1': text +error: use of deprecated field `this_crate::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:293:17 | LL | let _ = x.override1; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override2': text +error: use of deprecated field `this_crate::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:295:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::inherit': text +error: use of deprecated field `this_crate::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:300:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override1': text +error: use of deprecated field `this_crate::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:302:13 | LL | override1: _, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override2': text +error: use of deprecated field `this_crate::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:304:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2::0': text +error: use of deprecated field `this_crate::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:316:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'this_crate::Deprecated2::1': text +error: use of deprecated field `this_crate::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:318:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'this_crate::Deprecated2::2': text +error: use of deprecated field `this_crate::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:320:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate::Deprecated2::0': text +error: use of deprecated field `this_crate::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:325:14 | LL | (_, | ^ -error: use of deprecated item 'this_crate::Deprecated2::1': text +error: use of deprecated field `this_crate::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:327:14 | LL | _, | ^ -error: use of deprecated item 'this_crate::Deprecated2::2': text +error: use of deprecated field `this_crate::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:329:14 | LL | _) diff --git a/src/test/ui/lint/lint-stability2.rs b/src/test/ui/lint/lint-stability2.rs index 9710d0826c7..9ae23dac61b 100644 --- a/src/test/ui/lint/lint-stability2.rs +++ b/src/test/ui/lint/lint-stability2.rs @@ -1,5 +1,5 @@ // aux-build:lint_stability.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] diff --git a/src/test/ui/lint/lint-stability2.stderr b/src/test/ui/lint/lint-stability2.stderr index a14bf2ec8ca..036304d25f9 100644 --- a/src/test/ui/lint/lint-stability2.stderr +++ b/src/test/ui/lint/lint-stability2.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'lint_stability::deprecated': text +error: use of deprecated function `lint_stability::deprecated`: text --> $DIR/lint-stability2.rs:12:5 | LL | macro_test!(); diff --git a/src/test/ui/lint/lint-stability3.rs b/src/test/ui/lint/lint-stability3.rs index 3d2cc6890b8..4452846ec0a 100644 --- a/src/test/ui/lint/lint-stability3.rs +++ b/src/test/ui/lint/lint-stability3.rs @@ -1,5 +1,5 @@ // aux-build:lint_stability.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] #![allow(warnings)] diff --git a/src/test/ui/lint/lint-stability3.stderr b/src/test/ui/lint/lint-stability3.stderr index 858ac12612c..b89a7df4938 100644 --- a/src/test/ui/lint/lint-stability3.stderr +++ b/src/test/ui/lint/lint-stability3.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'lint_stability::deprecated_text': text +error: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability3.rs:13:5 | LL | macro_test_arg_nested!(deprecated_text); diff --git a/src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs b/src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs new file mode 100644 index 00000000000..ac547293c58 --- /dev/null +++ b/src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs @@ -0,0 +1,12 @@ +// check-pass + +#![deny(unused_braces)] + +fn main() { + let mut a = Some(3); + // Shouldn't warn below `a`. + while let Some(ref mut v) = {a} { + a.as_mut().map(|a| std::mem::swap(a, v)); + break; + } +} diff --git a/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr b/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr index 2f3d48bf039..4d8a8edf4c9 100644 --- a/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr +++ b/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr @@ -17,20 +17,20 @@ LL | / macro_rules! pong { LL | | () => { syntax error }; | | ^^^^^ expected one of 8 possible tokens LL | | } - | |__- in this expansion of `pong!` + | |__- in this expansion of `pong!` (#2) ... LL | ping!(); - | -------- in this macro invocation + | -------- in this macro invocation (#1) | ::: $DIR/auxiliary/ping.rs:5:1 | LL | / macro_rules! ping { LL | | () => { LL | | pong!(); - | | -------- in this macro invocation + | | -------- in this macro invocation (#2) LL | | } LL | | } - | |_- in this expansion of `ping!` + | |_- in this expansion of `ping!` (#1) error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` --> $DIR/main.rs:10:20 diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs index 9636b48c2da..a7f327cf53b 100644 --- a/src/test/ui/macros/macro-deprecation.rs +++ b/src/test/ui/macros/macro-deprecation.rs @@ -8,6 +8,6 @@ macro_rules! local_deprecated{ () => () } fn main() { - local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note - deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note + local_deprecated!(); //~ WARN use of deprecated macro `local_deprecated`: local deprecation note + deprecated_macro!(); //~ WARN use of deprecated macro `deprecated_macro`: deprecation note } diff --git a/src/test/ui/macros/macro-deprecation.stderr b/src/test/ui/macros/macro-deprecation.stderr index 0e8ecb58fe5..07849d7ce57 100644 --- a/src/test/ui/macros/macro-deprecation.stderr +++ b/src/test/ui/macros/macro-deprecation.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'local_deprecated': local deprecation note +warning: use of deprecated macro `local_deprecated`: local deprecation note --> $DIR/macro-deprecation.rs:11:5 | LL | local_deprecated!(); @@ -6,7 +6,7 @@ LL | local_deprecated!(); | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'deprecated_macro': deprecation note +warning: use of deprecated macro `deprecated_macro`: deprecation note --> $DIR/macro-deprecation.rs:12:5 | LL | deprecated_macro!(); diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index 755f55c28de..e2eff7c1c2d 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -22,7 +22,7 @@ fn main() { // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros' deprecated_macro!(); - //~^ WARN use of deprecated item 'deprecated_macro': deprecation reason + //~^ WARN use of deprecated macro `deprecated_macro`: deprecation reason local_deprecated!(); - //~^ WARN use of deprecated item 'local_deprecated': local deprecation reason + //~^ WARN use of deprecated macro `local_deprecated`: local deprecation reason } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index 9e127a3b855..34b62b4b1c3 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -22,7 +22,7 @@ LL | unstable_macro!(); | = help: add `#![feature(unstable_macros)]` to the crate attributes to enable -warning: use of deprecated item 'deprecated_macro': deprecation reason +warning: use of deprecated macro `deprecated_macro`: deprecation reason --> $DIR/macro-stability.rs:24:5 | LL | deprecated_macro!(); @@ -30,7 +30,7 @@ LL | deprecated_macro!(); | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'local_deprecated': local deprecation reason +warning: use of deprecated macro `local_deprecated`: local deprecation reason --> $DIR/macro-stability.rs:26:5 | LL | local_deprecated!(); diff --git a/src/test/ui/pattern/issue-74539.rs b/src/test/ui/pattern/issue-74539.rs new file mode 100644 index 00000000000..0b25f87ec53 --- /dev/null +++ b/src/test/ui/pattern/issue-74539.rs @@ -0,0 +1,15 @@ +enum E { + A(u8, u8), +} + +fn main() { + let e = E::A(2, 3); + match e { + E::A(x @ ..) => { + //~^ ERROR: `x @` is not allowed in a tuple struct + //~| ERROR: `..` patterns are not allowed here + //~| ERROR: this pattern has 1 field, but the corresponding tuple variant has 2 fields + x + } + }; +} diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr new file mode 100644 index 00000000000..cbc90b5397d --- /dev/null +++ b/src/test/ui/pattern/issue-74539.stderr @@ -0,0 +1,32 @@ +error: `x @` is not allowed in a tuple struct + --> $DIR/issue-74539.rs:8:14 + | +LL | E::A(x @ ..) => { + | ^^^^^^ this is only allowed in slice patterns + | + = help: remove this and bind each tuple field independently +help: if you don't need to use the contents of x, discard the tuple's remaining fields + | +LL | E::A(..) => { + | ^^ + +error: `..` patterns are not allowed here + --> $DIR/issue-74539.rs:8:18 + | +LL | E::A(x @ ..) => { + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields + --> $DIR/issue-74539.rs:8:9 + | +LL | A(u8, u8), + | --------- tuple variant defined here +... +LL | E::A(x @ ..) => { + | ^^^^^^^^^^^^ expected 2 fields, found 1 + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0023`. diff --git a/src/test/ui/pattern/issue-74702.rs b/src/test/ui/pattern/issue-74702.rs new file mode 100644 index 00000000000..0aeb3b217a2 --- /dev/null +++ b/src/test/ui/pattern/issue-74702.rs @@ -0,0 +1,7 @@ +fn main() { + let (foo @ ..,) = (0, 0); + //~^ ERROR: `foo @` is not allowed in a tuple + //~| ERROR: `..` patterns are not allowed here + //~| ERROR: mismatched types + dbg!(foo); +} diff --git a/src/test/ui/pattern/issue-74702.stderr b/src/test/ui/pattern/issue-74702.stderr new file mode 100644 index 00000000000..aca5c9aed96 --- /dev/null +++ b/src/test/ui/pattern/issue-74702.stderr @@ -0,0 +1,34 @@ +error: `foo @` is not allowed in a tuple + --> $DIR/issue-74702.rs:2:10 + | +LL | let (foo @ ..,) = (0, 0); + | ^^^^^^^^ this is only allowed in slice patterns + | + = help: remove this and bind each tuple field independently +help: if you don't need to use the contents of foo, discard the tuple's remaining fields + | +LL | let (..,) = (0, 0); + | ^^ + +error: `..` patterns are not allowed here + --> $DIR/issue-74702.rs:2:16 + | +LL | let (foo @ ..,) = (0, 0); + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0308]: mismatched types + --> $DIR/issue-74702.rs:2:9 + | +LL | let (foo @ ..,) = (0, 0); + | ^^^^^^^^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 1 element + | + = note: expected tuple `({integer}, {integer})` + found tuple `(_,)` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/pattern/issue-74954.rs b/src/test/ui/pattern/issue-74954.rs new file mode 100644 index 00000000000..269ec3c7abe --- /dev/null +++ b/src/test/ui/pattern/issue-74954.rs @@ -0,0 +1,7 @@ +// check-pass + +fn main() { + if let Some([b'@', filename @ ..]) = Some(b"@abc123") { + println!("filename {:?}", filename); + } +} diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs index 055781d2c60..c0733c8b416 100644 --- a/src/test/ui/proc-macro/attributes-on-definitions.rs +++ b/src/test/ui/proc-macro/attributes-on-definitions.rs @@ -6,7 +6,7 @@ extern crate attributes_on_definitions; attributes_on_definitions::with_attrs!(); -//~^ WARN use of deprecated item +//~^ WARN use of deprecated // No errors about the use of unstable and unsafe code inside the macro. fn main() {} diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr index 3e6b8f6a435..c63dd00119a 100644 --- a/src/test/ui/proc-macro/attributes-on-definitions.stderr +++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'attributes_on_definitions::with_attrs': test +warning: use of deprecated macro `attributes_on_definitions::with_attrs`: test --> $DIR/attributes-on-definitions.rs:8:1 | LL | attributes_on_definitions::with_attrs!(); diff --git a/src/test/ui/proc-macro/auxiliary/raw-ident.rs b/src/test/ui/proc-macro/auxiliary/raw-ident.rs new file mode 100644 index 00000000000..9daee21aa17 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/raw-ident.rs @@ -0,0 +1,35 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::{TokenStream, TokenTree, Ident, Punct, Spacing, Span}; + +#[proc_macro] +pub fn make_struct(input: TokenStream) -> TokenStream { + match input.into_iter().next().unwrap() { + TokenTree::Ident(ident) => { + vec![ + TokenTree::Ident(Ident::new("struct", Span::call_site())), + TokenTree::Ident(Ident::new_raw(&ident.to_string(), Span::call_site())), + TokenTree::Punct(Punct::new(';', Spacing::Alone)) + ].into_iter().collect() + } + _ => panic!() + } +} + +#[proc_macro] +pub fn make_bad_struct(input: TokenStream) -> TokenStream { + match input.into_iter().next().unwrap() { + TokenTree::Ident(ident) => { + vec![ + TokenTree::Ident(Ident::new_raw("struct", Span::call_site())), + TokenTree::Ident(Ident::new(&ident.to_string(), Span::call_site())), + TokenTree::Punct(Punct::new(';', Spacing::Alone)) + ].into_iter().collect() + } + _ => panic!() + } +} diff --git a/src/test/ui/proc-macro/crt-static.rs b/src/test/ui/proc-macro/crt-static.rs index 97f6265e308..4f11f81b00b 100644 --- a/src/test/ui/proc-macro/crt-static.rs +++ b/src/test/ui/proc-macro/crt-static.rs @@ -1,4 +1,4 @@ -// Test proc-macro crate can be built without addtional RUSTFLAGS +// Test proc-macro crate can be built without additional RUSTFLAGS // on musl target // override -Ctarget-feature=-crt-static from compiletest // compile-flags: -Ctarget-feature= diff --git a/src/test/ui/proc-macro/raw-ident.rs b/src/test/ui/proc-macro/raw-ident.rs new file mode 100644 index 00000000000..03cb4571496 --- /dev/null +++ b/src/test/ui/proc-macro/raw-ident.rs @@ -0,0 +1,16 @@ +// aux-build:raw-ident.rs + +#[macro_use] extern crate raw_ident; + +fn main() { + make_struct!(fn); + make_struct!(Foo); + make_struct!(await); + + r#fn; + r#Foo; + Foo; + r#await; + + make_bad_struct!(S); //~ ERROR expected one of +} diff --git a/src/test/ui/proc-macro/raw-ident.stderr b/src/test/ui/proc-macro/raw-ident.stderr new file mode 100644 index 00000000000..e82a1226b5a --- /dev/null +++ b/src/test/ui/proc-macro/raw-ident.stderr @@ -0,0 +1,10 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `S` + --> $DIR/raw-ident.rs:15:5 + | +LL | make_bad_struct!(S); + | ^^^^^^^^^^^^^^^^^^^^ expected one of 8 possible tokens + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/realloc-16687.rs b/src/test/ui/realloc-16687.rs index 0687a9ce454..bdcd47a7260 100644 --- a/src/test/ui/realloc-16687.rs +++ b/src/test/ui/realloc-16687.rs @@ -5,8 +5,9 @@ // well enough to reproduce (and illustrate) the bug from #16687. #![feature(allocator_api)] +#![feature(slice_ptr_get)] -use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout, ReallocPlacement}; +use std::alloc::{handle_alloc_error, AllocRef, Global, Layout}; use std::ptr::{self, NonNull}; fn main() { @@ -41,15 +42,13 @@ unsafe fn test_triangle() -> bool { println!("allocate({:?})", layout); } - let memory = Global - .alloc(layout, AllocInit::Uninitialized) - .unwrap_or_else(|_| handle_alloc_error(layout)); + let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); if PRINT { - println!("allocate({:?}) = {:?}", layout, memory.ptr); + println!("allocate({:?}) = {:?}", layout, ptr); } - memory.ptr.cast().as_ptr() + ptr.as_non_null_ptr().as_ptr() } unsafe fn deallocate(ptr: *mut u8, layout: Layout) { @@ -70,21 +69,19 @@ unsafe fn test_triangle() -> bool { NonNull::new_unchecked(ptr), old, new.size(), - ReallocPlacement::MayMove, - AllocInit::Uninitialized, ) } else { - Global.shrink(NonNull::new_unchecked(ptr), old, new.size(), ReallocPlacement::MayMove) + Global.shrink(NonNull::new_unchecked(ptr), old, new.size()) }; - let memory = memory.unwrap_or_else(|_| { + let ptr = memory.unwrap_or_else(|_| { handle_alloc_error(Layout::from_size_align_unchecked(new.size(), old.align())) }); if PRINT { - println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, memory.ptr); + println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, ptr); } - memory.ptr.cast().as_ptr() + ptr.as_non_null_ptr().as_ptr() } fn idx_to_size(i: usize) -> usize { diff --git a/src/test/ui/regions/regions-mock-codegen.rs b/src/test/ui/regions/regions-mock-codegen.rs index 380310190be..ad4b9c352ae 100644 --- a/src/test/ui/regions/regions-mock-codegen.rs +++ b/src/test/ui/regions/regions-mock-codegen.rs @@ -4,7 +4,7 @@ // pretty-expanded FIXME #23616 #![feature(allocator_api)] -use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout}; +use std::alloc::{handle_alloc_error, AllocRef, Global, Layout}; use std::ptr::NonNull; struct arena(()); @@ -25,10 +25,8 @@ struct Ccx { fn alloc(_bcx: &arena) -> &Bcx<'_> { unsafe { let layout = Layout::new::<Bcx>(); - let memory = Global - .alloc(layout, AllocInit::Uninitialized) - .unwrap_or_else(|_| handle_alloc_error(layout)); - &*(memory.ptr.as_ptr() as *const _) + let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + &*(ptr.as_ptr() as *const _) } } diff --git a/src/test/ui/rfc-2091-track-caller/error-with-main.rs b/src/test/ui/rfc-2091-track-caller/error-with-main.rs new file mode 100644 index 00000000000..b2ea31bb517 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-main.rs @@ -0,0 +1,4 @@ +#[track_caller] //~ ERROR `main` function is not allowed to be +fn main() { + panic!("{}: oh no", std::panic::Location::caller()); +} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-main.stderr b/src/test/ui/rfc-2091-track-caller/error-with-main.stderr new file mode 100644 index 00000000000..f05f88e7d71 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-main.stderr @@ -0,0 +1,12 @@ +error: `main` function is not allowed to be `#[track_caller]` + --> $DIR/error-with-main.rs:1:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | / fn main() { +LL | | panic!("{}: oh no", std::panic::Location::caller()); +LL | | } + | |_- `main` function is not allowed to be `#[track_caller]` + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2091-track-caller/error-with-start.rs b/src/test/ui/rfc-2091-track-caller/error-with-start.rs new file mode 100644 index 00000000000..0cab4717063 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-start.rs @@ -0,0 +1,7 @@ +#![feature(start)] + +#[start] +#[track_caller] //~ ERROR `start` is not allowed to be `#[track_caller]` +fn start(_argc: isize, _argv: *const *const u8) -> isize { + panic!("{}: oh no", std::panic::Location::caller()); +} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-start.stderr b/src/test/ui/rfc-2091-track-caller/error-with-start.stderr new file mode 100644 index 00000000000..1a1f3e04491 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-start.stderr @@ -0,0 +1,12 @@ +error: `start` is not allowed to be `#[track_caller]` + --> $DIR/error-with-start.rs:4:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | / fn start(_argc: isize, _argv: *const *const u8) -> isize { +LL | | panic!("{}: oh no", std::panic::Location::caller()); +LL | | } + | |_- `start` is not allowed to be `#[track_caller]` + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index 35a2956ee26..d6a3a760b3e 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -7,8 +7,10 @@ //! Test that panic locations for `#[track_caller]` functions in std have the correct //! location reported. +use std::cell::RefCell; use std::collections::{BTreeMap, HashMap, VecDeque}; use std::ops::{Index, IndexMut}; +use std::panic::{AssertUnwindSafe, UnwindSafe}; fn main() { // inspect the `PanicInfo` we receive to ensure the right file is the source @@ -20,7 +22,7 @@ fn main() { } })); - fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) { + fn assert_panicked(f: impl FnOnce() + UnwindSafe) { std::panic::catch_unwind(f).unwrap_err(); } @@ -57,4 +59,9 @@ fn main() { let weirdo: VecDeque<()> = Default::default(); assert_panicked(|| { weirdo.index(1); }); assert_panicked(|| { weirdo[1]; }); + + let refcell: RefCell<()> = Default::default(); + let _conflicting = refcell.borrow_mut(); + assert_panicked(AssertUnwindSafe(|| { refcell.borrow(); })); + assert_panicked(AssertUnwindSafe(|| { refcell.borrow_mut(); })); } diff --git a/src/test/ui/suggestions/issue-61226.fixed b/src/test/ui/suggestions/issue-61226.fixed new file mode 100644 index 00000000000..6e9d74344bc --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.fixed @@ -0,0 +1,6 @@ +// run-rustfix +struct X {} +fn main() { + let _ = vec![X {}]; //… + //~^ ERROR expected value, found struct `X` +} diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs index e83b0b4d630..695fe73418a 100644 --- a/src/test/ui/suggestions/issue-61226.rs +++ b/src/test/ui/suggestions/issue-61226.rs @@ -1,5 +1,6 @@ +// run-rustfix struct X {} fn main() { - vec![X]; //… + let _ = vec![X]; //… //~^ ERROR expected value, found struct `X` } diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr index 7f6f082d7a8..cda962a9045 100644 --- a/src/test/ui/suggestions/issue-61226.stderr +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -1,11 +1,11 @@ error[E0423]: expected value, found struct `X` - --> $DIR/issue-61226.rs:3:10 + --> $DIR/issue-61226.rs:4:18 | LL | struct X {} | ----------- `X` defined here LL | fn main() { -LL | vec![X]; //… - | ^ help: use struct literal syntax instead: `X {}` +LL | let _ = vec![X]; //… + | ^ help: use struct literal syntax instead: `X {}` error: aborting due to previous error diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.fixed b/src/test/ui/suggestions/type-ascription-instead-of-method.fixed new file mode 100644 index 00000000000..56b740b0d5c --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = Box::new("foo".to_string()); + //~^ ERROR expected type, found +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.rs b/src/test/ui/suggestions/type-ascription-instead-of-method.rs index 361729d50c2..a603e09e7e8 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-method.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.rs @@ -1,4 +1,5 @@ +// run-rustfix fn main() { - Box:new("foo".to_string()) + let _ = Box:new("foo".to_string()); //~^ ERROR expected type, found } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr index c111b4a9bc7..83bc33f410a 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr @@ -1,10 +1,10 @@ error: expected type, found `"foo"` - --> $DIR/type-ascription-instead-of-method.rs:2:13 + --> $DIR/type-ascription-instead-of-method.rs:3:21 | -LL | Box:new("foo".to_string()) - | - ^^^^^ expected type - | | - | help: maybe write a path separator here: `::` +LL | let _ = Box:new("foo".to_string()); + | - ^^^^^ expected type + | | + | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed b/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed new file mode 100644 index 00000000000..787fcc1208e --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed @@ -0,0 +1,6 @@ +// run-rustfix +fn main() -> Result<(), ()> { + let _ = vec![Ok(2)].into_iter().collect::<Result<Vec<_>,_>>()?; + //~^ ERROR expected `::`, found `(` + Ok(()) +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs index 220fd1eebda..934016b3b81 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs @@ -1,5 +1,6 @@ +// run-rustfix fn main() -> Result<(), ()> { - vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; + let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; //~^ ERROR expected `::`, found `(` Ok(()) } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr index 1d1999d350f..970b220b737 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr @@ -1,10 +1,10 @@ error: expected `::`, found `(` - --> $DIR/type-ascription-instead-of-path-2.rs:2:55 + --> $DIR/type-ascription-instead-of-path-2.rs:3:63 | -LL | vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; - | - ^ expected `::` - | | - | help: maybe write a path separator here: `::` +LL | let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; + | - ^ expected `::` + | | + | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed b/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed new file mode 100644 index 00000000000..b3247e1287d --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = Option::Some(""); + //~^ ERROR expected type, found +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs index b90867fef6b..6fd2c19541c 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs @@ -1,3 +1,4 @@ +// run-rustfix fn main() { let _ = Option:Some(""); //~^ ERROR expected type, found diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr index f38020dcc38..f59ba78d4d3 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr @@ -1,5 +1,5 @@ error: expected type, found `""` - --> $DIR/type-ascription-instead-of-variant.rs:2:25 + --> $DIR/type-ascription-instead-of-variant.rs:3:25 | LL | let _ = Option:Some(""); | - ^^ expected type diff --git a/src/test/ui/type/ascription/issue-47666.fixed b/src/test/ui/type/ascription/issue-47666.fixed new file mode 100644 index 00000000000..c4db747551e --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.fixed @@ -0,0 +1,4 @@ +// run-rustfix +fn main() { + let _ = Option::Some(vec![0, 1]); //~ ERROR expected type, found +} diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs index 8035de4a48a..c67202e2157 100644 --- a/src/test/ui/type/ascription/issue-47666.rs +++ b/src/test/ui/type/ascription/issue-47666.rs @@ -1,7 +1,4 @@ +// run-rustfix fn main() { let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found - //~^ ERROR expected value, found enum `Option` - //~| ERROR expected type, found variant `Some` } - -// This case isn't currently being handled gracefully due to the macro invocation. diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr index 72c7c144b53..ba393ff1a20 100644 --- a/src/test/ui/type/ascription/issue-47666.stderr +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -1,5 +1,5 @@ error: expected type, found reserved keyword `box` - --> $DIR/issue-47666.rs:2:25 + --> $DIR/issue-47666.rs:3:25 | LL | let _ = Option:Some(vec![0, 1]); | - ^^^^^^^^^^ @@ -12,35 +12,5 @@ LL | let _ = Option:Some(vec![0, 1]); = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0423]: expected value, found enum `Option` - --> $DIR/issue-47666.rs:2:13 - | -LL | let _ = Option:Some(vec![0, 1]); - | ^^^^^^ - | -help: try using one of the enum's variants - | -LL | let _ = std::option::Option::None:Some(vec![0, 1]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | let _ = std::option::Option::Some:Some(vec![0, 1]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0573]: expected type, found variant `Some` - --> $DIR/issue-47666.rs:2:20 - | -LL | let _ = Option:Some(vec![0, 1]); - | ^^^^^^^^^^^^^^^^ not a type - | -help: try using the variant's enum - | -LL | let _ = Option:std::option::Option; - | ^^^^^^^^^^^^^^^^^^^ -help: maybe you meant to write a path separator here - | -LL | let _ = Option::Some(vec![0, 1]); - | ^^ - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0423, E0573. -For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/type/ascription/issue-54516.fixed b/src/test/ui/type/ascription/issue-54516.fixed new file mode 100644 index 00000000000..181637b97bb --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.fixed @@ -0,0 +1,7 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem::size_of::<BTreeMap<u32, u32>>()); + //~^ ERROR casts cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs index 8d6fd2abb6d..f09ddd487d8 100644 --- a/src/test/ui/type/ascription/issue-54516.rs +++ b/src/test/ui/type/ascription/issue-54516.rs @@ -1,8 +1,7 @@ +// run-rustfix use std::collections::BTreeMap; fn main() { println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); //~^ ERROR casts cannot be followed by a function call - //~| ERROR expected value, found module `std::mem` [E0423] - //~| ERROR cannot find type `size_of` in this scope [E0412] } diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr index ec08cf209c2..2c7ff6bdc48 100644 --- a/src/test/ui/type/ascription/issue-54516.stderr +++ b/src/test/ui/type/ascription/issue-54516.stderr @@ -1,5 +1,5 @@ error: casts cannot be followed by a function call - --> $DIR/issue-54516.rs:4:20 + --> $DIR/issue-54516.rs:5:20 | LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); | ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,23 +8,5 @@ LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` -error[E0423]: expected value, found module `std::mem` - --> $DIR/issue-54516.rs:4:20 - | -LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); - | ^^^^^^^^- help: maybe you meant to write a path separator here: `::` - | | - | not a value - -error[E0412]: cannot find type `size_of` in this scope - --> $DIR/issue-54516.rs:4:29 - | -LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); - | -^^^^^^^ not found in this scope - | | - | help: maybe you meant to write a path separator here: `::` - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0412, E0423. -For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/type/ascription/issue-60933.fixed b/src/test/ui/type/ascription/issue-60933.fixed new file mode 100644 index 00000000000..ac9f6a07031 --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _: usize = std::mem::size_of::<u32>(); + //~^ ERROR casts cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs index bcf9f88cb41..cb093735efa 100644 --- a/src/test/ui/type/ascription/issue-60933.rs +++ b/src/test/ui/type/ascription/issue-60933.rs @@ -1,6 +1,5 @@ +// run-rustfix fn main() { - let u: usize = std::mem:size_of::<u32>(); + let _: usize = std::mem:size_of::<u32>(); //~^ ERROR casts cannot be followed by a function call - //~| ERROR expected value, found module `std::mem` [E0423] - //~| ERROR cannot find type `size_of` in this scope [E0412] } diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr index 2006362e1bb..5c35de88e14 100644 --- a/src/test/ui/type/ascription/issue-60933.stderr +++ b/src/test/ui/type/ascription/issue-60933.stderr @@ -1,30 +1,12 @@ error: casts cannot be followed by a function call - --> $DIR/issue-60933.rs:2:20 + --> $DIR/issue-60933.rs:3:20 | -LL | let u: usize = std::mem:size_of::<u32>(); +LL | let _: usize = std::mem:size_of::<u32>(); | ^^^^^^^^-^^^^^^^^^^^^^^ | | | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` -error[E0423]: expected value, found module `std::mem` - --> $DIR/issue-60933.rs:2:20 - | -LL | let u: usize = std::mem:size_of::<u32>(); - | ^^^^^^^^- help: maybe you meant to write a path separator here: `::` - | | - | not a value - -error[E0412]: cannot find type `size_of` in this scope - --> $DIR/issue-60933.rs:2:29 - | -LL | let u: usize = std::mem:size_of::<u32>(); - | -^^^^^^^ not found in this scope - | | - | help: maybe you meant to write a path separator here: `::` - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0412, E0423. -For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/type/type-ascription-with-fn-call.fixed b/src/test/ui/type/type-ascription-with-fn-call.fixed new file mode 100644 index 00000000000..6d96c4303c3 --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.fixed @@ -0,0 +1,9 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() ; + f(); //~ ERROR expected type, found function +} + +fn f() {} diff --git a/src/test/ui/type/type-ascription-with-fn-call.rs b/src/test/ui/type/type-ascription-with-fn-call.rs index 2bd2efa4d38..ed4f7c9041c 100644 --- a/src/test/ui/type/type-ascription-with-fn-call.rs +++ b/src/test/ui/type/type-ascription-with-fn-call.rs @@ -1,3 +1,4 @@ +// run-rustfix #![feature(type_ascription)] fn main() { diff --git a/src/test/ui/type/type-ascription-with-fn-call.stderr b/src/test/ui/type/type-ascription-with-fn-call.stderr index eeaca5300f9..5f74724b59e 100644 --- a/src/test/ui/type/type-ascription-with-fn-call.stderr +++ b/src/test/ui/type/type-ascription-with-fn-call.stderr @@ -1,8 +1,8 @@ error[E0573]: expected type, found function `f` - --> $DIR/type-ascription-with-fn-call.rs:5:5 + --> $DIR/type-ascription-with-fn-call.rs:6:5 | LL | f() : - | - help: did you mean to use `;` here instead? + | - help: maybe you meant to write `;` here LL | f(); | ^^^ | | diff --git a/src/test/ui/warn-path-statement.rs b/src/test/ui/warn-path-statement.rs index e8525f8b892..2435be623f3 100644 --- a/src/test/ui/warn-path-statement.rs +++ b/src/test/ui/warn-path-statement.rs @@ -1,6 +1,17 @@ // compile-flags: -D path-statements -fn main() { +struct Droppy; + +impl Drop for Droppy { + fn drop(&mut self) {} +} +fn main() { let x = 10; x; //~ ERROR path statement with no effect + + let y = Droppy; + y; //~ ERROR path statement drops value + + let z = (Droppy,); + z; //~ ERROR path statement drops value } diff --git a/src/test/ui/warn-path-statement.stderr b/src/test/ui/warn-path-statement.stderr index 30afb99e5f0..248d2ef299b 100644 --- a/src/test/ui/warn-path-statement.stderr +++ b/src/test/ui/warn-path-statement.stderr @@ -1,10 +1,22 @@ error: path statement with no effect - --> $DIR/warn-path-statement.rs:5:5 + --> $DIR/warn-path-statement.rs:10:5 | LL | x; | ^^ | = note: requested on the command line with `-D path-statements` -error: aborting due to previous error +error: path statement drops value + --> $DIR/warn-path-statement.rs:13:5 + | +LL | y; + | ^^ help: use `drop` to clarify the intent: `drop(y);` + +error: path statement drops value + --> $DIR/warn-path-statement.rs:16:5 + | +LL | z; + | ^^ help: use `drop` to clarify the intent: `drop(z);` + +error: aborting due to 3 previous errors diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 6ac89f2b1b8..5dede95a858 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -156,6 +156,7 @@ static DOCS_TARGETS: &[&str] = &[ "x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", ]; static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"]; diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 2d5c2381e4e50484bf281fc1bfe19743aa9eb37 +Subproject 1653f354644834073d6d2541e27fae94588e685 diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index 27a7fa88622..40af6bb3d7b 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -286,14 +286,14 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { }, _ => {}, } - if items.is_empty() || !attr.check_name(sym!(deprecated)) { + if items.is_empty() || !attr.has_name(sym!(deprecated)) { return; } for item in items { if_chain! { if let NestedMetaItem::MetaItem(mi) = &item; if let MetaItemKind::NameValue(lit) = &mi.kind; - if mi.check_name(sym!(since)); + if mi.has_name(sym!(since)); then { check_semver(cx, item.span(), lit); } @@ -309,7 +309,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { } match item.kind { ItemKind::ExternCrate(..) | ItemKind::Use(..) => { - let skip_unused_imports = item.attrs.iter().any(|attr| attr.check_name(sym!(macro_use))); + let skip_unused_imports = item.attrs.iter().any(|attr| attr.has_name(sym!(macro_use))); for attr in item.attrs { if in_external_macro(cx.sess(), attr.span) { @@ -524,7 +524,7 @@ fn check_attrs(cx: &LateContext<'_>, span: Span, name: Name, attrs: &[Attribute] for attr in attrs { if let Some(values) = attr.meta_item_list() { - if values.len() != 1 || !attr.check_name(sym!(inline)) { + if values.len() != 1 || !attr.has_name(sym!(inline)) { continue; } if is_word(&values[0], sym!(always)) { @@ -558,7 +558,7 @@ fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) { fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool { if let NestedMetaItem::MetaItem(mi) = &nmi { - mi.is_word() && mi.check_name(expected) + mi.is_word() && mi.has_name(expected) } else { false } @@ -618,15 +618,15 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::as fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute) { if_chain! { // check cfg_attr - if attr.check_name(sym!(cfg_attr)); + if attr.has_name(sym!(cfg_attr)); if let Some(items) = attr.meta_item_list(); if items.len() == 2; // check for `rustfmt` if let Some(feature_item) = items[0].meta_item(); - if feature_item.check_name(sym!(rustfmt)); + if feature_item.has_name(sym!(rustfmt)); // check for `rustfmt_skip` and `rustfmt::skip` if let Some(skip_item) = &items[1].meta_item(); - if skip_item.check_name(sym!(rustfmt_skip)) || + if skip_item.has_name(sym!(rustfmt_skip)) || skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym!(skip); // Only lint outer attributes, because custom inner attributes are unstable // Tracking issue: https://github.com/rust-lang/rust/issues/54726 @@ -685,7 +685,7 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) { } if_chain! { - if attr.check_name(sym!(cfg)); + if attr.has_name(sym!(cfg)); if let Some(list) = attr.meta_item_list(); let mismatched = find_mismatched_target_os(&list); if !mismatched.is_empty(); diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index d52bb8961fa..e87c33d1b09 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -323,7 +323,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs let (comment, current_spans) = strip_doc_comment_decoration(&comment, attr.span); spans.extend_from_slice(¤t_spans); doc.push_str(&comment); - } else if attr.check_name(sym!(doc)) { + } else if attr.has_name(sym!(doc)) { // ignore mix of sugared and non-sugared doc // don't trigger the safety or errors check return DocHeaders { diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs index decbee27815..4b605fdb366 100644 --- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs +++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { fn check_attrs(cx: &LateContext<'_>, name: Symbol, attrs: &[Attribute]) { for attr in attrs { - if !attr.check_name(sym!(inline)) { + if !attr.has_name(sym!(inline)) { continue; } diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index f3b8902e26f..ca1381852da 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -83,7 +83,7 @@ fn check_manual_non_exhaustive_enum(cx: &EarlyContext<'_>, item: &Item, variants } fn is_doc_hidden(attr: &Attribute) -> bool { - attr.check_name(sym!(doc)) + attr.has_name(sym!(doc)) && match attr.meta_item_list() { Some(l) => attr::list_contains_name(&l, sym!(hidden)), None => false, diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 06e0f43c10b..813f9c43948 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn enter_lint_attrs(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { - attr.check_name(sym!(doc)) + attr.has_name(sym!(doc)) && match attr.meta_item_list() { None => false, Some(l) => attr::list_contains_name(&l[..], sym!(hidden)), diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 9c962673537..3eae45b2819 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -57,7 +57,7 @@ declare_clippy_lint! { } fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { - let has_inline = attrs.iter().any(|a| a.check_name(sym!(inline))); + let has_inline = attrs.iter().any(|a| a.has_name(sym!(inline))); if !has_inline { span_lint( cx, diff --git a/src/tools/clippy/clippy_lints/src/needless_borrow.rs b/src/tools/clippy/clippy_lints/src/needless_borrow.rs index 415ab556c9f..9391049c6e8 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrow.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrow.rs @@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow { } fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if item.attrs.iter().any(|a| a.check_name(sym!(automatically_derived))) { + if item.attrs.iter().any(|a| a.has_name(sym!(automatically_derived))) { debug_assert!(self.derived_item.is_none()); self.derived_item = Some(item.hir_id); } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 09577877744..a7f7c97fc48 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -312,7 +312,7 @@ fn requires_exact_signature(attrs: &[Attribute]) -> bool { attrs.iter().any(|attr| { [sym!(proc_macro), sym!(proc_macro_attribute), sym!(proc_macro_derive)] .iter() - .any(|&allow| attr.check_name(allow)) + .any(|&allow| attr.has_name(allow)) }) } diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index faef7e724dd..8ed20995a70 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -235,7 +235,7 @@ impl EarlyLintPass for Return { } fn attr_is_cfg(attr: &ast::Attribute) -> bool { - attr.meta_item_list().is_some() && attr.check_name(sym!(cfg)) + attr.meta_item_list().is_some() && attr.has_name(sym!(cfg)) } // get the def site diff --git a/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs b/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs index 6a2b05e3e6d..7948d99162b 100644 --- a/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -155,7 +155,7 @@ impl<'tcx> LateLintPass<'tcx> for TriviallyCopyPassByRef { return; } for a in attrs { - if a.meta_item_list().is_some() && a.check_name(sym!(proc_macro_derive)) { + if a.meta_item_list().is_some() && a.has_name(sym!(proc_macro_derive)) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs index de425211e38..ba3492a6fff 100644 --- a/src/tools/clippy/clippy_lints/src/utils/conf.rs +++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs @@ -13,7 +13,7 @@ use std::{env, fmt, fs, io}; /// Gets the configuration file from arguments. pub fn file_from_args(args: &[NestedMetaItem]) -> Result<Option<PathBuf>, (&'static str, Span)> { for arg in args.iter().filter_map(NestedMetaItem::meta_item) { - if arg.check_name(sym!(conf_file)) { + if arg.has_name(sym!(conf_file)) { return match arg.kind { MetaItemKind::Word | MetaItemKind::List(_) => Err(("`conf_file` must be a named value", arg.span)), MetaItemKind::NameValue(ref value) => { diff --git a/src/tools/clippy/tests/ui/formatting.rs b/src/tools/clippy/tests/ui/formatting.rs index 078811b8d88..f54b3f2bfe2 100644 --- a/src/tools/clippy/tests/ui/formatting.rs +++ b/src/tools/clippy/tests/ui/formatting.rs @@ -149,7 +149,7 @@ fn main() { 1 + 2, 3 - 4, 5 ]; - // lint if it doesnt + // lint if it doesn't let _ = &[ -1 -4, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 2ab764eb920..047fbe9da14 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use std::env; use std::fs::File; use std::io::prelude::*; @@ -186,6 +187,17 @@ impl EarlyProps { if config.system_llvm && line.starts_with("no-system-llvm") { return true; } + if let Some(needed_components) = + config.parse_name_value_directive(line, "needs-llvm-components") + { + let components: HashSet<_> = config.llvm_components.split_whitespace().collect(); + if !needed_components + .split_whitespace() + .all(|needed_component| components.contains(needed_component)) + { + return true; + } + } if let Some(actual_version) = config.llvm_version { if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) { let min_version = extract_llvm_version(rest).unwrap(); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 9354cc16a9a..940e16720f6 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -178,27 +178,30 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma results } -fn print_diff(expected: &str, actual: &str, context_size: usize) { +fn write_diff(expected: &str, actual: &str, context_size: usize) -> String { + use std::fmt::Write; + let mut output = String::new(); let diff_results = make_diff(expected, actual, context_size); for result in diff_results { let mut line_number = result.line_number; for line in result.lines { match line { DiffLine::Expected(e) => { - println!("-\t{}", e); + writeln!(output, "-\t{}", e).unwrap(); line_number += 1; } DiffLine::Context(c) => { - println!("{}\t{}", line_number, c); + writeln!(output, "{}\t{}", line_number, c).unwrap(); line_number += 1; } DiffLine::Resulting(r) => { - println!("+\t{}", r); + writeln!(output, "+\t{}", r).unwrap(); } } } - println!(); + writeln!(output, "").unwrap(); } + output } pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) { @@ -655,8 +658,12 @@ impl<'test> TestCx<'test> { ------------------------------------------\n\ {}\n\ ------------------------------------------\n\ - \n", - expected, actual + diff:\n\ + ------------------------------------------\n\ + {}\n", + expected, + actual, + write_diff(expected, actual, 3), )); } } @@ -3227,7 +3234,7 @@ impl<'test> TestCx<'test> { } let expected_string = fs::read_to_string(&expected_file).unwrap(); if dumped_string != expected_string { - print_diff(&expected_string, &dumped_string, 3); + print!("{}", write_diff(&expected_string, &dumped_string, 3)); panic!( "Actual MIR output differs from expected MIR output {}", expected_file.display() @@ -3452,7 +3459,7 @@ impl<'test> TestCx<'test> { println!("normalized {}:\n{}\n", kind, actual); } else { println!("diff of {}:\n", kind); - print_diff(expected, actual, 3); + print!("{}", write_diff(expected, actual, 3)); } } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 55e17466a88..1f988f7d81b 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -138,7 +138,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "rand_chacha", "rand_core", "rand_hc", - "rand_isaac", "rand_pcg", "rand_xorshift", "redox_syscall", |
