diff options
566 files changed, 7461 insertions, 3564 deletions
diff --git a/Cargo.lock b/Cargo.lock index d4b7253feb5..f9ad78e3795 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,9 +26,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" dependencies = [ "cfg-if", "once_cell", @@ -49,18 +49,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" -dependencies = [ - "memchr", -] - -[[package]] -name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -77,9 +68,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "ammonia" @@ -111,9 +102,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36" +checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e" dependencies = [ "unicode-width", "yansi-term", @@ -168,26 +159,26 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -212,9 +203,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" dependencies = [ "backtrace", ] @@ -257,7 +248,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -298,15 +289,15 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "basic-toml" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" dependencies = [ "serde", ] @@ -328,9 +319,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block-buffer" @@ -343,13 +334,12 @@ dependencies = [ [[package]] name = "bstr" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" dependencies = [ "memchr", - "once_cell", - "regex-automata 0.1.10", + "regex-automata 0.3.7", "serde", ] @@ -391,15 +381,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecount" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad152d03a2c813c80bb94fedbf3a3f02b28f793e39e7c214c8a0bcc196343de7" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" dependencies = [ "packed_simd", ] @@ -412,15 +402,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "camino" -version = "1.1.4" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" dependencies = [ "serde", ] @@ -429,7 +419,7 @@ dependencies = [ name = "cargo-miri" version = "0.1.0" dependencies = [ - "cargo_metadata 0.18.0", + "cargo_metadata 0.18.1", "directories", "rustc-build-sysroot", "rustc_tools_util", @@ -440,9 +430,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -463,9 +453,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb9ac64500cc83ce4b9f8dafa78186aa008c8dea77a09b94cd307fd0cd5022a8" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", @@ -497,15 +487,15 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "winapi", + "windows-targets 0.52.0", ] [[package]] @@ -520,9 +510,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.4" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" dependencies = [ "clap_builder", "clap_derive", @@ -540,43 +530,43 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" dependencies = [ - "anstream 0.5.0", + "anstream 0.6.11", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.0", "terminal_size", ] [[package]] name = "clap_complete" -version = "4.4.4" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" +checksum = "299353be8209bd133b049bf1c63582d184a8b39fd9c04f15fe65f50f88bdfe6c" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clippy" @@ -596,12 +586,12 @@ dependencies = [ "regex", "rustc_tools_util", "serde", - "syn 2.0.32", + "syn 2.0.48", "tempfile", "termize", "tester", "tokio", - "toml 0.7.5", + "toml 0.7.8", "ui_test", "walkdir", ] @@ -612,7 +602,7 @@ version = "0.1.78" dependencies = [ "rustc-semver", "serde", - "toml 0.7.5", + "toml 0.7.8", "walkdir", ] @@ -620,7 +610,7 @@ dependencies = [ name = "clippy_dev" version = "0.0.1" dependencies = [ - "aho-corasick 1.0.2", + "aho-corasick", "clap", "indoc", "itertools", @@ -634,7 +624,7 @@ name = "clippy_lints" version = "0.1.78" dependencies = [ "arrayvec", - "cargo_metadata 0.18.0", + "cargo_metadata 0.18.1", "clippy_config", "clippy_utils", "declare_clippy_lint", @@ -647,7 +637,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "toml 0.7.5", + "toml 0.7.8", "unicode-normalization", "unicode-script", "url", @@ -712,9 +702,9 @@ dependencies = [ [[package]] name = "color-spantrace" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" dependencies = [ "once_cell", "owo-colors", @@ -730,11 +720,10 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] @@ -785,15 +774,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -812,9 +801,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -822,9 +811,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "coverage-dump" @@ -840,64 +829,55 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -921,9 +901,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", @@ -931,14 +911,14 @@ dependencies = [ "openssl-sys", "schannel", "socket2", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.63+curl-8.1.2" +version = "0.4.72+curl-8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc" +checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" dependencies = [ "cc", "libc", @@ -946,7 +926,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -961,12 +941,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.5", + "darling_macro 0.20.5", ] [[package]] @@ -979,22 +959,22 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim", - "syn 2.0.32", + "strsim 0.10.0", + "syn 2.0.48", ] [[package]] @@ -1010,13 +990,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77" dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.5", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -1031,7 +1011,16 @@ version = "0.1.78" dependencies = [ "itertools", "quote", - "syn 2.0.32", + "syn 2.0.48", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", ] [[package]] @@ -1095,10 +1084,10 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.20.3", + "darling 0.20.5", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -1187,31 +1176,33 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] name = "dissimilar" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210ec60ae7d710bed8683e333e9d2855a8a56a3e9892b38bad3bb0d4d29b0d5e" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" [[package]] name = "dlmalloc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a" +checksum = "960a02b0caee913a3df97cd43fcc7370d0695c1dfcd9aca2af3bb9e96c0acd80" dependencies = [ + "cfg-if", "compiler_builtins", "libc", "rustc-std-workspace-core", + "windows-sys 0.52.0", ] [[package]] name = "either" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elasticlunr-rs" @@ -1251,9 +1242,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -1270,9 +1261,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1283,9 +1274,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e7cf40684ae96ade6232ed84582f40ce0a66efcd43a5117aef610534f8e0b8" +checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" dependencies = [ "anstream 0.6.11", "anstyle", @@ -1296,18 +1287,18 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1337,9 +1328,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1353,9 +1344,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "field-offset" @@ -1369,21 +1360,21 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.21" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.2.16", - "windows-sys 0.48.0", + "redox_syscall", + "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -1446,9 +1437,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1465,9 +1456,12 @@ dependencies = [ [[package]] name = "fs-err" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] name = "fs_extra" @@ -1487,9 +1481,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1502,9 +1496,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1512,15 +1506,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1529,38 +1523,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1613,9 +1607,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -1624,9 +1618,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "compiler_builtins", "fallible-iterator", @@ -1644,11 +1638,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" dependencies = [ - "aho-corasick 0.7.20", + "aho-corasick", "bstr", "fnv", "log", @@ -1666,9 +1660,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -1718,9 +1712,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", @@ -1735,11 +1729,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1766,9 +1760,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1777,9 +1771,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1794,9 +1788,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humansize" @@ -1815,9 +1809,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.22" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1852,16 +1846,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1875,9 +1869,9 @@ dependencies = [ [[package]] name = "icu_list" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1a44bbed77a7e7b555f9d7dd4b43f75ec1402b438a901d20451943d50cbd90" +checksum = "fe6c04ec71ad1bacdbfb47164d4801f80a0533d9340f94f1a880f521eff59f54" dependencies = [ "displaydoc", "icu_list_data", @@ -1889,15 +1883,15 @@ dependencies = [ [[package]] name = "icu_list_data" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3237583f0cb7feafabb567c4492fe9ef1d2d4113f6a8798a923273ea5de996d" +checksum = "42f6afcf7a9a7fedece70b7f17d7a7ecdfb8df145d37ae46d0277cd1e3932532" [[package]] name = "icu_locid" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f284eb342dc49d3e9d9f3b188489d76b5d22dfb1d1a5e0d1941811253bac625c" +checksum = "5c0aa2536adc14c07e2a521e95512b75ed8ef832f0fdf9299d4a0a45d2be2a9d" dependencies = [ "displaydoc", "litemap", @@ -1908,9 +1902,9 @@ dependencies = [ [[package]] name = "icu_locid_transform" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6551daf80882d8e68eee186cc19e132d8bde1b1f059a79b93384a5ca0e8fc5e7" +checksum = "57c17d8f6524fdca4471101dd71f0a132eb6382b5d6d7f2970441cb25f6f435a" dependencies = [ "displaydoc", "icu_locid", @@ -1922,15 +1916,15 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a741eba5431f75eb2f1f9022d3cffabcadda6771e54fb4e77c8ba8653e4da44" +checksum = "545c6c3e8bf9580e2dafee8de6f9ec14826aaf359787789c7724f1f85f47d3dc" [[package]] name = "icu_provider" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68acdef80034b5e35d8524e9817479d389a4f9774f3f0cbe1bf3884d80fd5934" +checksum = "ba58e782287eb6950247abbf11719f83f5d4e4a5c1f2cd490d30a334bc47c2f4" dependencies = [ "displaydoc", "icu_locid", @@ -1945,9 +1939,9 @@ dependencies = [ [[package]] name = "icu_provider_adapters" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b380ef2d3d93b015cd0563d7e0d005cc07f82a5503716dbc191798d0079e1d" +checksum = "a229f978260da7c3aabb68cb7dc7316589936680570fe55e50fdd3f97711a4dd" dependencies = [ "icu_locid", "icu_locid_transform", @@ -1958,13 +1952,13 @@ dependencies = [ [[package]] name = "icu_provider_macros" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2060258edfcfe32ca7058849bf0f146cb5c59aadbedf480333c0d0002f97bc99" +checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -1975,9 +1969,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2014,9 +2008,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown", @@ -2026,9 +2020,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.6" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -2095,19 +2089,19 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.2" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.8" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix", - "windows-sys 0.48.0", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -2121,9 +2115,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jemalloc-sys" @@ -2146,9 +2140,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -2254,15 +2248,26 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] [[package]] name = "libz-sys" -version = "1.1.9" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "libc", @@ -2296,15 +2301,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "litemap" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2647d5b7134127971a6de0d533c49de2159167e7f259c427195f87168a1" +checksum = "f9d642685b028806386b2b6e75685faadd3eb65a85fff7df711ce18446a422da" [[package]] name = "lld-wrapper" @@ -2312,9 +2317,9 @@ version = "0.1.0" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -2322,9 +2327,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lzma-sys" @@ -2374,10 +2379,11 @@ dependencies = [ [[package]] name = "md-5" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ + "cfg-if", "digest", ] @@ -2393,7 +2399,7 @@ dependencies = [ "clap", "clap_complete", "elasticlunr-rs", - "env_logger 0.11.1", + "env_logger 0.11.2", "handlebars", "log", "memchr", @@ -2481,9 +2487,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", "compiler_builtins", @@ -2493,9 +2499,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -2518,7 +2524,7 @@ dependencies = [ "aes", "colored", "ctrlc", - "env_logger 0.10.0", + "env_logger 0.10.2", "getrandom", "jemalloc-sys", "lazy_static", @@ -2571,7 +2577,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "libc", ] @@ -2615,10 +2621,16 @@ dependencies = [ ] [[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -2668,9 +2680,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opener" @@ -2689,7 +2701,7 @@ version = "0.10.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -2706,7 +2718,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -2736,7 +2748,7 @@ dependencies = [ "camino", "clap", "derive_builder", - "env_logger 0.10.0", + "env_logger 0.10.2", "fs_extra", "glob", "humansize", @@ -2836,15 +2848,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -2855,9 +2867,9 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "perf-event-open-sys" @@ -2870,19 +2882,20 @@ dependencies = [ [[package]] name = "pest" -version = "2.7.0" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.0" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" dependencies = [ "pest", "pest_generator", @@ -2890,22 +2903,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.0" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] name = "pest_meta" -version = "2.7.0" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" dependencies = [ "once_cell", "pest", @@ -2952,9 +2965,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2964,9 +2977,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "polonius-engine" @@ -2981,9 +2994,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -3015,9 +3034,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -3054,7 +3073,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "memchr", "unicase", ] @@ -3065,7 +3084,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "memchr", "pulldown-cmark-escape", "unicase", @@ -3091,18 +3110,18 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.29" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575fc2d9b3da54adbdfaddf6eca48fec256d977c8630a1750b8991347d1ac911" +checksum = "0e244f96e03a3067f9e521d3167bd42657594cb8588c8d3a2db01545dc1af2e0" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -3169,9 +3188,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3179,9 +3198,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3189,42 +3208,34 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" dependencies = [ - "aho-corasick 1.0.2", + "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.7", + "regex-syntax 0.7.5", ] [[package]] @@ -3246,6 +3257,23 @@ dependencies = [ ] [[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-lite" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" + +[[package]] name = "regex-syntax" version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3253,9 +3281,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" @@ -3281,9 +3309,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ "base64", "bytes", @@ -3306,6 +3334,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -3336,7 +3365,7 @@ name = "rustbook" version = "0.1.0" dependencies = [ "clap", - "env_logger 0.10.0", + "env_logger 0.10.2", "mdbook", ] @@ -3432,7 +3461,7 @@ dependencies = [ name = "rustc_abi" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "rand", "rand_xoshiro", "rustc_data_structures", @@ -3463,7 +3492,7 @@ dependencies = [ name = "rustc_ast" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "memchr", "rustc_data_structures", "rustc_index", @@ -3614,7 +3643,7 @@ dependencies = [ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "itertools", "libc", "measureme", @@ -3649,7 +3678,7 @@ name = "rustc_codegen_ssa" version = "0.0.0" dependencies = [ "ar_archive_writer", - "bitflags 2.4.1", + "bitflags 2.4.2", "cc", "itertools", "jobserver", @@ -3716,7 +3745,7 @@ name = "rustc_data_structures" version = "0.0.0" dependencies = [ "arrayvec", - "bitflags 2.4.1", + "bitflags 2.4.2", "either", "elsa", "ena", @@ -3899,7 +3928,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "unic-langid", ] @@ -4033,7 +4062,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "synstructure", ] @@ -4179,7 +4208,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "synstructure", ] @@ -4187,7 +4216,7 @@ dependencies = [ name = "rustc_metadata" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libloading", "odht", "rustc_ast", @@ -4217,7 +4246,7 @@ dependencies = [ name = "rustc_middle" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "derive_more", "either", "field-offset", @@ -4353,7 +4382,7 @@ dependencies = [ name = "rustc_parse" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "rustc_ast", "rustc_ast_pretty", "rustc_data_structures", @@ -4491,7 +4520,7 @@ dependencies = [ name = "rustc_resolve" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "pulldown-cmark 0.9.6", "rustc_arena", "rustc_ast", @@ -4530,7 +4559,7 @@ dependencies = [ name = "rustc_session" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "getopts", "libc", "rustc_ast", @@ -4559,6 +4588,7 @@ dependencies = [ "rustc_data_structures", "rustc_hir", "rustc_middle", + "rustc_session", "rustc_span", "rustc_target", "scoped-tls", @@ -4588,7 +4618,7 @@ dependencies = [ name = "rustc_symbol_mangling" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "punycode", "rustc-demangle", "rustc_data_structures", @@ -4606,7 +4636,7 @@ dependencies = [ name = "rustc_target" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "object", "rustc_abi", "rustc_data_structures", @@ -4630,7 +4660,7 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f" name = "rustc_trait_selection" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "itertools", "rustc_ast", "rustc_attr", @@ -4706,7 +4736,7 @@ dependencies = [ name = "rustc_type_ir" version = "0.0.0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "derivative", "rustc_data_structures", "rustc_index", @@ -4798,14 +4828,14 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] name = "rustfmt-nightly" version = "1.7.0" dependencies = [ - "annotate-snippets 0.9.1", + "annotate-snippets 0.9.2", "anyhow", "bytecount", "cargo_metadata 0.15.4", @@ -4823,7 +4853,7 @@ dependencies = [ "serde_json", "term", "thiserror", - "toml 0.7.5", + "toml 0.7.8", "tracing", "tracing-subscriber", "unicode-properties", @@ -4833,22 +4863,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.19" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ruzstd" @@ -4863,9 +4893,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -4878,11 +4908,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4893,15 +4923,15 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -4912,9 +4942,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -4926,49 +4956,49 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" dependencies = [ - "self_cell 1.0.2", + "self_cell 1.0.3", ] [[package]] name = "self_cell" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e388332cd64eb80cd595a00941baf513caffae8dce9cfd0467fc9c66397dade6" +checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" [[package]] name = "semver" -version = "1.0.17" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.185" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.185" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "indexmap", "itoa", @@ -4978,9 +5008,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -4999,9 +5029,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -5010,9 +5040,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -5021,9 +5051,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -5042,39 +5072,39 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "snap" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -5091,9 +5121,9 @@ dependencies = [ [[package]] name = "spdx-rs" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1f9cfa402cd27dd022fd1943f0f969b10dda75d5e50e3a78ccee9c0188e2a" +checksum = "990870190ec8d8c64ba66e4a6746243d6e57d99353991e0e6092334833f429b1" dependencies = [ "chrono", "log", @@ -5212,6 +5242,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + +[[package]] name = "strum" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5252,9 +5288,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -5263,14 +5299,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", - "unicode-xid", + "syn 2.0.48", ] [[package]] @@ -5297,6 +5332,27 @@ dependencies = [ ] [[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] name = "tabled" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5308,9 +5364,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.38" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" dependencies = [ "filetime", "libc", @@ -5319,15 +5375,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -5354,9 +5409,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -5414,22 +5469,22 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -5484,11 +5539,14 @@ version = "0.1.0" [[package]] name = "time" -version = "0.3.22" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ + "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -5496,24 +5554,25 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] [[package]] name = "tinystr" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0e245e80bdc9b4e5356fc45a72184abbc3861992603f515270e9340f5a219" +checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" dependencies = [ "displaydoc", "zerovec", @@ -5536,11 +5595,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -5563,9 +5621,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.2" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -5586,9 +5644,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.5" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -5598,18 +5656,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.11" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", "serde", @@ -5644,13 +5702,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -5675,20 +5733,31 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -5700,27 +5769,26 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", ] [[package]] name = "tracing-tree" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d6b63348fad3ae0439b8bebf8d38fb5bda0b115d7a8a7e6f165f12790c58c3" +checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d" dependencies = [ - "is-terminal", "nu-ansi-term", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twox-hash" @@ -5744,25 +5812,24 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-parse" -version = "0.1.10" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2d0556a998f4c55500ce1730901ba32bafbe820068cbdc091421525d61253b" +checksum = "c06ff81122fcbf4df4c1660b15f7e3336058e7aec14437c9f85c6b31a0f279b9" dependencies = [ - "once_cell", - "regex", + "regex-lite", ] [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "ui_test" @@ -5770,7 +5837,7 @@ version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaf4bf7c184b8dfc7a4d3b90df789b1eb992ee42811cd115f32a7a1eb781058d" dependencies = [ - "annotate-snippets 0.9.1", + "annotate-snippets 0.9.2", "anyhow", "bstr", "cargo-platform", @@ -5830,7 +5897,7 @@ checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.32", + "syn 2.0.48", "unic-langid-impl", ] @@ -5852,15 +5919,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -5873,9 +5940,9 @@ dependencies = [ [[package]] name = "unicode-properties" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f91c8b21fbbaa18853c3d0801c78f4fc94cdb976699bb03e832e75f7fd22f0" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" [[package]] name = "unicode-script" @@ -5885,9 +5952,9 @@ checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" [[package]] name = "unicode-security" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef5756b3097992b934b06608c69f48448a0fbe804bb1e72b982f6d7983e9e63" +checksum = "ee9e13753df674873f3c4693b240ae5c03245ddc157dfccf7c26db9329af3a11" dependencies = [ "unicode-normalization", "unicode-script", @@ -5895,9 +5962,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" @@ -5957,9 +6024,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -5980,9 +6047,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.4.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", ] @@ -6007,9 +6074,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -6037,9 +6104,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -6047,24 +6114,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -6074,9 +6141,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6084,28 +6151,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", @@ -6129,9 +6196,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -6148,7 +6215,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -6159,24 +6226,24 @@ checksum = "970efb0b6849eb8a87a898f586af7cc167567b070014c7434514c0bde0ca341c" dependencies = [ "proc-macro2", "rayon", - "syn 2.0.32", + "syn 2.0.48", "windows-metadata", ] [[package]] -name = "windows-metadata" +name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "218fd59201e26acdbb894fa2b302d1de84bf3eec7d0eb894ac8e9c5a854ee4ef" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-metadata" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] +checksum = "218fd59201e26acdbb894fa2b302d1de84bf3eec7d0eb894ac8e9c5a854ee4ef" [[package]] name = "windows-sys" @@ -6184,7 +6251,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -6198,32 +6265,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -6243,15 +6295,9 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" @@ -6261,15 +6307,9 @@ checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" @@ -6279,15 +6319,9 @@ checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" [[package]] name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" @@ -6297,15 +6331,9 @@ checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" @@ -6315,15 +6343,9 @@ checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" @@ -6333,15 +6355,9 @@ checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" @@ -6351,15 +6367,9 @@ checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" @@ -6369,35 +6379,38 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.4.7" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] name = "writeable" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0af0c3d13faebf8dda0b5256fa7096a2d5ccb662f7b9f54a40fe201077ab1c2" +checksum = "dad7bb64b8ef9c0aa27b6da38b452b0ee9fd82beaf276a87dd796fb55cbae14e" [[package]] name = "xattr" -version = "0.2.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", + "linux-raw-sys", + "rustix", ] [[package]] @@ -6449,9 +6462,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e38c508604d6bbbd292dadb3c02559aa7fff6b654a078a36217cad871636e4" +checksum = "65e71b2e4f287f467794c671e2b8f8a5f3716b3c829079a1c44740148eff07e4" dependencies = [ "serde", "stable_deref_trait", @@ -6461,13 +6474,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e19fb6ed40002bab5403ffa37e53e0e56f914a4450c8765f533018db1db35f" +checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "synstructure", ] @@ -6488,7 +6501,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] @@ -6508,15 +6521,15 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", "synstructure", ] [[package]] name = "zerovec" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1194130c5b155bf8ae50ab16c86ab758cd695cf9ad176d2f870b744cbdbb572e" +checksum = "eff4439ae91fb5c72b8abc12f3f2dbf51bd27e6eadb9f8a5bc8898dddb0e27ea" dependencies = [ "yoke", "zerofrom", @@ -6525,13 +6538,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acabf549809064225ff8878baedc4ce3732ac3b07e7c7ce6e5c2ccdbc485c324" +checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.48", ] [[package]] diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 937ee4bcd42..087f6a192b5 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -4,9 +4,10 @@ version = "0.0.0" edition = "2021" [dependencies] +# FIXME: bumping memchr to 2.7.1 causes linker errors in MSVC thin-lto # tidy-alphabetical-start bitflags = "2.4.1" -memchr = "2.5.0" +memchr = "=2.5.0" rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 933372fae4e..87ed47648c8 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1068,7 +1068,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> { match block { Some(block) => self.lower_block_expr(block), - None => self.expr_err(span, self.dcx().span_delayed_bug(span, "no block")), + None => self.expr_err(span, self.dcx().has_errors().unwrap()), } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 480072ce705..6b5fc014240 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1285,9 +1285,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> { let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, - TyKind::Err => { - hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered")) - } + TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()), // Lower the anonymous structs or unions in a nested lowering context. // // ``` diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index e8ffab9307e..6c2a511538d 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2479,7 +2479,8 @@ mod diags { &mut self, span: Span, ) -> Option<(DiagnosticBuilder<'tcx>, usize)> { - self.diags.buffered_mut_errors.remove(&span) + // FIXME(#120456) - is `swap_remove` correct? + self.diags.buffered_mut_errors.swap_remove(&span) } pub fn buffer_mut_error(&mut self, span: Span, t: DiagnosticBuilder<'tcx>, count: usize) { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cfb46f3ac8a..ae4000f02a7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1432,7 +1432,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } }; - let (sig, map) = tcx.instantiate_bound_regions(sig, |br| { + let (unnormalized_sig, map) = tcx.instantiate_bound_regions(sig, |br| { use crate::renumber::RegionCtxt; let region_ctxt_fn = || { @@ -1454,7 +1454,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { region_ctxt_fn, ) }); - debug!(?sig); + debug!(?unnormalized_sig); // IMPORTANT: We have to prove well formed for the function signature before // we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc` // get normalized away, causing us to ignore the `'b: 'a` bound used by the function. @@ -1464,7 +1464,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // // See #91068 for an example. self.prove_predicates( - sig.inputs_and_output.iter().map(|ty| { + unnormalized_sig.inputs_and_output.iter().map(|ty| { ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed( ty.into(), ))) @@ -1472,7 +1472,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { term_location.to_locations(), ConstraintCategory::Boring, ); - let sig = self.normalize(sig, term_location); + + let sig = self.normalize(unnormalized_sig, term_location); + // HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))` + // with built-in `Fn` implementations, since the impl may not be + // well-formed itself. + if sig != unnormalized_sig { + self.prove_predicates( + sig.inputs_and_output.iter().map(|ty| { + ty::Binder::dummy(ty::PredicateKind::Clause( + ty::ClauseKind::WellFormed(ty.into()), + )) + }), + term_location.to_locations(), + ConstraintCategory::Boring, + ); + } + self.check_call_dest(body, term, &sig, *destination, *target, term_location); // The ordinary liveness rules will ensure that all diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 81757a62e5b..dea1c7823a5 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -58,7 +58,8 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { // be those that were never initialized - we will consider those as being used as // they will either have been removed by unreachable code optimizations; or linted // as unused variables. - self.never_initialized_mut_locals.remove(&into.local); + // FIXME(#120456) - is `swap_remove` correct? + self.never_initialized_mut_locals.swap_remove(&into.local); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index e48479c8da2..54e8ed85e32 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -266,6 +266,10 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> { ("riscv32" | "riscv64", "fast-unaligned-access") if get_version().0 <= 17 => { LLVMFeature::new("unaligned-scalar-mem") } + // For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled. + ("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => { + LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")) + } (_, s) => LLVMFeature::new(s), } } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index ee1d548b231..241b0a15f78 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -106,7 +106,8 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> { match attrs.instruction_set { None => {} Some(InstructionSetAttr::ArmA32) => { - target_features.remove(&sym::thumb_mode); + // FIXME(#120456) - is `swap_remove` correct? + target_features.swap_remove(&sym::thumb_mode); } Some(InstructionSetAttr::ArmT32) => { target_features.insert(sym::thumb_mode); diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 85ebbb00c5f..4a6d4fe930c 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -313,6 +313,8 @@ const_eval_realloc_or_alloc_with_offset = *[other] {""} } {$ptr} which does not point to the beginning of an object +const_eval_recursive_static = encountered static that tried to initialize itself with itself + const_eval_remainder_by_zero = calculating the remainder with a divisor of zero const_eval_remainder_overflow = diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 80d02589900..935329f1189 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -19,6 +19,7 @@ use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, MachineStopTy pub enum ConstEvalErrKind { ConstAccessesMutGlobal, ModifiedGlobal, + RecursiveStatic, AssertFailure(AssertKind<ConstInt>), Panic { msg: Symbol, line: u32, col: u32, file: Symbol }, } @@ -31,13 +32,14 @@ impl MachineStopType for ConstEvalErrKind { ConstAccessesMutGlobal => const_eval_const_accesses_mut_global, ModifiedGlobal => const_eval_modified_global, Panic { .. } => const_eval_panic, + RecursiveStatic => const_eval_recursive_static, AssertFailure(x) => x.diagnostic_message(), } } fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue)) { use ConstEvalErrKind::*; match *self { - ConstAccessesMutGlobal | ModifiedGlobal => {} + RecursiveStatic | ConstAccessesMutGlobal | ModifiedGlobal => {} AssertFailure(kind) => kind.add_args(adder), Panic { msg, line, col, file } => { adder("msg".into(), msg.into_diagnostic_arg()); diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index c55d899e4d5..7099cdd5a75 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -2,12 +2,12 @@ use either::{Left, Right}; use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo}; -use rustc_middle::mir::pretty::write_allocation_bytes; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, TyCtxt}; +use rustc_span::def_id::LocalDefId; use rustc_span::Span; use rustc_target::abi::{self, Abi}; @@ -17,8 +17,9 @@ use crate::errors; use crate::errors::ConstEvalError; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate, InternKind, InterpCx, - InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, + create_static_alloc, intern_const_alloc_recursive, take_static_root_alloc, CtfeValidationMode, + GlobalId, Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, + OpTy, RefTracking, StackPopCleanup, }; // Returns a pointer to where the result lives @@ -46,7 +47,21 @@ fn eval_body_using_ecx<'mir, 'tcx>( ); let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?; assert!(layout.is_sized()); - let ret = ecx.allocate(layout, MemoryKind::Stack)?; + + let intern_kind = if cid.promoted.is_some() { + InternKind::Promoted + } else { + match tcx.static_mutability(cid.instance.def_id()) { + Some(m) => InternKind::Static(m), + None => InternKind::Constant, + } + }; + + let ret = if let InternKind::Static(_) = intern_kind { + create_static_alloc(ecx, cid.instance.def_id(), layout)? + } else { + ecx.allocate(layout, MemoryKind::Stack)? + }; trace!( "eval_body_using_ecx: pushing stack frame for global: {}{}", @@ -66,14 +81,6 @@ fn eval_body_using_ecx<'mir, 'tcx>( while ecx.step()? {} // Intern the result - let intern_kind = if cid.promoted.is_some() { - InternKind::Promoted - } else { - match tcx.static_mutability(cid.instance.def_id()) { - Some(m) => InternKind::Static(m), - None => InternKind::Constant, - } - }; intern_const_alloc_recursive(ecx, intern_kind, &ret)?; Ok(ret) @@ -250,10 +257,36 @@ pub fn eval_to_const_value_raw_provider<'tcx>( } #[instrument(skip(tcx), level = "debug")] +pub fn eval_static_initializer_provider<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> { + assert!(tcx.is_static(def_id.to_def_id())); + + let instance = ty::Instance::mono(tcx, def_id.to_def_id()); + let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None }; + let mut ecx = InterpCx::new( + tcx, + tcx.def_span(def_id), + ty::ParamEnv::reveal_all(), + // Statics (and promoteds inside statics) may access other statics, because unlike consts + // they do not have to behave "as if" they were evaluated at runtime. + CompileTimeInterpreter::new(CanAccessMutGlobal::Yes, CheckAlignment::Error), + ); + let alloc_id = eval_in_interpreter(&mut ecx, cid, true)?.alloc_id; + let alloc = take_static_root_alloc(&mut ecx, alloc_id); + let alloc = tcx.mk_const_alloc(alloc); + Ok(alloc) +} + +#[instrument(skip(tcx), level = "debug")] pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { + // This shouldn't be used for statics, since statics are conceptually places, + // not values -- so what we do here could break pointer identity. + assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id())); // Const eval always happens in Reveal::All mode in order to be able to use the hidden types of // opaque types. This is needed for trivial things like `size_of`, but also for using associated // types that are not specified in the opaque type. @@ -273,7 +306,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let def = cid.instance.def.def_id(); let is_static = tcx.is_static(def); - let ecx = InterpCx::new( + let mut ecx = InterpCx::new( tcx, tcx.def_span(def), key.param_env, @@ -283,11 +316,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>( // so we have to reject reading mutable global memory. CompileTimeInterpreter::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error), ); - eval_in_interpreter(ecx, cid, is_static) + eval_in_interpreter(&mut ecx, cid, is_static) } pub fn eval_in_interpreter<'mir, 'tcx>( - mut ecx: InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, cid: GlobalId<'tcx>, is_static: bool, ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { @@ -295,7 +328,7 @@ pub fn eval_in_interpreter<'mir, 'tcx>( debug_assert_eq!(is_static, ecx.tcx.static_mutability(cid.instance.def_id()).is_some()); let res = ecx.load_mir(cid.instance.def, cid.promoted); - match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)) { + match res.and_then(|body| eval_body_using_ecx(ecx, cid, body)) { Err(error) => { let (error, backtrace) = error.into_parts(); backtrace.print_backtrace(); @@ -330,8 +363,11 @@ pub fn eval_in_interpreter<'mir, 'tcx>( } Ok(mplace) => { // Since evaluation had no errors, validate the resulting constant. - // This is a separate `try` block to provide more targeted error reporting. + + // Temporarily allow access to the static_root_alloc_id for the purpose of validation. + let static_root_alloc_id = ecx.machine.static_root_alloc_id.take(); let validation = const_validate_mplace(&ecx, &mplace, cid); + ecx.machine.static_root_alloc_id = static_root_alloc_id; let alloc_id = mplace.ptr().provenance.unwrap().alloc_id(); @@ -383,15 +419,9 @@ pub fn const_report_error<'mir, 'tcx>( let ub_note = matches!(error, InterpError::UndefinedBehavior(_)).then(|| {}); - let alloc = ecx.tcx.global_alloc(alloc_id).unwrap_memory().inner(); - let mut bytes = String::new(); - if alloc.size() != abi::Size::ZERO { - bytes = "\n".into(); - // FIXME(translation) there might be pieces that are translatable. - write_allocation_bytes(*ecx.tcx, alloc, &mut bytes, " ").unwrap(); - } - let raw_bytes = - errors::RawBytesNote { size: alloc.size().bytes(), align: alloc.align.bytes(), bytes }; + let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id); + let (size, align, _) = ecx.get_alloc_info(alloc_id); + let raw_bytes = errors::RawBytesNote { size: size.bytes(), align: align.bytes(), bytes }; crate::const_eval::report( *ecx.tcx, diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index d08985edb76..2c60ede7975 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -58,6 +58,9 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> { /// Whether to check alignment during evaluation. pub(super) check_alignment: CheckAlignment, + + /// Used to prevent reads from a static's base allocation, as that may allow for self-initialization. + pub(crate) static_root_alloc_id: Option<AllocId>, } #[derive(Copy, Clone)] @@ -91,6 +94,7 @@ impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { stack: Vec::new(), can_access_mut_global, check_alignment, + static_root_alloc_id: None, } } } @@ -122,7 +126,8 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> { where K: Borrow<Q>, { - FxIndexMap::remove(self, k) + // FIXME(#120456) - is `swap_remove` correct? + FxIndexMap::swap_remove(self, k) } #[inline(always)] @@ -745,6 +750,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // Everything else is fine. Ok(()) } + + fn before_alloc_read( + ecx: &InterpCx<'mir, 'tcx, Self>, + alloc_id: AllocId, + ) -> InterpResult<'tcx> { + if Some(alloc_id) == ecx.machine.static_root_alloc_id { + Err(ConstEvalErrKind::RecursiveStatic.into()) + } else { + Ok(()) + } + } } // Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 6d470ff162e..a88e130cd4b 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -153,7 +153,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ); } - self.copy_op(src, dest, /*allow_transmute*/ true)?; + self.copy_op_allow_transmute(src, dest)?; } } Ok(()) @@ -441,7 +441,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if src_field.layout.is_1zst() && cast_ty_field.is_1zst() { // Skip 1-ZST fields. } else if src_field.layout.ty == cast_ty_field.ty { - self.copy_op(&src_field, &dst_field, /*allow_transmute*/ false)?; + self.copy_op(&src_field, &dst_field)?; } else { if found_cast_field { span_bug!(self.cur_span(), "unsize_into: more than one field to cast"); diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 33e96e7faa8..517994d4741 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -288,7 +288,7 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure { write!(f, "inside closure") } else { - // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever + // Note: this triggers a `must_produce_diag` state, which means that if we ever // get here we must emit a diagnostic. We should never display a `FrameInfo` unless // we actually want to emit a warning or error to the user. write!(f, "inside `{}`", self.instance) @@ -304,7 +304,7 @@ impl<'tcx> FrameInfo<'tcx> { errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 } } else { let instance = format!("{}", self.instance); - // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever get + // Note: this triggers a `must_produce_diag` state, which means that if we ever get // here we must emit a diagnostic. We should never display a `FrameInfo` unless we // actually want to emit a warning or error to the user. errors::FrameNote { where_: "instance", span, instance, times: 0 } @@ -899,7 +899,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .local_to_op(self.frame(), mir::RETURN_PLACE, None) .expect("return place should always be live"); let dest = self.frame().return_place.clone(); - let err = self.copy_op(&op, &dest, /*allow_transmute*/ true); + let err = if self.stack().len() == 1 { + // The initializer of constants and statics will get validated separately + // after the constant has been fully evaluated. While we could fall back to the default + // code path, that will cause -Zenforce-validity to cycle on static initializers. + // Reading from a static's memory is not allowed during its evaluation, and will always + // trigger a cycle error. Validation must read from the memory of the current item. + // For Miri this means we do not validate the root frame return value, + // but Miri anyway calls `read_target_isize` on that so separate validation + // is not needed. + self.copy_op_no_dest_validation(&op, &dest) + } else { + self.copy_op_allow_transmute(&op, &dest) + }; trace!("return value: {:?}", self.dump_place(&dest)); // We delay actually short-circuiting on this error until *after* the stack frame is // popped, since we want this error to be attributed to the caller, whose type defines diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 38e7843761b..959ec2ca865 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -49,7 +49,8 @@ fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>( ) -> Result<impl Iterator<Item = CtfeProvenance> + 'tcx, ()> { trace!("intern_shallow {:?}", alloc_id); // remove allocation - let Some((_kind, mut alloc)) = ecx.memory.alloc_map.remove(&alloc_id) else { + // FIXME(#120456) - is `swap_remove` correct? + let Some((_kind, mut alloc)) = ecx.memory.alloc_map.swap_remove(&alloc_id) else { return Err(()); }; // Set allocation mutability as appropriate. This is used by LLVM to put things into @@ -84,6 +85,8 @@ pub enum InternKind { /// /// This *cannot raise an interpreter error*. Doing so is left to validation, which /// tracks where in the value we are and thus can show much better error messages. +/// +/// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller. #[instrument(level = "debug", skip(ecx))] pub fn intern_const_alloc_recursive< 'mir, @@ -96,12 +99,12 @@ pub fn intern_const_alloc_recursive< ) -> Result<(), ErrorGuaranteed> { // We are interning recursively, and for mutability we are distinguishing the "root" allocation // that we are starting in, and all other allocations that we are encountering recursively. - let (base_mutability, inner_mutability) = match intern_kind { + let (base_mutability, inner_mutability, is_static) = match intern_kind { InternKind::Constant | InternKind::Promoted => { // Completely immutable. Interning anything mutably here can only lead to unsoundness, // since all consts are conceptually independent values but share the same underlying // memory. - (Mutability::Not, Mutability::Not) + (Mutability::Not, Mutability::Not, false) } InternKind::Static(Mutability::Not) => { ( @@ -114,22 +117,31 @@ pub fn intern_const_alloc_recursive< // Inner allocations are never mutable. They can only arise via the "tail // expression" / "outer scope" rule, and we treat them consistently with `const`. Mutability::Not, + true, ) } InternKind::Static(Mutability::Mut) => { // Just make everything mutable. We accept code like // `static mut X = &mut [42]`, so even inner allocations need to be mutable. - (Mutability::Mut, Mutability::Mut) + (Mutability::Mut, Mutability::Mut, true) } }; // Intern the base allocation, and initialize todo list for recursive interning. let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id(); + trace!(?base_alloc_id, ?base_mutability); // First we intern the base allocation, as it requires a different mutability. // This gives us the initial set of nested allocations, which will then all be processed // recursively in the loop below. - let mut todo: Vec<_> = - intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().map(|prov| prov).collect(); + let mut todo: Vec<_> = if is_static { + // Do not steal the root allocation, we need it later for `take_static_root_alloc` + // But still change its mutability to match the requested one. + let alloc = ecx.memory.alloc_map.get_mut(&base_alloc_id).unwrap(); + alloc.1.mutability = base_mutability; + alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect() + } else { + intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().map(|prov| prov).collect() + }; // We need to distinguish "has just been interned" from "was already in `tcx`", // so we track this in a separate set. let mut just_interned: FxHashSet<_> = std::iter::once(base_alloc_id).collect(); @@ -147,7 +159,17 @@ pub fn intern_const_alloc_recursive< // before validation, and interning doesn't know the type of anything, this means we can't show // better errors. Maybe we should consider doing validation before interning in the future. while let Some(prov) = todo.pop() { + trace!(?prov); let alloc_id = prov.alloc_id(); + + if base_alloc_id == alloc_id && is_static { + // This is a pointer to the static itself. It's ok for a static to refer to itself, + // even mutably. Whether that mutable pointer is legal at all is checked in validation. + // See tests/ui/statics/recursive_interior_mut.rs for how such a situation can occur. + // We also already collected all the nested allocations, so there's no need to do that again. + continue; + } + // Crucially, we check this *before* checking whether the `alloc_id` // has already been interned. The point of this check is to ensure that when // there are multiple pointers to the same allocation, they are *all* immutable. @@ -175,6 +197,7 @@ pub fn intern_const_alloc_recursive< // `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely // on the promotion analysis not screwing up to ensure that it is sound to intern // promoteds as immutable. + trace!("found bad mutable pointer"); found_bad_mutable_pointer = true; } if ecx.tcx.try_get_global_alloc(alloc_id).is_some() { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 7991f90b815..f020616f6d8 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -120,7 +120,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = self.tcx.span_as_caller_location(span); let val = self.const_val_to_op(val, self.tcx.caller_location_ty(), Some(dest.layout))?; - self.copy_op(&val, dest, /* allow_transmute */ false)?; + self.copy_op(&val, dest)?; } sym::min_align_of_val | sym::size_of_val => { @@ -157,7 +157,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { tcx.const_eval_global_id(self.param_env, gid, Some(tcx.span)) })?; let val = self.const_val_to_op(val, ty, Some(dest.layout))?; - self.copy_op(&val, dest, /*allow_transmute*/ false)?; + self.copy_op(&val, dest)?; } sym::ctpop @@ -391,7 +391,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.project_index(&input, i)?.into() }; - self.copy_op(&value, &place, /*allow_transmute*/ false)?; + self.copy_op(&value, &place)?; } } sym::simd_extract => { @@ -401,15 +401,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { index < input_len, "index `{index}` must be in bounds of vector with length {input_len}" ); - self.copy_op( - &self.project_index(&input, index)?, - dest, - /*allow_transmute*/ false, - )?; + self.copy_op(&self.project_index(&input, index)?, dest)?; } sym::likely | sym::unlikely | sym::black_box => { // These just return their argument - self.copy_op(&args[0], dest, /*allow_transmute*/ false)?; + self.copy_op(&args[0], dest)?; } sym::raw_eq => { let result = self.raw_eq_intrinsic(&args[0], &args[1])?; diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index b981a1ee2ca..0106ec425bc 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -388,6 +388,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Takes read-only access to the allocation so we can keep all the memory read /// operations take `&self`. Use a `RefCell` in `AllocExtra` if you /// need to mutate. + /// + /// This is not invoked for ZST accesses, as no read actually happens. #[inline(always)] fn before_memory_read( _tcx: TyCtxtAt<'tcx>, @@ -399,7 +401,20 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { Ok(()) } + /// Hook for performing extra checks on any memory read access, + /// that involves an allocation, even ZST reads. + /// + /// Used to prevent statics from self-initializing by reading from their own memory + /// as it is being initialized. + fn before_alloc_read( + _ecx: &InterpCx<'mir, 'tcx, Self>, + _alloc_id: AllocId, + ) -> InterpResult<'tcx> { + Ok(()) + } + /// Hook for performing extra checks on a memory write access. + /// This is not invoked for ZST accesses, as no write actually happens. #[inline(always)] fn before_memory_write( _tcx: TyCtxtAt<'tcx>, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 4acf4ed893c..2e642ac15b4 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -624,19 +624,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { size, CheckInAllocMsg::MemoryAccessTest, |alloc_id, offset, prov| { + // We want to call the hook on *all* accesses that involve an AllocId, + // including zero-sized accesses. That means we have to do it here + // rather than below in the `Some` branch. + M::before_alloc_read(self, alloc_id)?; let alloc = self.get_alloc_raw(alloc_id)?; Ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc))) }, )?; + if let Some((alloc_id, offset, prov, alloc)) = ptr_and_alloc { let range = alloc_range(offset, size); M::before_memory_read(self.tcx, &self.machine, &alloc.extra, (alloc_id, prov), range)?; Ok(Some(AllocRef { alloc, range, tcx: *self.tcx, alloc_id })) } else { - // Even in this branch we have to be sure that we actually access the allocation, in - // order to ensure that `static FOO: Type = FOO;` causes a cycle error instead of - // magically pulling *any* ZST value from the ether. However, the `get_raw` above is - // always called when `ptr` has an `AllocId`. Ok(None) } } @@ -855,6 +856,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { DumpAllocs { ecx: self, allocs } } + /// Print the allocation's bytes, without any nested allocations. + pub fn print_alloc_bytes_for_diagnostics(&self, id: AllocId) -> String { + // Using the "raw" access to avoid the `before_alloc_read` hook, we specifically + // want to be able to read all memory for diagnostics, even if that is cyclic. + let alloc = self.get_alloc_raw(id).unwrap(); + let mut bytes = String::new(); + if alloc.size() != Size::ZERO { + bytes = "\n".into(); + // FIXME(translation) there might be pieces that are translatable. + rustc_middle::mir::pretty::write_allocation_bytes(*self.tcx, alloc, &mut bytes, " ") + .unwrap(); + } + bytes + } + /// Find leaked allocations. Allocations reachable from `static_roots` or a `Global` allocation /// are not considered leaked, as well as leaks whose kind's `may_leak()` returns true. pub fn find_leaked_allocations( diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index c1b6ce4eb4e..a15e52d07e6 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -39,4 +39,5 @@ use self::{ }; pub(crate) use self::intrinsics::eval_nullary_intrinsic; +pub(crate) use self::util::{create_static_alloc, take_static_root_alloc}; use eval_context::{from_known_layout, mir_assign_valid_types}; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 03d1dc9fd3d..6e987784ff9 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -759,14 +759,57 @@ where } /// Copies the data from an operand to a place. + /// The layouts of the `src` and `dest` may disagree. + /// Does not perform validation of the destination. + /// The only known use case for this function is checking the return + /// value of a static during stack frame popping. + #[inline(always)] + pub(super) fn copy_op_no_dest_validation( + &mut self, + src: &impl Readable<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, + ) -> InterpResult<'tcx> { + self.copy_op_inner( + src, dest, /* allow_transmute */ true, /* validate_dest */ false, + ) + } + + /// Copies the data from an operand to a place. + /// The layouts of the `src` and `dest` may disagree. + #[inline(always)] + pub fn copy_op_allow_transmute( + &mut self, + src: &impl Readable<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, + ) -> InterpResult<'tcx> { + self.copy_op_inner( + src, dest, /* allow_transmute */ true, /* validate_dest */ true, + ) + } + + /// Copies the data from an operand to a place. + /// `src` and `dest` must have the same layout and the copied value will be validated. + #[inline(always)] + pub fn copy_op( + &mut self, + src: &impl Readable<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, + ) -> InterpResult<'tcx> { + self.copy_op_inner( + src, dest, /* allow_transmute */ false, /* validate_dest */ true, + ) + } + + /// Copies the data from an operand to a place. /// `allow_transmute` indicates whether the layouts may disagree. #[inline(always)] #[instrument(skip(self), level = "debug")] - pub fn copy_op( + fn copy_op_inner( &mut self, src: &impl Readable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, + validate_dest: bool, ) -> InterpResult<'tcx> { // Generally for transmutation, data must be valid both at the old and new type. // But if the types are the same, the 2nd validation below suffices. @@ -777,7 +820,7 @@ where // Do the actual copy. self.copy_op_no_validate(src, dest, allow_transmute)?; - if M::enforce_validity(self, dest.layout()) { + if validate_dest && M::enforce_validity(self, dest.layout()) { // Data got changed, better make sure it matches the type! self.validate_operand(&dest.to_op(self)?)?; } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 23f3d7eb67d..d4c96f4573d 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -151,12 +151,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Use(ref operand) => { // Avoid recomputing the layout let op = self.eval_operand(operand, Some(dest.layout))?; - self.copy_op(&op, &dest, /*allow_transmute*/ false)?; + self.copy_op(&op, &dest)?; } CopyForDeref(place) => { let op = self.eval_place_to_op(place, Some(dest.layout))?; - self.copy_op(&op, &dest, /* allow_transmute*/ false)?; + self.copy_op(&op, &dest)?; } BinaryOp(bin_op, box (ref left, ref right)) => { @@ -316,7 +316,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let field_index = active_field_index.unwrap_or(field_index); let field_dest = self.project_field(&variant_dest, field_index.as_usize())?; let op = self.eval_operand(operand, Some(field_dest.layout))?; - self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?; + self.copy_op(&op, &field_dest)?; } self.write_discriminant(variant_index, dest) } @@ -339,7 +339,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // Write the src to the first element. let first = self.project_index(&dest, 0)?; - self.copy_op(&src, &first, /*allow_transmute*/ false)?; + self.copy_op(&src, &first)?; // This is performance-sensitive code for big static/const arrays! So we // avoid writing each operand individually and instead just make many copies diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 4037220e5ed..b2207c3d310 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -481,7 +481,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: Depending on the PassMode, this should reset some padding to uninitialized. (This // is true for all `copy_op`, but there are a lot of special cases for argument passing // specifically.) - self.copy_op(&caller_arg_copy, &callee_arg, /*allow_transmute*/ true)?; + self.copy_op_allow_transmute(&caller_arg_copy, &callee_arg)?; // If this was an in-place pass, protect the place it comes from for the duration of the call. if let FnArg::InPlace(place) = caller_arg { M::protect_in_place_function_argument(self, place)?; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 3a9ee904734..2a13671a829 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,9 +1,15 @@ -use rustc_middle::mir::interpret::InterpResult; +use crate::const_eval::CompileTimeEvalContext; +use crate::interpret::{MemPlaceMeta, MemoryKind}; +use rustc_middle::mir::interpret::{AllocId, Allocation, InterpResult, Pointer}; +use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; +use rustc_span::def_id::DefId; use std::ops::ControlFlow; +use super::MPlaceTy; + /// Checks whether a type contains generic parameters which must be instantiated. /// /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization @@ -73,3 +79,23 @@ where Ok(()) } } + +pub(crate) fn take_static_root_alloc<'mir, 'tcx: 'mir>( + ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, + alloc_id: AllocId, +) -> Allocation { + ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1 +} + +pub(crate) fn create_static_alloc<'mir, 'tcx: 'mir>( + ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, + static_def_id: DefId, + layout: TyAndLayout<'tcx>, +) -> InterpResult<'tcx, MPlaceTy<'tcx>> { + let alloc = Allocation::try_uninit(layout.size, layout.align.abi)?; + let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id); + assert_eq!(ecx.machine.static_root_alloc_id, None); + ecx.machine.static_root_alloc_id = Some(alloc_id); + assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none()); + Ok(ecx.ptr_with_meta_to_mplace(Pointer::from(alloc_id).into(), MemPlaceMeta::None, layout)) +} diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index eb9f3fee165..08a2e38bfa1 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -27,9 +27,9 @@ use rustc_target::abi::{ use std::hash::Hash; use super::{ - format_interp_error, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, - InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, - ValueVisitor, + format_interp_error, machine::AllocMap, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, + Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, + Scalar, ValueVisitor, }; // for the validation errors @@ -712,11 +712,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' fn in_mutable_memory(&self, op: &OpTy<'tcx, M::Provenance>) -> bool { if let Some(mplace) = op.as_mplace_or_imm().left() { if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) { - if self.ecx.tcx.global_alloc(alloc_id).unwrap_memory().inner().mutability - == Mutability::Mut - { - return true; - } + let mutability = match self.ecx.tcx.global_alloc(alloc_id) { + GlobalAlloc::Static(_) => { + self.ecx.memory.alloc_map.get(alloc_id).unwrap().1.mutability + } + GlobalAlloc::Memory(alloc) => alloc.inner().mutability, + _ => span_bug!(self.ecx.tcx.span, "not a memory allocation"), + }; + return mutability == Mutability::Mut; } } false diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 839cfd8d85a..e33f374c359 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -40,6 +40,7 @@ pub fn provide(providers: &mut Providers) { const_eval::provide(providers); providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; + providers.eval_static_initializer = const_eval::eval_static_initializer_provider; providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider; providers.eval_to_valtree = |tcx, param_env_and_value| { let (param_env, raw) = param_env_and_value.into_parts(); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 5ce6a71c4bd..1ff72516324 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -98,6 +98,26 @@ impl<'tcx> MirPass<'tcx> for Validator { } } } + + // Enforce that coroutine-closure layouts are identical. + if let Some(layout) = body.coroutine_layout() + && let Some(by_move_body) = body.coroutine_by_move_body() + && let Some(by_move_layout) = by_move_body.coroutine_layout() + { + if layout != by_move_layout { + // If this turns out not to be true, please let compiler-errors know. + // It is possible to support, but requires some changes to the layout + // computation code. + cfg_checker.fail( + Location::START, + format!( + "Coroutine layout differs from by-move coroutine layout:\n\ + layout: {layout:#?}\n\ + by_move_layout: {by_move_layout:#?}", + ), + ); + } + } } } @@ -117,18 +137,14 @@ struct CfgChecker<'a, 'tcx> { impl<'a, 'tcx> CfgChecker<'a, 'tcx> { #[track_caller] fn fail(&self, location: Location, msg: impl AsRef<str>) { - let span = self.body.source_info(location).span; - // We use `span_delayed_bug` as we might see broken MIR when other errors have already - // occurred. - self.tcx.dcx().span_delayed_bug( - span, - format!( - "broken MIR in {:?} ({}) at {:?}:\n{}", - self.body.source.instance, - self.when, - location, - msg.as_ref() - ), + // We might see broken MIR when other errors have already occurred. + assert!( + self.tcx.dcx().has_errors().is_some(), + "broken MIR in {:?} ({}) at {:?}:\n{}", + self.body.source.instance, + self.when, + location, + msg.as_ref(), ); } diff --git a/compiler/rustc_data_structures/src/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs index 349fd7f9769..809ce3d4483 100644 --- a/compiler/rustc_data_structures/src/small_c_str.rs +++ b/compiler/rustc_data_structures/src/small_c_str.rs @@ -82,6 +82,6 @@ impl<'a> FromIterator<&'a str> for SmallCStr { impl From<&ffi::CStr> for SmallCStr { fn from(s: &ffi::CStr) -> Self { - Self { data: SmallVec::from_slice(s.to_bytes()) } + Self { data: SmallVec::from_slice(s.to_bytes_with_nul()) } } } diff --git a/compiler/rustc_data_structures/src/small_c_str/tests.rs b/compiler/rustc_data_structures/src/small_c_str/tests.rs index 47277604b2b..7b975dadcb7 100644 --- a/compiler/rustc_data_structures/src/small_c_str/tests.rs +++ b/compiler/rustc_data_structures/src/small_c_str/tests.rs @@ -43,3 +43,11 @@ fn long() { fn internal_nul() { let _ = SmallCStr::new("abcd\0def"); } + +#[test] +fn from_cstr() { + let c = c"foo"; + let s: SmallCStr = c.into(); + assert_eq!(s.len_with_nul(), 4); + assert_eq!(s.as_c_str(), c"foo"); +} diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index e174cba7813..a1abe8fd4f3 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -376,7 +376,7 @@ impl From<Cow<'static, str>> for DiagnosticMessage { } } -/// A workaround for good_path_delayed_bug ICEs when formatting types in disabled lints. +/// A workaround for must_produce_diag ICEs when formatting types in disabled lints. /// /// Delays formatting until `.into(): DiagnosticMessage` is used. pub struct DelayDm<F>(pub F); diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 37f568f12a7..1a34a83c1a4 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -85,11 +85,7 @@ fn source_string(file: Lrc<SourceFile>, line: &Line) -> String { /// Maps `Diagnostic::Level` to `snippet::AnnotationType` fn annotation_type_for_level(level: Level) -> AnnotationType { match level { - Level::Bug - | Level::Fatal - | Level::Error - | Level::DelayedBug - | Level::GoodPathDelayedBug => AnnotationType::Error, + Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => AnnotationType::Error, Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning, Level::Note | Level::OnceNote => AnnotationType::Note, Level::Help | Level::OnceHelp => AnnotationType::Help, diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 2deb18484ec..b14a12175c7 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -237,8 +237,7 @@ impl Diagnostic { match self.level { Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true, - Level::GoodPathDelayedBug - | Level::ForceWarning(_) + Level::ForceWarning(_) | Level::Warning | Level::Note | Level::OnceNote diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index edcc23db6de..afb1b854e72 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1635,7 +1635,8 @@ impl HumanEmitter { let mut to_add = FxHashMap::default(); for (depth, style) in depths { - if multilines.remove(&depth).is_none() { + // FIXME(#120456) - is `swap_remove` correct? + if multilines.swap_remove(&depth).is_none() { to_add.insert(depth, style); } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 2a0eddf6a0f..b0db3545ae7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -78,6 +78,7 @@ use std::fmt; use std::hash::Hash; use std::io::Write; use std::num::NonZeroUsize; +use std::ops::DerefMut; use std::panic; use std::path::{Path, PathBuf}; @@ -436,7 +437,6 @@ struct DiagCtxtInner { lint_err_guars: Vec<ErrorGuaranteed>, /// The delayed bugs and their error guarantees. delayed_bugs: Vec<(DelayedDiagnostic, ErrorGuaranteed)>, - good_path_delayed_bugs: Vec<DelayedDiagnostic>, /// The number of stashed errors. Unlike the other counts, this can go up /// and down, so it doesn't guarantee anything. @@ -447,13 +447,18 @@ struct DiagCtxtInner { /// The warning count shown to the user at the end. deduplicated_warn_count: usize, + emitter: Box<DynEmitter>, + + /// Must we produce a diagnostic to justify the use of the expensive + /// `trimmed_def_paths` function? + must_produce_diag: bool, + /// Has this diagnostic context printed any diagnostics? (I.e. has /// `self.emitter.emit_diagnostic()` been called? has_printed: bool, - emitter: Box<DynEmitter>, /// This flag indicates that an expected diagnostic was emitted and suppressed. - /// This is used for the `good_path_delayed_bugs` check. + /// This is used for the `must_produce_diag` check. suppressed_expected_diag: bool, /// This set contains the code of all emitted diagnostics to avoid @@ -534,11 +539,6 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) { pub static TRACK_DIAGNOSTIC: AtomicRef<fn(Diagnostic, &mut dyn FnMut(Diagnostic))> = AtomicRef::new(&(default_track_diagnostic as _)); -enum DelayedBugKind { - Normal, - GoodPath, -} - #[derive(Copy, Clone, Default)] pub struct DiagCtxtFlags { /// If false, warning-level lints are suppressed. @@ -564,11 +564,16 @@ impl Drop for DiagCtxtInner { self.emit_stashed_diagnostics(); if self.err_guars.is_empty() { - self.flush_delayed(DelayedBugKind::Normal) + self.flush_delayed() } if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() { - self.flush_delayed(DelayedBugKind::GoodPath); + if self.must_produce_diag { + panic!( + "must_produce_diag: trimmed_def_paths called but no diagnostics emitted; \ + use `DelayDm` for lints or `with_no_trimmed_paths` for debugging" + ); + } } if self.check_unstable_expect_diagnostics { @@ -610,12 +615,12 @@ impl DiagCtxt { err_guars: Vec::new(), lint_err_guars: Vec::new(), delayed_bugs: Vec::new(), - good_path_delayed_bugs: Vec::new(), stashed_err_count: 0, deduplicated_err_count: 0, deduplicated_warn_count: 0, - has_printed: false, emitter, + must_produce_diag: false, + has_printed: false, suppressed_expected_diag: false, taught_diagnostics: Default::default(), emitted_diagnostic_codes: Default::default(), @@ -663,21 +668,51 @@ impl DiagCtxt { /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as /// the overall count of emitted error diagnostics. pub fn reset_err_count(&self) { + // Use destructuring so that if a field gets added to `DiagCtxtInner`, it's impossible to + // fail to update this method as well. let mut inner = self.inner.borrow_mut(); - inner.stashed_err_count = 0; - inner.deduplicated_err_count = 0; - inner.deduplicated_warn_count = 0; - inner.has_printed = false; - - // actually free the underlying memory (which `clear` would not do) - inner.err_guars = Default::default(); - inner.lint_err_guars = Default::default(); - inner.delayed_bugs = Default::default(); - inner.good_path_delayed_bugs = Default::default(); - inner.taught_diagnostics = Default::default(); - inner.emitted_diagnostic_codes = Default::default(); - inner.emitted_diagnostics = Default::default(); - inner.stashed_diagnostics = Default::default(); + let DiagCtxtInner { + flags: _, + err_guars, + lint_err_guars, + delayed_bugs, + stashed_err_count, + deduplicated_err_count, + deduplicated_warn_count, + emitter: _, + must_produce_diag, + has_printed, + suppressed_expected_diag, + taught_diagnostics, + emitted_diagnostic_codes, + emitted_diagnostics, + stashed_diagnostics, + future_breakage_diagnostics, + check_unstable_expect_diagnostics, + unstable_expect_diagnostics, + fulfilled_expectations, + ice_file: _, + } = inner.deref_mut(); + + // For the `Vec`s and `HashMap`s, we overwrite with an empty container to free the + // underlying memory (which `clear` would not do). + *err_guars = Default::default(); + *lint_err_guars = Default::default(); + *delayed_bugs = Default::default(); + *stashed_err_count = 0; + *deduplicated_err_count = 0; + *deduplicated_warn_count = 0; + *must_produce_diag = false; + *has_printed = false; + *suppressed_expected_diag = false; + *taught_diagnostics = Default::default(); + *emitted_diagnostic_codes = Default::default(); + *emitted_diagnostics = Default::default(); + *stashed_diagnostics = Default::default(); + *future_breakage_diagnostics = Default::default(); + *check_unstable_expect_diagnostics = false; + *unstable_expect_diagnostics = Default::default(); + *fulfilled_expectations = Default::default(); } /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key. @@ -703,7 +738,8 @@ impl DiagCtxt { pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> { let mut inner = self.inner.borrow_mut(); let key = (span.with_parent(None), key); - let diag = inner.stashed_diagnostics.remove(&key)?; + // FIXME(#120456) - is `swap_remove` correct? + let diag = inner.stashed_diagnostics.swap_remove(&key)?; if diag.is_error() { if diag.is_lint.is_none() { inner.stashed_err_count -= 1; @@ -776,11 +812,12 @@ impl DiagCtxt { match (errors.len(), warnings.len()) { (0, 0) => return, (0, _) => { - // Use `inner.emitter` directly, otherwise the warning might not be emitted, e.g. - // with a configuration like `--cap-lints allow --force-warn bare_trait_objects`. - inner - .emitter - .emit_diagnostic(Diagnostic::new(Warning, DiagnosticMessage::Str(warnings))); + // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a + // configuration like `--cap-lints allow --force-warn bare_trait_objects`. + inner.emit_diagnostic(Diagnostic::new( + ForceWarning(None), + DiagnosticMessage::Str(warnings), + )); } (_, 0) => { inner.emit_diagnostic(Diagnostic::new(Error, errors)); @@ -808,20 +845,23 @@ impl DiagCtxt { error_codes.sort(); if error_codes.len() > 1 { let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; - inner.failure_note(format!( + let msg1 = format!( "Some errors have detailed explanations: {}{}", error_codes[..limit].join(", "), if error_codes.len() > 9 { "..." } else { "." } - )); - inner.failure_note(format!( + ); + let msg2 = format!( "For more information about an error, try `rustc --explain {}`.", &error_codes[0] - )); + ); + inner.emit_diagnostic(Diagnostic::new(FailureNote, msg1)); + inner.emit_diagnostic(Diagnostic::new(FailureNote, msg2)); } else { - inner.failure_note(format!( + let msg = format!( "For more information about this error, try `rustc --explain {}`.", &error_codes[0] - )); + ); + inner.emit_diagnostic(Diagnostic::new(FailureNote, msg)); } } } @@ -844,10 +884,6 @@ impl DiagCtxt { self.inner.borrow_mut().taught_diagnostics.insert(code) } - pub fn force_print_diagnostic(&self, db: Diagnostic) { - self.inner.borrow_mut().emitter.emit_diagnostic(db); - } - pub fn emit_diagnostic(&self, diagnostic: Diagnostic) -> Option<ErrorGuaranteed> { self.inner.borrow_mut().emit_diagnostic(diagnostic) } @@ -935,7 +971,13 @@ impl DiagCtxt { } pub fn flush_delayed(&self) { - self.inner.borrow_mut().flush_delayed(DelayedBugKind::Normal); + self.inner.borrow_mut().flush_delayed(); + } + + /// Used when trimmed_def_paths is called and we must produce a diagnostic + /// to justify its cost. + pub fn set_must_produce_diag(&self) { + self.inner.borrow_mut().must_produce_diag = true; } } @@ -1109,13 +1151,6 @@ impl DiagCtxt { DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit() } - /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`. - // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. - #[track_caller] - pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) { - DiagnosticBuilder::<()>::new(self, GoodPathDelayedBug, msg).emit() - } - #[rustc_lint_diagnostics] #[track_caller] pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { @@ -1176,7 +1211,7 @@ impl DiagCtxt { span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Note, msg).with_span(span) + self.struct_note(msg).with_span(span) } #[rustc_lint_diagnostics] @@ -1206,6 +1241,15 @@ impl DiagCtxt { #[rustc_lint_diagnostics] #[track_caller] + pub fn struct_failure_note( + &self, + msg: impl Into<DiagnosticMessage>, + ) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, FailureNote, msg) + } + + #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Allow, msg) } @@ -1267,42 +1311,39 @@ impl DiagCtxtInner { if diagnostic.has_future_breakage() { // Future breakages aren't emitted if they're Level::Allow, // but they still need to be constructed and stashed below, - // so they'll trigger the good-path bug check. + // so they'll trigger the must_produce_diag check. self.suppressed_expected_diag = true; self.future_breakage_diagnostics.push(diagnostic.clone()); } - if matches!(diagnostic.level, DelayedBug | GoodPathDelayedBug) - && self.flags.eagerly_emit_delayed_bugs - { + // Note that because this comes before the `match` below, + // `-Zeagerly-emit-delayed-bugs` continues to work even after we've + // issued an error and stopped recording new delayed bugs. + if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs { diagnostic.level = Error; } match diagnostic.level { - // This must come after the possible promotion of `DelayedBug`/`GoodPathDelayedBug` to + // This must come after the possible promotion of `DelayedBug` to // `Error` above. Fatal | Error if self.treat_next_err_as_bug() => { diagnostic.level = Bug; } DelayedBug => { - // FIXME(eddyb) this should check for `has_errors` and stop pushing - // once *any* errors were emitted (and truncate `delayed_bugs` - // when an error is first emitted, also), but maybe there's a case - // in which that's not sound? otherwise this is really inefficient. - let backtrace = std::backtrace::Backtrace::capture(); - // This `unchecked_error_guaranteed` is valid. It is where the - // `ErrorGuaranteed` for delayed bugs originates. - #[allow(deprecated)] - let guar = ErrorGuaranteed::unchecked_error_guaranteed(); - self.delayed_bugs - .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar)); - return Some(guar); - } - GoodPathDelayedBug => { - let backtrace = std::backtrace::Backtrace::capture(); - self.good_path_delayed_bugs - .push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); - return None; + // If we have already emitted at least one error, we don't need + // to record the delayed bug, because it'll never be used. + return if let Some(guar) = self.has_errors_or_lint_errors() { + Some(guar) + } else { + let backtrace = std::backtrace::Backtrace::capture(); + // This `unchecked_error_guaranteed` is valid. It is where the + // `ErrorGuaranteed` for delayed bugs originates. + #[allow(deprecated)] + let guar = ErrorGuaranteed::unchecked_error_guaranteed(); + self.delayed_bugs + .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar)); + Some(guar) + }; } Warning if !self.flags.can_emit_warnings => { if diagnostic.has_future_breakage() { @@ -1368,6 +1409,16 @@ impl DiagCtxtInner { } if is_error { + // If we have any delayed bugs recorded, we can discard them + // because they won't be used. (This should only occur if there + // have been no errors previously emitted, because we don't add + // new delayed bugs once the first error is emitted.) + if !self.delayed_bugs.is_empty() { + assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0); + self.delayed_bugs.clear(); + self.delayed_bugs.shrink_to_fit(); + } + // This `unchecked_error_guaranteed` is valid. It is where the // `ErrorGuaranteed` for errors and lint errors originates. #[allow(deprecated)] @@ -1411,27 +1462,14 @@ impl DiagCtxtInner { .or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied()) } - fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) { - self.emit_diagnostic(Diagnostic::new(FailureNote, msg)); - } - - fn flush_delayed(&mut self, kind: DelayedBugKind) { - let (bugs, note1) = match kind { - DelayedBugKind::Normal => ( - std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(), - "no errors encountered even though delayed bugs were created", - ), - DelayedBugKind::GoodPath => ( - std::mem::take(&mut self.good_path_delayed_bugs), - "no warnings or errors encountered even though good path delayed bugs were created", - ), - }; - let note2 = "those delayed bugs will now be shown as internal compiler errors"; - - if bugs.is_empty() { + fn flush_delayed(&mut self) { + if self.delayed_bugs.is_empty() { return; } + let bugs: Vec<_> = + std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(); + // If backtraces are enabled, also print the query stack let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); for (i, bug) in bugs.into_iter().enumerate() { @@ -1455,6 +1493,8 @@ impl DiagCtxtInner { // frame them better (e.g. separate warnings from them). Also, // make it a note so it doesn't count as an error, because that // could trigger `-Ztreat-err-as-bug`, which we don't want. + let note1 = "no errors encountered even though delayed bugs were created"; + let note2 = "those delayed bugs will now be shown as internal compiler errors"; self.emit_diagnostic(Diagnostic::new(Note, note1)); self.emit_diagnostic(Diagnostic::new(Note, note2)); } @@ -1463,7 +1503,7 @@ impl DiagCtxtInner { if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner }; // "Undelay" the delayed bugs (into plain `Bug`s). - if !matches!(bug.level, DelayedBug | GoodPathDelayedBug) { + if bug.level != DelayedBug { // NOTE(eddyb) not panicking here because we're already producing // an ICE, and the more information the merrier. bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel { @@ -1535,7 +1575,6 @@ impl DelayedDiagnostic { /// Fatal yes FatalAbort/FatalError(*) yes - - /// Error yes ErrorGuaranteed yes - yes /// DelayedBug yes ErrorGuaranteed yes - - -/// GoodPathDelayedBug - () yes - - /// ForceWarning - () yes - lint-only /// Warning - () yes yes yes /// Note - () rare yes - @@ -1568,20 +1607,6 @@ pub enum Level { /// that should only be reached when compiling erroneous code. DelayedBug, - /// Like `DelayedBug`, but weaker: lets you register an error without emitting it. If - /// compilation ends without any other diagnostics being emitted (and without an expected lint - /// being suppressed), this will be emitted as a bug. Otherwise, it will be silently dropped. - /// I.e. "expect other diagnostics are emitted (or suppressed)" semantics. Useful on code paths - /// that should only be reached when emitting diagnostics, e.g. for expensive one-time - /// diagnostic formatting operations. - /// - /// FIXME(nnethercote) good path delayed bugs are semantically strange: if printed they produce - /// an ICE, but they don't satisfy `is_error` and they don't guarantee an error is emitted. - /// Plus there's the extra complication with expected (suppressed) lints. They have limited - /// use, and are used in very few places, and "good path" isn't a good name. It would be good - /// to remove them. - GoodPathDelayedBug, - /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation /// from finishing. /// @@ -1626,7 +1651,7 @@ impl Level { fn color(self) -> ColorSpec { let mut spec = ColorSpec::new(); match self { - Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => { + Bug | Fatal | Error | DelayedBug => { spec.set_fg(Some(Color::Red)).set_intense(true); } ForceWarning(_) | Warning => { @@ -1646,7 +1671,7 @@ impl Level { pub fn to_str(self) -> &'static str { match self { - Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error", + Bug | DelayedBug => "error: internal compiler error", Fatal | Error => "error", ForceWarning(_) | Warning => "warning", Note | OnceNote => "note", @@ -1671,8 +1696,8 @@ impl Level { // subdiagnostic message? fn can_be_top_or_sub(&self) -> (bool, bool) { match self { - Bug | DelayedBug | Fatal | Error | GoodPathDelayedBug | ForceWarning(_) - | FailureNote | Allow | Expect(_) => (true, false), + Bug | DelayedBug | Fatal | Error | ForceWarning(_) | FailureNote | Allow + | Expect(_) => (true, false), Warning | Note | Help => (true, true), diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index eec86c36aed..be4b6399e12 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -34,10 +34,10 @@ pub(super) fn failed_to_match_macro<'cx>( if try_success_result.is_ok() { // Nonterminal parser recovery might turn failed matches into successful ones, // but for that it must have emitted an error already - tracker - .cx - .dcx() - .span_delayed_bug(sp, "Macro matching returned a success on the second try"); + assert!( + tracker.cx.dcx().has_errors().is_some(), + "Macro matching returned a success on the second try" + ); } if let Some(result) = tracker.result { diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index a6ac8ecd950..cee7c84adb2 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { if self_ty.span.can_be_used_for_suggestions() { lint.multipart_suggestion_verbose( - "use `dyn`", + "if this is an object-safe trait, use `dyn`", sugg, Applicability::MachineApplicable, ); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a001044c3e5..98a27c5ed20 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -758,8 +758,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // since we should have emitten an error for them earlier, and they will // not be well-formed! if polarity == ty::ImplPolarity::Negative { - self.tcx().dcx().span_delayed_bug( - binding.span, + assert!( + self.tcx().dcx().has_errors().is_some(), "negative trait bounds should not have bindings", ); continue; diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index cbbf560076e..7705445ffaa 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -218,7 +218,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { for def_ids in associated_types.values_mut() { for (projection_bound, span) in &projection_bounds { let def_id = projection_bound.projection_def_id(); - def_ids.remove(&def_id); + // FIXME(#120456) - is `swap_remove` correct? + def_ids.swap_remove(&def_id); if tcx.generics_require_sized_self(def_id) { tcx.emit_node_span_lint( UNUSED_ASSOCIATED_TYPE_BOUNDS, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7f674a1e7e4..e7506cee60e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1865,13 +1865,13 @@ fn check_variances_for_type_defn<'tcx>( let hir_param = &hir_generics.params[index]; if ty_param.def_id != hir_param.def_id.into() { - // valid programs always have lifetimes before types in the generic parameter list + // Valid programs always have lifetimes before types in the generic parameter list. // ty_generics are normalized to be in this required order, and variances are built // from ty generics, not from hir generics. but we need hir generics to get - // a span out + // a span out. // - // if they aren't in the same order, then the user has written invalid code, and already - // got an error about it (or I'm wrong about this) + // If they aren't in the same order, then the user has written invalid code, and already + // got an error about it (or I'm wrong about this). tcx.dcx().span_delayed_bug( hir_param.span, "hir generics and ty generics in different order", diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 370c6c607d7..6c3a9b747ef 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -15,7 +15,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy, @@ -25,13 +25,14 @@ use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::collections::BTreeMap; -pub fn check_trait( - tcx: TyCtxt<'_>, +pub fn check_trait<'tcx>( + tcx: TyCtxt<'tcx>, trait_def_id: DefId, impl_def_id: LocalDefId, + impl_header: ty::ImplTraitHeader<'tcx>, ) -> Result<(), ErrorGuaranteed> { let lang_items = tcx.lang_items(); - let checker = Checker { tcx, trait_def_id, impl_def_id }; + let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header }; let mut res = checker.check(lang_items.drop_trait(), visit_implementation_of_drop); res = res.and(checker.check(lang_items.copy_trait(), visit_implementation_of_copy)); res = res.and( @@ -50,24 +51,25 @@ struct Checker<'tcx> { tcx: TyCtxt<'tcx>, trait_def_id: DefId, impl_def_id: LocalDefId, + impl_header: ty::ImplTraitHeader<'tcx>, } impl<'tcx> Checker<'tcx> { fn check( &self, trait_def_id: Option<DefId>, - f: impl FnOnce(TyCtxt<'tcx>, LocalDefId) -> Result<(), ErrorGuaranteed>, + f: impl FnOnce(&Self) -> Result<(), ErrorGuaranteed>, ) -> Result<(), ErrorGuaranteed> { - if Some(self.trait_def_id) == trait_def_id { f(self.tcx, self.impl_def_id) } else { Ok(()) } + if Some(self.trait_def_id) == trait_def_id { f(self) } else { Ok(()) } } } -fn visit_implementation_of_drop( - tcx: TyCtxt<'_>, - impl_did: LocalDefId, -) -> Result<(), ErrorGuaranteed> { +fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { + let tcx = checker.tcx; + let header = checker.impl_header; + let impl_did = checker.impl_def_id; // Destructors only work on local ADT types. - match tcx.type_of(impl_did).instantiate_identity().kind() { + match header.trait_ref.self_ty().kind() { ty::Adt(def, _) if def.did().is_local() => return Ok(()), ty::Error(_) => return Ok(()), _ => {} @@ -78,13 +80,13 @@ fn visit_implementation_of_drop( Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span })) } -fn visit_implementation_of_copy( - tcx: TyCtxt<'_>, - impl_did: LocalDefId, -) -> Result<(), ErrorGuaranteed> { +fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { + let tcx = checker.tcx; + let impl_header = checker.impl_header; + let impl_did = checker.impl_def_id; debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); - let self_type = tcx.type_of(impl_did).instantiate_identity(); + let self_type = impl_header.trait_ref.self_ty(); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); let param_env = tcx.param_env(impl_did); @@ -92,56 +94,58 @@ fn visit_implementation_of_copy( debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type); - if let ty::ImplPolarity::Negative = tcx.impl_polarity(impl_did) { + if let ty::ImplPolarity::Negative = impl_header.polarity { return Ok(()); } - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; - let cause = traits::ObligationCause::misc(span, impl_did); + let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did); match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) { Ok(()) => Ok(()), Err(CopyImplementationError::InfringingFields(fields)) => { + let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span)) } Err(CopyImplementationError::NotAnAdt) => { + let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span })) } Err(CopyImplementationError::HasDestructor) => { + let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span })) } } } -fn visit_implementation_of_const_param_ty( - tcx: TyCtxt<'_>, - impl_did: LocalDefId, -) -> Result<(), ErrorGuaranteed> { - let self_type = tcx.type_of(impl_did).instantiate_identity(); +fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { + let tcx = checker.tcx; + let header = checker.impl_header; + let impl_did = checker.impl_def_id; + let self_type = header.trait_ref.self_ty(); assert!(!self_type.has_escaping_bound_vars()); let param_env = tcx.param_env(impl_did); - if let ty::ImplPolarity::Negative = tcx.impl_polarity(impl_did) { + if let ty::ImplPolarity::Negative = header.polarity { return Ok(()); } - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; - let cause = traits::ObligationCause::misc(span, impl_did); + let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did); match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) { Ok(()) => Ok(()), Err(ConstParamTyImplementationError::InfrigingFields(fields)) => { + let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span)) } Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { + let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span })) } } } -fn visit_implementation_of_coerce_unsized( - tcx: TyCtxt<'_>, - impl_did: LocalDefId, -) -> Result<(), ErrorGuaranteed> { +fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { + let tcx = checker.tcx; + let impl_did = checker.impl_def_id; debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", impl_did); // Just compute this for the side-effects, in particular reporting @@ -151,20 +155,20 @@ fn visit_implementation_of_coerce_unsized( tcx.at(span).ensure().coerce_unsized_info(impl_did) } -fn visit_implementation_of_dispatch_from_dyn( - tcx: TyCtxt<'_>, - impl_did: LocalDefId, -) -> Result<(), ErrorGuaranteed> { +fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { + let tcx = checker.tcx; + let header = checker.impl_header; + let impl_did = checker.impl_def_id; + let trait_ref = header.trait_ref; debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); let span = tcx.def_span(impl_did); let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); - let source = tcx.type_of(impl_did).instantiate_identity(); + let source = trait_ref.self_ty(); assert!(!source.has_escaping_bound_vars()); let target = { - let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity(); assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait); trait_ref.args.type_at(1) diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 7f59763f2a0..d6281fa08f7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -23,6 +23,7 @@ fn check_impl( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<'_>, + trait_def: &ty::TraitDef, ) -> Result<(), ErrorGuaranteed> { debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", @@ -36,19 +37,20 @@ fn check_impl( return Ok(()); } - enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id) - .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id)) + enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id, trait_def) + .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id, trait_def)) } fn enforce_trait_manually_implementable( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_def_id: DefId, + trait_def: &ty::TraitDef, ) -> Result<(), ErrorGuaranteed> { let impl_header_span = tcx.def_span(impl_def_id); // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]` - if tcx.trait_def(trait_def_id).deny_explicit_impl { + if trait_def.deny_explicit_impl { let trait_name = tcx.item_name(trait_def_id); let mut err = struct_span_code_err!( tcx.dcx(), @@ -67,8 +69,7 @@ fn enforce_trait_manually_implementable( return Err(err.emit()); } - if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable = - tcx.trait_def(trait_def_id).specialization_kind + if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable = trait_def.specialization_kind { if !tcx.features().specialization && !tcx.features().min_specialization @@ -87,8 +88,9 @@ fn enforce_empty_impls_for_marker_traits( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_def_id: DefId, + trait_def: &ty::TraitDef, ) -> Result<(), ErrorGuaranteed> { - if !tcx.trait_def(trait_def_id).is_marker { + if !trait_def.is_marker { return Ok(()); } @@ -132,14 +134,15 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let mut res = tcx.ensure().specialization_graph_of(def_id); for &impl_def_id in impls { - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); + let trait_header = tcx.impl_trait_header(impl_def_id).unwrap().instantiate_identity(); + let trait_def = tcx.trait_def(trait_header.trait_ref.def_id); - res = res.and(check_impl(tcx, impl_def_id, trait_ref)); - res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref)); + res = res.and(check_impl(tcx, impl_def_id, trait_header.trait_ref, trait_def)); + res = res.and(check_object_overlap(tcx, impl_def_id, trait_header.trait_ref)); - res = res.and(unsafety::check_item(tcx, impl_def_id, trait_ref)); + res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)); res = res.and(tcx.ensure().orphan_check_impl(impl_def_id)); - res = res.and(builtin::check_trait(tcx, def_id, impl_def_id)); + res = res.and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); } res diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index d217d53587d..53a5ada4105 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -2,23 +2,23 @@ //! crate or pertains to a type defined in this crate. use rustc_errors::{codes::*, struct_span_code_err}; -use rustc_hir as hir; use rustc_hir::Unsafety; -use rustc_middle::ty::{TraitRef, TyCtxt}; +use rustc_middle::ty::{ImplPolarity::*, ImplTraitHeader, TraitDef, TyCtxt}; use rustc_span::def_id::LocalDefId; use rustc_span::ErrorGuaranteed; pub(super) fn check_item( tcx: TyCtxt<'_>, def_id: LocalDefId, - trait_ref: TraitRef<'_>, + trait_header: ImplTraitHeader<'_>, + trait_def: &TraitDef, ) -> Result<(), ErrorGuaranteed> { - let item = tcx.hir().expect_item(def_id); - let impl_ = item.expect_impl(); - let trait_def = tcx.trait_def(trait_ref.def_id); - let unsafe_attr = impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); - match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) { - (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { + let trait_ref = trait_header.trait_ref; + let unsafe_attr = + tcx.generics_of(def_id).params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); + match (trait_def.unsafety, unsafe_attr, trait_header.unsafety, trait_header.polarity) { + (Unsafety::Normal, None, Unsafety::Unsafe, Positive | Reservation) => { + let span = tcx.def_span(def_id); return Err(struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), @@ -27,7 +27,7 @@ pub(super) fn check_item( trait_ref.print_trait_sugared() ) .with_span_suggestion_verbose( - item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)), + span.with_hi(span.lo() + rustc_span::BytePos(7)), "remove `unsafe` from this trait implementation", "", rustc_errors::Applicability::MachineApplicable, @@ -35,10 +35,11 @@ pub(super) fn check_item( .emit()); } - (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => { + (Unsafety::Unsafe, _, Unsafety::Normal, Positive | Reservation) => { + let span = tcx.def_span(def_id); return Err(struct_span_code_err!( tcx.dcx(), - tcx.def_span(def_id), + span, E0200, "the trait `{}` requires an `unsafe impl` declaration", trait_ref.print_trait_sugared() @@ -50,7 +51,7 @@ pub(super) fn check_item( trait_ref.print_trait_sugared() )) .with_span_suggestion_verbose( - item.span.shrink_to_lo(), + span.shrink_to_lo(), "add `unsafe` to this trait implementation", "unsafe ", rustc_errors::Applicability::MaybeIncorrect, @@ -58,10 +59,11 @@ pub(super) fn check_item( .emit()); } - (Unsafety::Normal, Some(attr_name), Unsafety::Normal, hir::ImplPolarity::Positive) => { + (Unsafety::Normal, Some(attr_name), Unsafety::Normal, Positive | Reservation) => { + let span = tcx.def_span(def_id); return Err(struct_span_code_err!( tcx.dcx(), - tcx.def_span(def_id), + span, E0569, "requires an `unsafe impl` declaration due to `#[{}]` attribute", attr_name @@ -73,7 +75,7 @@ pub(super) fn check_item( trait_ref.print_trait_sugared() )) .with_span_suggestion_verbose( - item.span.shrink_to_lo(), + span.shrink_to_lo(), "add `unsafe` to this trait implementation", "unsafe ", rustc_errors::Applicability::MaybeIncorrect, @@ -81,14 +83,14 @@ pub(super) fn check_item( .emit()); } - (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => { + (_, _, Unsafety::Unsafe, Negative) => { // Reported in AST validation - tcx.dcx().span_delayed_bug(item.span, "unsafe negative impl"); + assert!(tcx.dcx().has_errors().is_some(), "unsafe negative impl"); Ok(()) } - (_, _, Unsafety::Normal, hir::ImplPolarity::Negative(_)) - | (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive) - | (Unsafety::Normal, Some(_), Unsafety::Unsafe, hir::ImplPolarity::Positive) + (_, _, Unsafety::Normal, Negative) + | (Unsafety::Unsafe, _, Unsafety::Unsafe, Positive | Reservation) + | (Unsafety::Normal, Some(_), Unsafety::Unsafe, Positive | Reservation) | (Unsafety::Normal, None, Unsafety::Normal, _) => Ok(()), } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e8787d159ae..4891dae47c6 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1539,6 +1539,7 @@ fn impl_trait_header( }; ty::EarlyBinder::bind(ty::ImplTraitHeader { trait_ref, + unsafety: impl_.unsafety, polarity: polarity_of_impl(tcx, def_id, impl_, item.span) }) }) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c9cf43ddfc8..287cb880908 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1873,7 +1873,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { lifetime_ref: &'tcx hir::Lifetime, bad_def: ResolvedArg, ) { - let old_value = self.map.defs.remove(&lifetime_ref.hir_id); + // FIXME(#120456) - is `swap_remove` correct? + let old_value = self.map.defs.swap_remove(&lifetime_ref.hir_id); assert_eq!(old_value, Some(bad_def)); } } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1aaefc5b520..1cd77050217 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -187,8 +187,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { } tcx.sess.time("wf_checking", || { - tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module)) - })?; + tcx.hir().par_for_each_module(|module| { + let _ = tcx.ensure().check_mod_type_wf(module); + }) + }); if tcx.features().rustc_attrs { collect::test_opaque_hidden_types(tcx)?; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f21de1609cb..9a8f287ec14 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -139,10 +139,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Never | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => { - let reported = self + let guar = self .dcx() .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); - return Err(reported); + return Err(guar); } }) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ec3d4ec66a0..ce8b62d19b4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1579,7 +1579,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ctxt = { let mut enclosing_breakables = self.enclosing_breakables.borrow_mut(); debug_assert!(enclosing_breakables.stack.len() == index + 1); - enclosing_breakables.by_id.remove(&id).expect("missing breakable context"); + // FIXME(#120456) - is `swap_remove` correct? + enclosing_breakables.by_id.swap_remove(&id).expect("missing breakable context"); enclosing_breakables.stack.pop().expect("missing breakable context") }; (ctxt, result) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index c1af4b5983e..629c2f2a971 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -304,6 +304,10 @@ fn typeck_with_fallback<'tcx>( let typeck_results = fcx.resolve_type_vars_in_body(body); + // We clone the defined opaque types during writeback in the new solver + // because we have to use them during normalization. + let _ = fcx.infcx.take_opaque_types(); + // Consistency check our TypeckResults instance can hold all ItemLocalIds // it will need to hold. assert_eq!(typeck_results.hir_owner, id.owner); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 4e9cb92919a..a580c114f26 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -518,12 +518,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { .report_mismatched_types(&cause, method_self_ty, self_ty, terr) .emit(); } else { - span_bug!( - self.span, - "{} was a subtype of {} but now is not?", - self_ty, - method_self_ty - ); + error!("{self_ty} was a subtype of {method_self_ty} but now is not?"); + // This must already have errored elsewhere. + self.dcx().has_errors().unwrap(); } } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 5ce80ef5c10..b83a0f893f5 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -221,8 +221,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if base_ty.is_none() { // When encountering `return [0][0]` outside of a `fn` body we can encounter a base // that isn't in the type table. We assume more relevant errors have already been - // emitted, so we delay an ICE if none have. (#64638) - self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`")); + // emitted. (#64638) + assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`"); } if let Some(base_ty) = base_ty && let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() @@ -562,7 +562,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_opaque_types(&mut self) { - let opaque_types = self.fcx.infcx.take_opaque_types(); + // We clone the opaques instead of stealing them here as they are still used for + // normalization in the next generation trait solver. + // + // FIXME(-Znext-solver): Opaque types defined after this would simply get dropped + // at the end of typeck. While this seems unlikely to happen in practice this + // should still get fixed. Either by preventing writeback from defining new opaque + // types or by using this function at the end of writeback and running it as a + // fixpoint. + let opaque_types = self.fcx.infcx.clone_opaque_types(); for (opaque_type_key, decl) in opaque_types { let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span); let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span); diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 859593e1194..05b9479c7b0 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -285,13 +285,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { T: Relate<'tcx>, { let Trace { at, trace, a_is_expected } = self; - at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); - fields - .sub(a_is_expected) - .relate(a, b) - .map(move |_| InferOk { value: (), obligations: fields.obligations }) - }) + let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); + fields + .sub(a_is_expected) + .relate(a, b) + .map(move |_| InferOk { value: (), obligations: fields.obligations }) } /// Makes `a == b`; the expectation is set by the call to @@ -302,13 +300,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { T: Relate<'tcx>, { let Trace { at, trace, a_is_expected } = self; - at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); - fields - .equate(a_is_expected) - .relate(a, b) - .map(move |_| InferOk { value: (), obligations: fields.obligations }) - }) + let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); + fields + .equate(a_is_expected) + .relate(a, b) + .map(move |_| InferOk { value: (), obligations: fields.obligations }) } #[instrument(skip(self), level = "debug")] @@ -317,13 +313,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { T: Relate<'tcx>, { let Trace { at, trace, a_is_expected } = self; - at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); - fields - .lub(a_is_expected) - .relate(a, b) - .map(move |t| InferOk { value: t, obligations: fields.obligations }) - }) + let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); + fields + .lub(a_is_expected) + .relate(a, b) + .map(move |t| InferOk { value: t, obligations: fields.obligations }) } #[instrument(skip(self), level = "debug")] @@ -332,13 +326,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { T: Relate<'tcx>, { let Trace { at, trace, a_is_expected } = self; - at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); - fields - .glb(a_is_expected) - .relate(a, b) - .map(move |t| InferOk { value: t, obligations: fields.obligations }) - }) + let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); + fields + .glb(a_is_expected) + .relate(a, b) + .map(move |t| InferOk { value: t, obligations: fields.obligations }) } } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 216b2e70abf..56a45586c9d 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -620,42 +620,40 @@ impl<'tcx> InferCtxt<'tcx> { variables1: &OriginalQueryValues<'tcx>, variables2: impl Fn(BoundVar) -> GenericArg<'tcx>, ) -> InferResult<'tcx, ()> { - self.commit_if_ok(|_| { - let mut obligations = vec![]; - for (index, value1) in variables1.var_values.iter().enumerate() { - let value2 = variables2(BoundVar::new(index)); - - match (value1.unpack(), value2.unpack()) { - (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => { - obligations.extend( - self.at(cause, param_env) - .eq(DefineOpaqueTypes::Yes, v1, v2)? - .into_obligations(), - ); - } - (GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2)) - if re1.is_erased() && re2.is_erased() => - { - // no action needed - } - (GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => { - obligations.extend( - self.at(cause, param_env) - .eq(DefineOpaqueTypes::Yes, v1, v2)? - .into_obligations(), - ); - } - (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => { - let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?; - obligations.extend(ok.into_obligations()); - } - _ => { - bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,); - } + let mut obligations = vec![]; + for (index, value1) in variables1.var_values.iter().enumerate() { + let value2 = variables2(BoundVar::new(index)); + + match (value1.unpack(), value2.unpack()) { + (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => { + obligations.extend( + self.at(cause, param_env) + .eq(DefineOpaqueTypes::Yes, v1, v2)? + .into_obligations(), + ); + } + (GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2)) + if re1.is_erased() && re2.is_erased() => + { + // no action needed + } + (GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => { + obligations.extend( + self.at(cause, param_env) + .eq(DefineOpaqueTypes::Yes, v1, v2)? + .into_obligations(), + ); + } + (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => { + let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?; + obligations.extend(ok.into_obligations()); + } + _ => { + bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,); } } - Ok(InferOk { value: (), obligations }) - }) + } + Ok(InferOk { value: (), obligations }) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 4d2d19b51e2..b953b25d6c4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -132,20 +132,6 @@ pub struct TypeErrCtxt<'a, 'tcx> { Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>, } -impl Drop for TypeErrCtxt<'_, '_> { - fn drop(&mut self) { - if self.dcx().has_errors().is_some() { - // Ok, emitted an error. - } else { - // Didn't emit an error; maybe it was created but not yet emitted. - self.infcx - .tcx - .sess - .good_path_delayed_bug("used a `TypeErrCtxt` without raising an error or lint"); - } - } -} - impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn dcx(&self) -> &'tcx DiagCtxt { self.infcx.tcx.dcx() diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 6137506d4a9..c39d0425f7e 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -802,14 +802,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } // Errors in earlier passes can yield error variables without - // resolution errors here; delay ICE in favor of those errors. - self.tcx().dcx().span_delayed_bug( - self.var_infos[node_idx].origin.span(), - format!( - "collect_error_for_expanding_node() could not find \ - error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \ - upper_bounds={upper_bounds:#?}" - ), + // resolution errors here; ICE if no errors have been emitted yet. + assert!( + self.tcx().dcx().has_errors().is_some(), + "collect_error_for_expanding_node() could not find error for var {node_idx:?} in \ + universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \ + upper_bounds={upper_bounds:#?}", ); } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 0bf4598608f..2caf3b3cc93 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1325,6 +1325,12 @@ impl<'tcx> InferCtxt<'tcx> { std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types) } + #[instrument(level = "debug", skip(self), ret)] + pub fn clone_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> { + debug_assert_ne!(self.defining_use_anchor, DefiningAnchor::Error); + self.inner.borrow().opaque_type_storage.opaque_types.clone() + } + pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { self.resolve_vars_if_possible(t).to_string() } diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index 6a684dba8de..9f49ed00219 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -20,7 +20,8 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { if let Some(idx) = idx { self.opaque_types.get_mut(&key).unwrap().hidden_type = idx; } else { - match self.opaque_types.remove(&key) { + // FIXME(#120456) - is `swap_remove` correct? + match self.opaque_types.swap_remove(&key) { None => bug!("reverted opaque type inference that was never registered: {:?}", key), Some(_) => {} } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 7208f17fb34..c0a99e5cc41 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -300,9 +300,9 @@ where self.components_must_outlive(origin, subcomponents, region, category); } Component::UnresolvedInferenceVariable(v) => { - // ignore this, we presume it will yield an error - // later, since if a type variable is not resolved by - // this point it never will be + // Ignore this, we presume it will yield an error later, + // since if a type variable is not resolved by this point + // it never will be. self.tcx.dcx().span_delayed_bug( origin.span(), format!("unresolved inference variable in outlives: {v:?}"), diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 24b351988bf..3ef37bf3466 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -172,13 +172,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { self.bound_from_components(components, visited) } Component::UnresolvedInferenceVariable(v) => { - // ignore this, we presume it will yield an error - // later, since if a type variable is not resolved by - // this point it never will be + // Ignore this, we presume it will yield an error later, since + // if a type variable is not resolved by this point it never + // will be. self.tcx .dcx() .delayed_bug(format!("unresolved inference variable in outlives: {v:?}")); - // add a bound that never holds + // Add a bound that never holds. VerifyBound::AnyBound(vec![]) } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 5ae080d4702..0862204d88e 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -431,14 +431,13 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>( // If not, that means that we somehow buffered a lint for a node id // that was not lint-checked (perhaps it doesn't exist?). This is a bug. for (id, lints) in cx.context.buffered.map { - for early_lint in lints { - sess.dcx().span_delayed_bug( - early_lint.span, - format!( - "failed to process buffered lint here (dummy = {})", - id == ast::DUMMY_NODE_ID - ), + if !lints.is_empty() { + assert!( + sess.dcx().has_errors().is_some(), + "failed to process buffered lint here (dummy = {})", + id == ast::DUMMY_NODE_ID ); + break; } } } diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 519ab8bd50f..f386db9d8db 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -207,6 +207,13 @@ fn is_cast_to_bigger_memory_layout<'tcx>( } let from_layout = cx.layout_of(*inner_start_ty).ok()?; + + // if the type isn't sized, we bail out, instead of potentially giving + // the user a meaningless warning. + if from_layout.is_unsized() { + return None; + } + let alloc_layout = cx.layout_of(alloc_ty).ok()?; let to_layout = cx.layout_of(*inner_end_ty).ok()?; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 9f670893b27..35ee0c53046 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -651,9 +651,11 @@ trait UnusedDelimLint { fn is_expr_delims_necessary( inner: &ast::Expr, + ctx: UnusedDelimsCtx, followed_by_block: bool, - followed_by_else: bool, ) -> bool { + let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse; + if followed_by_else { match inner.kind { ast::ExprKind::Binary(op, ..) if op.node.is_lazy() => return true, @@ -662,6 +664,13 @@ trait UnusedDelimLint { } } + // Check it's range in LetScrutineeExpr + if let ast::ExprKind::Range(..) = inner.kind + && matches!(ctx, UnusedDelimsCtx::LetScrutineeExpr) + { + return true; + } + // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`. { let mut innermost = inner; @@ -1007,8 +1016,7 @@ impl UnusedDelimLint for UnusedParens { ) { match value.kind { ast::ExprKind::Paren(ref inner) => { - let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse; - if !Self::is_expr_delims_necessary(inner, followed_by_block, followed_by_else) + if !Self::is_expr_delims_necessary(inner, ctx, followed_by_block) && value.attrs.is_empty() && !value.span.from_expansion() && (ctx != UnusedDelimsCtx::LetScrutineeExpr @@ -1334,7 +1342,7 @@ impl UnusedDelimLint for UnusedBraces { // FIXME(const_generics): handle paths when #67075 is fixed. if let [stmt] = inner.stmts.as_slice() { if let ast::StmtKind::Expr(ref expr) = stmt.kind { - if !Self::is_expr_delims_necessary(expr, followed_by_block, false) + if !Self::is_expr_delims_necessary(expr, ctx, followed_by_block) && (ctx != UnusedDelimsCtx::AnonConst || (matches!(expr.kind, ast::ExprKind::Lit(_)) && !expr.span.from_expansion())) diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7ed78a2ffc8..09b1f03f151 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -708,7 +708,8 @@ impl LintBuffer { } pub fn take(&mut self, id: NodeId) -> Vec<BufferedEarlyLint> { - self.map.remove(&id).unwrap_or_default() + // FIXME(#120456) - is `swap_remove` correct? + self.map.swap_remove(&id).unwrap_or_default() } pub fn buffer_lint( diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 58e219e5a46..6598f1db86d 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -8,7 +8,12 @@ edition = "2021" libc = "0.2.73" # tidy-alphabetical-end +# FIXME: updating cc past 1.0.79 breaks libstd bootstrapping, pin +# to the last working version here so `cargo update` doesn't cause the +# a higher version to be selected +# https://github.com/rust-lang/cc-rs/issues/913 +# 1.0.{84, 85} fix this but have been yanked [build-dependencies] # tidy-alphabetical-start -cc = "1.0.69" +cc = "=1.0.79" # tidy-alphabetical-end diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 373bc5cc581..627be997513 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -139,7 +139,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer( RustMappingRegions, NumMappingRegions)) { MappingRegions.emplace_back( fromRust(Region.Count), fromRust(Region.FalseCount), -#if LLVM_VERSION_GE(18, 0) +#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0) coverage::CounterMappingRegion::MCDCParameters{}, #endif Region.FileID, Region.ExpandedFileID, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index d79d4b226a5..178bfc3a380 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -250,6 +250,15 @@ provide! { tcx, def_id, other, cdata, fn_arg_names => { table } coroutine_kind => { table_direct } coroutine_for_closure => { table } + eval_static_initializer => { + Ok(cdata + .root + .tables + .eval_static_initializer + .get(cdata, def_id.index) + .map(|lazy| lazy.decode((cdata, tcx))) + .unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer"))) + } trait_def => { table } deduced_param_attrs => { table } is_type_alias_impl_trait => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4a24c038f7a..6f908f7752a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1045,11 +1045,9 @@ fn should_encode_mir( (true, mir_opt_base) } // Constants - DefKind::AnonConst - | DefKind::InlineConst - | DefKind::AssocConst - | DefKind::Static(..) - | DefKind::Const => (true, false), + DefKind::AnonConst | DefKind::InlineConst | DefKind::AssocConst | DefKind::Const => { + (true, false) + } // Coroutines require optimized MIR to compute layout. DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true), // Full-fledged functions + closures @@ -1454,6 +1452,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .coroutine_for_closure .set_some(def_id.index, self.tcx.coroutine_for_closure(def_id).into()); } + if let DefKind::Static(_) = def_kind { + if !self.tcx.is_foreign_item(def_id) { + let data = self.tcx.eval_static_initializer(def_id).unwrap(); + record!(self.tables.eval_static_initializer[def_id] <- data); + } + } if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind { self.encode_info_for_adt(local_id); } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4d0a6cb60ee..eac78a3cd7c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -443,6 +443,7 @@ define_tables! { fn_arg_names: Table<DefIndex, LazyArray<Ident>>, coroutine_kind: Table<DefIndex, hir::CoroutineKind>, coroutine_for_closure: Table<DefIndex, RawDefId>, + eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>, trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>, trait_item_def_id: Table<DefIndex, RawDefId>, expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>, diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 6ffa0819f35..2a6f473cd32 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -207,6 +207,11 @@ pub fn explain_lint_level_source( err: &mut Diagnostic, ) { let name = lint.name_lower(); + if let Level::Allow = level { + // Do not point at `#[allow(compat_lint)]` as the reason for a compatibility lint + // triggering. (#121009) + return; + } match src { LintLevelSource::Default => { err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name)); diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index a1cdc794749..9d4ec7d25bb 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,4 +1,4 @@ -use super::{AllocId, AllocRange, Pointer, Scalar}; +use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar}; use crate::error; use crate::mir::{ConstAlloc, ConstValue}; @@ -83,6 +83,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo { TrivialTypeTraversalImpls! { ErrorHandled } pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>; +pub type EvalStaticInitializerRawResult<'tcx> = Result<ConstAllocation<'tcx>, ErrorHandled>; pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>; /// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed. /// This is needed in `thir::pattern::lower_inline_const`. diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 0da3524e055..ec2af393639 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -142,11 +142,12 @@ use crate::ty::GenericArgKind; use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ - BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, - EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo, - InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, Misalignment, PointerKind, - ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, - UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, + BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult, + EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, + InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo, + MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo, + ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, + ValidationErrorKind, }; pub use self::value::Scalar; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index e8aca5f2e7d..643b61c1de3 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,7 +1,7 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}; use crate::mir; -use crate::query::{TyCtxtAt, TyCtxtEnsure}; +use crate::query::TyCtxtEnsure; use crate::ty::visit::TypeVisitableExt; use crate::ty::GenericArgs; use crate::ty::{self, TyCtxt}; @@ -173,44 +173,6 @@ impl<'tcx> TyCtxt<'tcx> { self.eval_to_valtree(inputs) } } - - /// Evaluate a static's initializer, returning the allocation of the initializer's memory. - #[inline(always)] - pub fn eval_static_initializer( - self, - def_id: DefId, - ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> { - self.at(DUMMY_SP).eval_static_initializer(def_id) - } -} - -impl<'tcx> TyCtxtAt<'tcx> { - /// Evaluate a static's initializer, returning the allocation of the initializer's memory. - /// - /// The span is entirely ignored here, but still helpful for better query cycle errors. - pub fn eval_static_initializer( - self, - def_id: DefId, - ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> { - trace!("eval_static_initializer: Need to compute {:?}", def_id); - assert!(self.is_static(def_id)); - let instance = ty::Instance::mono(*self, def_id); - let gid = GlobalId { instance, promoted: None }; - self.eval_to_allocation(gid, ty::ParamEnv::reveal_all()) - } - - /// Evaluate anything constant-like, returning the allocation of the final memory. - /// - /// The span is entirely ignored here, but still helpful for better query cycle errors. - fn eval_to_allocation( - self, - gid: GlobalId<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> { - trace!("eval_to_allocation: Need to compute {:?}", gid); - let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; - Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) - } } impl<'tcx> TyCtxtEnsure<'tcx> { @@ -232,15 +194,4 @@ impl<'tcx> TyCtxtEnsure<'tcx> { let inputs = self.tcx.erase_regions(param_env.and(cid)); self.eval_to_const_value_raw(inputs) } - - /// Evaluate a static's initializer, returning the allocation of the initializer's memory. - pub fn eval_static_initializer(self, def_id: DefId) { - trace!("eval_static_initializer: Need to compute {:?}", def_id); - assert!(self.tcx.is_static(def_id)); - let instance = ty::Instance::mono(self.tcx, def_id); - let gid = GlobalId { instance, promoted: None }; - let param_env = ty::ParamEnv::reveal_all(); - trace!("eval_to_allocation: Need to compute {:?}", gid); - self.eval_to_allocation_raw(param_env.and(gid)) - } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e22d5228628..3017f912ef0 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2,7 +2,7 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html -use crate::mir::interpret::{AllocRange, ConstAllocation, Scalar}; +use crate::mir::interpret::{AllocRange, Scalar}; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a011f6114de..5638b575b31 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -4,6 +4,8 @@ use std::fs; use std::io::{self, Write as _}; use std::path::{Path, PathBuf}; +use crate::mir::interpret::ConstAllocation; + use super::graphviz::write_mir_fn_graphviz; use rustc_ast::InlineAsmTemplatePiece; use rustc_middle::mir::interpret::{ diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 90b6df1dd1f..8bd872c1b19 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -86,7 +86,8 @@ rustc_index::newtype_index! { pub struct CoroutineSavedLocal {} } -#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub struct CoroutineSavedTy<'tcx> { pub ty: Ty<'tcx>, /// Source info corresponding to the local in the original MIR body. @@ -96,7 +97,8 @@ pub struct CoroutineSavedTy<'tcx> { } /// The layout of coroutine state. -#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[derive(Clone, PartialEq, Eq)] +#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub struct CoroutineLayout<'tcx> { /// The type of every local stored inside the coroutine. pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 5666a59e38e..7ac7fa0ac33 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -337,6 +337,7 @@ tcx_lifetime! { rustc_middle::mir::ConstValue, rustc_middle::mir::interpret::GlobalId, rustc_middle::mir::interpret::LitToConstInput, + rustc_middle::mir::interpret::EvalStaticInitializerRawResult, rustc_middle::traits::query::MethodAutoderefStepsResult, rustc_middle::traits::query::type_op::AscribeUserType, rustc_middle::traits::query::type_op::Eq, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 60d195e4d3e..a7f4e75e214 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -20,7 +20,8 @@ use crate::middle::stability::{self, DeprecationEntry}; use crate::mir; use crate::mir::interpret::GlobalId; use crate::mir::interpret::{ - EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, + EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, + EvalToValTreeResult, }; use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; @@ -1061,7 +1062,7 @@ rustc_queries! { /// Evaluates a constant and returns the computed allocation. /// - /// **Do not use this** directly, use the `tcx.eval_static_initializer` wrapper. + /// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead. query eval_to_allocation_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> EvalToAllocationRawResult<'tcx> { desc { |tcx| @@ -1071,6 +1072,16 @@ rustc_queries! { cache_on_disk_if { true } } + /// Evaluate a static's initializer, returning the allocation of the initializer's memory. + query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> { + desc { |tcx| + "evaluating initializer of static `{}`", + tcx.def_path_str(key) + } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + /// Evaluates const items or anonymous constants /// (such as enum variant explicit discriminants or array lengths) /// into a representation suitable for the type system and const generics. diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 23771073745..5e4d899f517 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -35,6 +35,16 @@ impl<'tcx> IntoKind for Const<'tcx> { } } +impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> { + fn flags(&self) -> TypeFlags { + self.0.flags + } + + fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex { + self.0.outer_exclusive_binder + } +} + impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> { fn ty(self) -> Ty<'tcx> { self.ty() @@ -63,11 +73,13 @@ impl<'tcx> Const<'tcx> { self.0.kind } + // FIXME(compiler-errors): Think about removing this. #[inline] pub fn flags(self) -> TypeFlags { self.0.flags } + // FIXME(compiler-errors): Think about removing this. #[inline] pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex { self.0.outer_exclusive_binder diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bd86c1c284e..cc734e7157f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -28,7 +28,7 @@ use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind, ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, - Visibility, + TypeVisitable, Visibility, }; use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use rustc_ast::{self as ast, attr}; @@ -87,7 +87,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type GenericArg = ty::GenericArg<'tcx>; type Term = ty::Term<'tcx>; - type Binder<T> = Binder<'tcx, T>; + type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>; + type BoundVars = &'tcx List<ty::BoundVariableKind>; + type BoundVar = ty::BoundVariableKind; type CanonicalVars = CanonicalVarInfos<'tcx>; type Ty = Ty<'tcx>; @@ -151,6 +153,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) -> Self::Const { Const::new_bound(self, debruijn, var, ty) } + + fn expect_error_or_delayed_bug() { + let has_errors = ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs()); + assert!(has_errors.is_some()); + } } type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>; @@ -1046,12 +1053,22 @@ impl<'tcx> TyCtxtAt<'tcx> { name: Symbol, def_kind: DefKind, ) -> TyCtxtFeed<'tcx, LocalDefId> { - // This function modifies `self.definitions` using a side-effect. - // We need to ensure that these side effects are re-run by the incr. comp. engine. - // Depending on the forever-red node will tell the graph that the calling query - // needs to be re-evaluated. - self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + let feed = self.tcx.create_def(parent, name, def_kind); + feed.def_span(self.span); + feed + } +} + +impl<'tcx> TyCtxt<'tcx> { + /// `tcx`-dependent operations performed for every created definition. + pub fn create_def( + self, + parent: LocalDefId, + name: Symbol, + def_kind: DefKind, + ) -> TyCtxtFeed<'tcx, LocalDefId> { + let data = def_kind.def_path_data(name); // The following call has the side effect of modifying the tables inside `definitions`. // These very tables are relied on by the incr. comp. engine to decode DepNodes and to // decode the on-disk cache. @@ -1066,20 +1083,14 @@ impl<'tcx> TyCtxtAt<'tcx> { // This is fine because: // - those queries are `eval_always` so we won't miss their result changing; // - this write will have happened before these queries are called. - let def_id = self.tcx.create_def(parent, name, def_kind); - - let feed = self.tcx.feed_local_def_id(def_id); - feed.def_span(self.span); - feed - } -} - -impl<'tcx> TyCtxt<'tcx> { - /// `tcx`-dependent operations performed for every created definition. - pub fn create_def(self, parent: LocalDefId, name: Symbol, def_kind: DefKind) -> LocalDefId { - let data = def_kind.def_path_data(name); let def_id = self.untracked.definitions.write().create_def(parent, data); + // This function modifies `self.definitions` using a side-effect. + // We need to ensure that these side effects are re-run by the incr. comp. engine. + // Depending on the forever-red node will tell the graph that the calling query + // needs to be re-evaluated. + self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + let feed = self.feed_local_def_id(def_id); feed.def_kind(def_kind); // Unique types created for closures participate in type privacy checking. @@ -1091,7 +1102,7 @@ impl<'tcx> TyCtxt<'tcx> { feed.visibility(ty::Visibility::Restricted(parent_mod)); } - def_id + feed } pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ee74ef2fb6..15bddb2a64f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -252,6 +252,7 @@ pub struct ImplHeader<'tcx> { pub struct ImplTraitHeader<'tcx> { pub trait_ref: ty::TraitRef<'tcx>, pub polarity: ImplPolarity, + pub unsafety: hir::Unsafety, } #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] @@ -503,6 +504,16 @@ impl<'tcx> IntoKind for Ty<'tcx> { } } +impl<'tcx> rustc_type_ir::visit::Flags for Ty<'tcx> { + fn flags(&self) -> TypeFlags { + self.0.flags + } + + fn outer_exclusive_binder(&self) -> DebruijnIndex { + self.0.outer_exclusive_binder + } +} + impl EarlyParamRegion { /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 045856dd9cd..22f0574d614 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -126,6 +126,7 @@ parameterized_over_tcx! { crate::middle::exported_symbols::ExportedSymbol, crate::mir::Body, crate::mir::CoroutineLayout, + crate::mir::interpret::ConstAllocation, ty::Ty, ty::FnSig, ty::GenericPredicates, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 200811940ed..b63f9c6dfa0 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -29,6 +29,16 @@ pub struct Predicate<'tcx>( pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>, ); +impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> { + fn flags(&self) -> TypeFlags { + self.0.flags + } + + fn outer_exclusive_binder(&self) -> ty::DebruijnIndex { + self.0.outer_exclusive_binder + } +} + impl<'tcx> Predicate<'tcx> { /// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`. #[inline] @@ -36,11 +46,13 @@ impl<'tcx> Predicate<'tcx> { self.0.internee } + // FIXME(compiler-errors): Think about removing this. #[inline(always)] pub fn flags(self) -> TypeFlags { self.0.flags } + // FIXME(compiler-errors): Think about removing this. #[inline(always)] pub fn outer_exclusive_binder(self) -> DebruijnIndex { self.0.outer_exclusive_binder diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5cf90e94907..92ec1a83bee 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3156,13 +3156,12 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N // this is pub to be able to intra-doc-link it pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> { // Trimming paths is expensive and not optimized, since we expect it to only be used for error - // reporting. + // reporting. Record the fact that we did it, so we can abort if we later found it was + // unnecessary. // - // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths` - // wrapper can be used to suppress this query, in exchange for full paths being formatted. - tcx.sess.good_path_delayed_bug( - "trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging", - ); + // The `rustc_middle::ty::print::with_no_trimmed_paths` wrapper can be used to suppress this + // checking, in exchange for full paths being formatted. + tcx.sess.record_trimmed_def_paths(); // Once constructed, unique namespace+symbol pairs will have a `Some(_)` entry, while // non-unique pairs will have a `None` entry. diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 1191d7fca32..b206727f051 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -26,6 +26,19 @@ impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> { } } +impl<'tcx> rustc_type_ir::visit::Flags for Region<'tcx> { + fn flags(&self) -> TypeFlags { + self.type_flags() + } + + fn outer_exclusive_binder(&self) -> ty::DebruijnIndex { + match **self { + ty::ReBound(debruijn, _) => debruijn.shifted_in(1), + _ => ty::INNERMOST, + } + } +} + impl<'tcx> Region<'tcx> { #[inline] pub fn new_early_param( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index a3d5f1f1955..66086ac87f1 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -942,6 +942,16 @@ where } } +impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { + fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> { + self.bound_vars + } + + fn has_no_bound_vars(&self) -> bool { + self.bound_vars.is_empty() + } +} + impl<'tcx, T> Binder<'tcx, T> { /// Skips the binder and returns the "bound" value. This is a /// risky thing to do because it's easy to get confused about @@ -1808,6 +1818,7 @@ impl<'tcx> Ty<'tcx> { self.0.0 } + // FIXME(compiler-errors): Think about removing this. #[inline(always)] pub fn flags(self) -> TypeFlags { self.0.0.flags @@ -2362,6 +2373,20 @@ impl<'tcx> Ty<'tcx> { /// to represent the closure kind, because it has not yet been /// inferred. Once upvar inference (in `rustc_hir_analysis/src/check/upvar.rs`) /// is complete, that type variable will be unified. + /// + /// To be noted that you can use [`ClosureArgs::kind()`] or [`CoroutineClosureArgs::kind()`] + /// to get the same information, which you can get by calling [`GenericArgs::as_closure()`] + /// or [`GenericArgs::as_coroutine_closure()`], depending on the type of the closure. + /// + /// Otherwise, this method can be used as follows: + /// + /// ```rust,ignore (snippet of compiler code) + /// let TyKind::Closure(def_id, [closure_fn_kind_ty, ..]) = closure_ty.kind() + /// && let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() + /// { + /// // your code + /// } + /// ``` pub fn to_opt_closure_kind(self) -> Option<ty::ClosureKind> { match self.kind() { Int(int_ty) => match int_ty { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c674a868d9f..09bb06de483 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1320,6 +1320,7 @@ impl<'tcx> Ty<'tcx> { ty } + // FIXME(compiler-errors): Think about removing this. #[inline] pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex { self.0.outer_exclusive_binder diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 7acdb931f1a..59292a281ed 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -1,140 +1,10 @@ use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags}; -use rustc_errors::ErrorGuaranteed; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use std::ops::ControlFlow; -pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; - -pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> { - /// Returns `true` if `self` has any late-bound regions that are either - /// bound by `binder` or bound by some binder outside of `binder`. - /// If `binder` is `ty::INNERMOST`, this indicates whether - /// there are any late-bound regions that appear free. - fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { - self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break() - } - - /// Returns `true` if this type has any regions that escape `binder` (and - /// hence are not bound by it). - fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool { - self.has_vars_bound_at_or_above(binder.shifted_in(1)) - } - - /// Return `true` if this type has regions that are not a part of the type. - /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)` - /// would return `true`. The latter can occur when traversing through the - /// former. - /// - /// See [`HasEscapingVarsVisitor`] for more information. - fn has_escaping_bound_vars(&self) -> bool { - self.has_vars_bound_at_or_above(ty::INNERMOST) - } - - fn has_type_flags(&self, flags: TypeFlags) -> bool { - let res = - self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags); - trace!(?self, ?flags, ?res, "has_type_flags"); - res - } - fn has_projections(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PROJECTION) - } - fn has_inherent_projections(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INHERENT) - } - fn has_opaque_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) - } - fn has_coroutines(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_COROUTINE) - } - fn references_error(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_ERROR) - } - fn error_reported(&self) -> Result<(), ErrorGuaranteed> { - if self.references_error() { - // We must include lint errors and delayed bugs here. - if let Some(reported) = - ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs()) - { - Err(reported) - } else { - bug!("expected some kind of error in `error_reported`"); - } - } else { - Ok(()) - } - } - fn has_non_region_param(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM) - } - fn has_infer_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_INFER) - } - fn has_infer_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INFER) - } - fn has_non_region_infer(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER) - } - fn has_infer(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_INFER) - } - fn has_placeholders(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PLACEHOLDER) - } - fn has_non_region_placeholders(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER) - } - fn has_param(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PARAM) - } - /// "Free" regions in this context means that it has any region - /// that is not (a) erased or (b) late-bound. - fn has_free_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) - } - - fn has_erased_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_ERASED) - } - - /// True if there are any un-erased free regions. - fn has_erasable_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) - } - - /// Indicates whether this value references only 'global' - /// generic parameters that are the same regardless of what fn we are - /// in. This is used for caching. - fn is_global(&self) -> bool { - !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES) - } - - /// True if there are any late-bound regions - fn has_bound_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_BOUND) - } - /// True if there are any late-bound non-region variables - fn has_non_region_bound_vars(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND) - } - /// True if there are any bound variables - fn has_bound_vars(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_BOUND_VARS) - } - - /// Indicates whether this value still has parameters/placeholders/inference variables - /// which could be replaced later, in a way that would change the results of `impl` - /// specialization. - fn still_further_specializable(&self) -> bool { - self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) - } -} - -impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {} +pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; /////////////////////////////////////////////////////////////////////////// // Region folder @@ -370,185 +240,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> { } } -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -struct FoundEscapingVars; - -/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a -/// bound region or a bound type. -/// -/// So, for example, consider a type like the following, which has two binders: -/// -/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope -/// -/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the -/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner -/// fn type*, that type has an escaping region: `'a`. -/// -/// Note that what I'm calling an "escaping var" is often just called a "free var". However, -/// we already use the term "free var". It refers to the regions or types that we use to represent -/// bound regions or type params on a fn definition while we are type checking its body. -/// -/// To clarify, conceptually there is no particular difference between -/// an "escaping" var and a "free" var. However, there is a big -/// difference in practice. Basically, when "entering" a binding -/// level, one is generally required to do some sort of processing to -/// a bound var, such as replacing it with a fresh/placeholder -/// var, or making an entry in the environment to represent the -/// scope to which it is attached, etc. An escaping var represents -/// a bound var for which this processing has not yet been done. -struct HasEscapingVarsVisitor { - /// Anything bound by `outer_index` or "above" is escaping. - outer_index: ty::DebruijnIndex, -} - -impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor { - type BreakTy = FoundEscapingVars; - - fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow<Self::BreakTy> { - self.outer_index.shift_in(1); - let result = t.super_visit_with(self); - self.outer_index.shift_out(1); - result - } - - #[inline] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - // If the outer-exclusive-binder is *strictly greater* than - // `outer_index`, that means that `t` contains some content - // bound at `outer_index` or above (because - // `outer_exclusive_binder` is always 1 higher than the - // content in `t`). Therefore, `t` has some escaping vars. - if t.outer_exclusive_binder() > self.outer_index { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - // If the region is bound by `outer_index` or anything outside - // of outer index, then it escapes the binders we have - // visited. - if r.bound_at_or_above_binder(self.outer_index) { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } - - fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { - // If the outer-exclusive-binder is *strictly greater* than - // `outer_index`, that means that `ct` contains some content - // bound at `outer_index` or above (because - // `outer_exclusive_binder` is always 1 higher than the - // content in `t`). Therefore, `t` has some escaping vars. - if ct.outer_exclusive_binder() > self.outer_index { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> { - if predicate.outer_exclusive_binder() > self.outer_index { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } -} - -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -struct FoundFlags; - -// FIXME: Optimize for checking for infer flags -struct HasTypeFlagsVisitor { - flags: ty::TypeFlags, -} - -impl std::fmt::Debug for HasTypeFlagsVisitor { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.flags.fmt(fmt) - } -} - -// Note: this visitor traverses values down to the level of -// `Ty`/`Const`/`Predicate`, but not within those types. This is because the -// type flags at the outer layer are enough. So it's faster than it first -// looks, particular for `Ty`/`Predicate` where it's just a field access. -// -// N.B. The only case where this isn't totally true is binders, which also -// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that -// are present, regardless of whether those bound variables are used. This -// is important for anonymization of binders in `TyCtxt::erase_regions`. We -// specifically detect this case in `visit_binder`. -impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { - type BreakTy = FoundFlags; - - fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow<Self::BreakTy> { - // If we're looking for the HAS_BINDER_VARS flag, check if the - // binder has vars. This won't be present in the binder's bound - // value, so we need to check here too. - if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.bound_vars().is_empty() { - return ControlFlow::Break(FoundFlags); - } - - t.super_visit_with(self) - } - - #[inline] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - // Note: no `super_visit_with` call. - let flags = t.flags(); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - // Note: no `super_visit_with` call, as usual for `Region`. - let flags = r.type_flags(); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { - // Note: no `super_visit_with` call. - if c.flags().intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> { - // Note: no `super_visit_with` call. - if predicate.flags().intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } -} - /// Collects all the late-bound regions at the innermost binding level /// into a hash set. struct LateBoundRegionsCollector { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 906b3205ca7..35f5a6bfac5 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // them. let mut fake_borrows = match_has_guard.then(FxIndexSet::default); - let mut otherwise = None; + let otherwise_block = self.cfg.start_new_block(); // This will generate code to test scrutinee_place and // branch to the appropriate arm block @@ -327,46 +327,44 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match_start_span, scrutinee_span, block, - &mut otherwise, + otherwise_block, candidates, &mut fake_borrows, ); - if let Some(otherwise_block) = otherwise { - // See the doc comment on `match_candidates` for why we may have an - // otherwise block. Match checking will ensure this is actually - // unreachable. - let source_info = self.source_info(scrutinee_span); - - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. - // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. - let cause_matched_place = FakeReadCause::ForMatchedPlace(None); - - if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { - self.cfg.push_fake_read( - otherwise_block, - source_info, - cause_matched_place, - scrutinee_place, - ); - } + // See the doc comment on `match_candidates` for why we may have an + // otherwise block. Match checking will ensure this is actually + // unreachable. + let source_info = self.source_info(scrutinee_span); + + // Matching on a `scrutinee_place` with an uninhabited type doesn't + // generate any memory reads by itself, and so if the place "expression" + // contains unsafe operations like raw pointer dereferences or union + // field projections, we wouldn't know to require an `unsafe` block + // around a `match` equivalent to `std::intrinsics::unreachable()`. + // See issue #47412 for this hole being discovered in the wild. + // + // HACK(eddyb) Work around the above issue by adding a dummy inspection + // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // + // NOTE: ReadForMatch also checks that the scrutinee is initialized. + // This is currently needed to not allow matching on an uninitialized, + // uninhabited value. If we get never patterns, those will check that + // the place is initialized, and so this read would only be used to + // check safety. + let cause_matched_place = FakeReadCause::ForMatchedPlace(None); - self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { + self.cfg.push_fake_read( + otherwise_block, + source_info, + cause_matched_place, + scrutinee_place, + ); } + self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + // Link each leaf candidate to the `pre_binding_block` of the next one. let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; @@ -1163,7 +1161,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: Span, scrutinee_span: Span, start_block: BasicBlock, - otherwise_block: &mut Option<BasicBlock>, + otherwise_block: BasicBlock, candidates: &mut [&mut Candidate<'pat, 'tcx>], fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>, ) { @@ -1210,7 +1208,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: Span, scrutinee_span: Span, start_block: BasicBlock, - otherwise_block: &mut Option<BasicBlock>, + otherwise_block: BasicBlock, candidates: &mut [&mut Candidate<'_, 'tcx>], fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>, ) { @@ -1243,11 +1241,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // never reach this point. if unmatched_candidates.is_empty() { let source_info = self.source_info(span); - if let Some(otherwise) = *otherwise_block { - self.cfg.goto(block, source_info, otherwise); - } else { - *otherwise_block = Some(block); - } + self.cfg.goto(block, source_info, otherwise_block); return; } @@ -1428,7 +1422,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span: Span, candidates: &mut [&mut Candidate<'_, 'tcx>], block: BasicBlock, - otherwise_block: &mut Option<BasicBlock>, + otherwise_block: BasicBlock, fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>, ) { let (first_candidate, remaining_candidates) = candidates.split_first_mut().unwrap(); @@ -1453,7 +1447,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let match_pairs = mem::take(&mut first_candidate.match_pairs); first_candidate.pre_binding_block = Some(block); - let mut otherwise = None; + let remainder_start = self.cfg.start_new_block(); for match_pair in match_pairs { let PatKind::Or { ref pats } = &match_pair.pattern.kind else { bug!("Or-patterns should have been sorted to the end"); @@ -1463,7 +1457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { first_candidate.visit_leaves(|leaf_candidate| { self.test_or_pattern( leaf_candidate, - &mut otherwise, + remainder_start, pats, or_span, &match_pair.place, @@ -1472,8 +1466,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }); } - let remainder_start = otherwise.unwrap_or_else(|| self.cfg.start_new_block()); - self.match_candidates( span, scrutinee_span, @@ -1491,7 +1483,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn test_or_pattern<'pat>( &mut self, candidate: &mut Candidate<'pat, 'tcx>, - otherwise: &mut Option<BasicBlock>, + otherwise: BasicBlock, pats: &'pat [Box<Pat<'tcx>>], or_span: Span, place: &PlaceBuilder<'tcx>, @@ -1503,8 +1495,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .map(|pat| Candidate::new(place.clone(), pat, candidate.has_guard, self)) .collect(); let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect(); - let otherwise = if candidate.otherwise_block.is_some() { - &mut candidate.otherwise_block + let otherwise = if let Some(otherwise_block) = candidate.otherwise_block { + otherwise_block } else { otherwise }; @@ -1680,8 +1672,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: Span, scrutinee_span: Span, mut candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>], - block: BasicBlock, - otherwise_block: &mut Option<BasicBlock>, + start_block: BasicBlock, + otherwise_block: BasicBlock, fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>, ) { // extract the match-pair from the highest priority candidate @@ -1749,12 +1741,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("untested_candidates: {}", candidates.len()); // The block that we should branch to if none of the - // `target_candidates` match. This is either the block where we - // start matching the untested candidates if there are any, - // otherwise it's the `otherwise_block`. - let remainder_start = &mut None; - let remainder_start = - if candidates.is_empty() { &mut *otherwise_block } else { remainder_start }; + // `target_candidates` match. + let remainder_start = if !candidates.is_empty() { + let remainder_start = self.cfg.start_new_block(); + self.match_candidates( + span, + scrutinee_span, + remainder_start, + otherwise_block, + candidates, + fake_borrows, + ); + remainder_start + } else { + otherwise_block + }; // For each outcome of test, process the candidates that still // apply. Collect a list of blocks where control flow will @@ -1775,24 +1776,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); candidate_start } else { - *remainder_start.get_or_insert_with(|| self.cfg.start_new_block()) + remainder_start } }) .collect(); - if !candidates.is_empty() { - let remainder_start = remainder_start.unwrap_or_else(|| self.cfg.start_new_block()); - self.match_candidates( - span, - scrutinee_span, - remainder_start, - otherwise_block, - candidates, - fake_borrows, - ); - } - - self.perform_test(span, scrutinee_span, block, &match_place, &test, target_blocks); + // Perform the test, branching to one of N blocks. + self.perform_test(span, scrutinee_span, start_block, &match_place, &test, target_blocks); } /// Determine the fake borrows that are needed from a set of places that diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8688c589063..241b6c6cb2c 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -33,7 +33,7 @@ struct UnsafetyVisitor<'a, 'tcx> { body_target_features: &'tcx [Symbol], /// When inside the LHS of an assignment to a field, this is the type /// of the LHS and the span of the assignment expression. - assignment_info: Option<(Ty<'tcx>, Span)>, + assignment_info: Option<Ty<'tcx>>, in_union_destructure: bool, param_env: ParamEnv<'tcx>, inside_adt: bool, @@ -473,10 +473,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { if let ty::Adt(adt_def, _) = lhs.ty.kind() && adt_def.is_union() { - if let Some((assigned_ty, assignment_span)) = self.assignment_info { + if let Some(assigned_ty) = self.assignment_info { if assigned_ty.needs_drop(self.tcx, self.param_env) { - // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}")); + // This would be unsafe, but should be outright impossible since we + // reject such unions. + assert!( + self.tcx.dcx().has_errors().is_some(), + "union fields that need dropping should be impossible: \ + {assigned_ty}" + ); } } else { self.requires_unsafe(expr.span, AccessToUnionField); @@ -492,14 +497,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField); } - // Second, check for accesses to union fields - // don't have any special handling for AssignOp since it causes a read *and* write to lhs + // Second, check for accesses to union fields. Don't have any + // special handling for AssignOp since it causes a read *and* + // write to lhs. if matches!(expr.kind, ExprKind::Assign { .. }) { - self.assignment_info = Some((lhs.ty, expr.span)); + self.assignment_info = Some(lhs.ty); visit::walk_expr(self, lhs); self.assignment_info = None; visit::walk_expr(self, &self.thir()[rhs]); - return; // we have already visited everything by now + return; // We have already visited everything by now. } } ExprKind::Borrow { borrow_kind, arg } => { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c24b24d6f01..99952e1c178 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -3,6 +3,7 @@ use crate::thir::cx::region::Scope; use crate::thir::cx::Cx; use crate::thir::util::UserAnnotatedTyHelpers; use itertools::Itertools; +use rustc_ast::LitKind; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -20,7 +21,8 @@ use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{ self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType, }; -use rustc_span::{sym, Span}; +use rustc_span::source_map::Spanned; +use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; impl<'tcx> Cx<'tcx> { @@ -894,7 +896,14 @@ impl<'tcx> Cx<'tcx> { Res::Def(DefKind::ConstParam, def_id) => { let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local()); let generics = self.tcx.generics_of(hir_id.owner); - let index = generics.param_def_id_to_index[&def_id]; + let Some(&index) = generics.param_def_id_to_index.get(&def_id) else { + self.tcx.dcx().has_errors().unwrap(); + // We already errored about a late bound const + return ExprKind::Literal { + lit: &Spanned { span: DUMMY_SP, node: LitKind::Err }, + neg: false, + }; + }; let name = self.tcx.hir().name(hir_id); let param = ty::ParamConst::new(index, name); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 18a00724c3d..c77c80d9f4b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -153,8 +153,7 @@ impl<'tcx> ConstToPat<'tcx> { // a hard error when we don't have a valtree or when we find something in // the valtree that is not structural; then this can all be made a lot simpler. - let structural = - traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty()); + let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty()); debug!( "search_for_structural_match_violation cv.ty: {:?} returned: {:?}", cv.ty(), diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index fbb62695383..a0c3de3af58 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -243,10 +243,11 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { // old value is being dropped. let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty; if assigned_ty.needs_drop(self.tcx, self.param_env) { - // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.dcx().span_delayed_bug( - self.source_info.span, - format!("union fields that need dropping should be impossible: {assigned_ty}") + // This would be unsafe, but should be outright impossible since we reject + // such unions. + assert!( + self.tcx.dcx().has_errors().is_some(), + "union fields that need dropping should be impossible: {assigned_ty}" ); } } else { diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index d3d0c7bcc95..934e77e7deb 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,9 +1,10 @@ use rustc_data_structures::graph::WithNumNodes; use rustc_index::bit_set::BitSet; use rustc_middle::mir; -use rustc_span::{BytePos, Span, DUMMY_SP}; +use rustc_span::{BytePos, Span}; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; +use crate::coverage::spans::from_mir::SpanFromMir; use crate::coverage::ExtractedHirInfo; mod from_mir; @@ -61,7 +62,7 @@ pub(super) fn generate_coverage_spans( basic_coverage_blocks, ); let coverage_spans = SpansRefiner::refine_sorted_spans(basic_coverage_blocks, sorted_spans); - mappings.extend(coverage_spans.into_iter().map(|CoverageSpan { bcb, span, .. }| { + mappings.extend(coverage_spans.into_iter().map(|RefinedCovspan { bcb, span, .. }| { // Each span produced by the generator represents an ordinary code region. BcbMapping { kind: BcbMappingKind::Code(bcb), span } })); @@ -85,18 +86,36 @@ pub(super) fn generate_coverage_spans( Some(CoverageSpans { bcb_has_mappings, mappings }) } -/// A BCB is deconstructed into one or more `Span`s. Each `Span` maps to a `CoverageSpan` that -/// references the originating BCB and one or more MIR `Statement`s and/or `Terminator`s. -/// Initially, the `Span`s come from the `Statement`s and `Terminator`s, but subsequent -/// transforms can combine adjacent `Span`s and `CoverageSpan` from the same BCB, merging the -/// `merged_spans` vectors, and the `Span`s to cover the extent of the combined `Span`s. -/// -/// Note: A span merged into another CoverageSpan may come from a `BasicBlock` that -/// is not part of the `CoverageSpan` bcb if the statement was included because it's `Span` matches -/// or is subsumed by the `Span` associated with this `CoverageSpan`, and it's `BasicBlock` -/// `dominates()` the `BasicBlock`s in this `CoverageSpan`. -#[derive(Debug, Clone)] -struct CoverageSpan { +#[derive(Debug)] +struct CurrCovspan { + /// This is used as the basis for [`PrevCovspan::original_span`], so it must + /// not be modified. + span: Span, + bcb: BasicCoverageBlock, + is_closure: bool, +} + +impl CurrCovspan { + fn new(span: Span, bcb: BasicCoverageBlock, is_closure: bool) -> Self { + Self { span, bcb, is_closure } + } + + fn into_prev(self) -> PrevCovspan { + let Self { span, bcb, is_closure } = self; + PrevCovspan { original_span: span, span, bcb, merged_spans: vec![span], is_closure } + } + + fn into_refined(self) -> RefinedCovspan { + // This is only called in cases where `curr` is a closure span that has + // been carved out of `prev`. + debug_assert!(self.is_closure); + self.into_prev().into_refined() + } +} + +#[derive(Debug)] +struct PrevCovspan { + original_span: Span, span: Span, bcb: BasicCoverageBlock, /// List of all the original spans from MIR that have been merged into this @@ -105,37 +124,82 @@ struct CoverageSpan { is_closure: bool, } -impl CoverageSpan { - fn new(span: Span, bcb: BasicCoverageBlock, is_closure: bool) -> Self { - Self { span, bcb, merged_spans: vec![span], is_closure } +impl PrevCovspan { + fn is_mergeable(&self, other: &CurrCovspan) -> bool { + self.bcb == other.bcb && !self.is_closure && !other.is_closure } - pub fn merge_from(&mut self, other: &Self) { + fn merge_from(&mut self, other: &CurrCovspan) { debug_assert!(self.is_mergeable(other)); self.span = self.span.to(other.span); - self.merged_spans.extend_from_slice(&other.merged_spans); + self.merged_spans.push(other.span); } - pub fn cutoff_statements_at(&mut self, cutoff_pos: BytePos) { + fn cutoff_statements_at(&mut self, cutoff_pos: BytePos) { self.merged_spans.retain(|span| span.hi() <= cutoff_pos); if let Some(max_hi) = self.merged_spans.iter().map(|span| span.hi()).max() { self.span = self.span.with_hi(max_hi); } } - #[inline] - pub fn is_mergeable(&self, other: &Self) -> bool { - self.is_in_same_bcb(other) && !(self.is_closure || other.is_closure) + fn into_dup(self) -> DuplicateCovspan { + let Self { original_span, span, bcb, merged_spans: _, is_closure } = self; + // Only unmodified spans end up in `pending_dups`. + debug_assert_eq!(original_span, span); + DuplicateCovspan { span, bcb, is_closure } } - #[inline] - pub fn is_in_same_bcb(&self, other: &Self) -> bool { - self.bcb == other.bcb + fn refined_copy(&self) -> RefinedCovspan { + let &Self { original_span: _, span, bcb, merged_spans: _, is_closure } = self; + RefinedCovspan { span, bcb, is_closure } + } + + fn into_refined(self) -> RefinedCovspan { + self.refined_copy() } } -/// Converts the initial set of `CoverageSpan`s (one per MIR `Statement` or `Terminator`) into a -/// minimal set of `CoverageSpan`s, using the BCB CFG to determine where it is safe and useful to: +#[derive(Debug)] +struct DuplicateCovspan { + span: Span, + bcb: BasicCoverageBlock, + is_closure: bool, +} + +impl DuplicateCovspan { + /// Returns a copy of this covspan, as a [`RefinedCovspan`]. + /// Should only be called in places that would otherwise clone this covspan. + fn refined_copy(&self) -> RefinedCovspan { + let &Self { span, bcb, is_closure } = self; + RefinedCovspan { span, bcb, is_closure } + } + + fn into_refined(self) -> RefinedCovspan { + // Even though we consume self, we can just reuse the copying impl. + self.refined_copy() + } +} + +#[derive(Debug)] +struct RefinedCovspan { + span: Span, + bcb: BasicCoverageBlock, + is_closure: bool, +} + +impl RefinedCovspan { + fn is_mergeable(&self, other: &Self) -> bool { + self.bcb == other.bcb && !self.is_closure && !other.is_closure + } + + fn merge_from(&mut self, other: &Self) { + debug_assert!(self.is_mergeable(other)); + self.span = self.span.to(other.span); + } +} + +/// Converts the initial set of coverage spans (one per MIR `Statement` or `Terminator`) into a +/// minimal set of coverage spans, using the BCB CFG to determine where it is safe and useful to: /// /// * Remove duplicate source code coverage regions /// * Merge spans that represent continuous (both in source code and control flow), non-branching @@ -145,43 +209,33 @@ struct SpansRefiner<'a> { /// The BasicCoverageBlock Control Flow Graph (BCB CFG). basic_coverage_blocks: &'a CoverageGraph, - /// The initial set of `CoverageSpan`s, sorted by `Span` (`lo` and `hi`) and by relative + /// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative /// dominance between the `BasicCoverageBlock`s of equal `Span`s. - sorted_spans_iter: std::vec::IntoIter<CoverageSpan>, + sorted_spans_iter: std::vec::IntoIter<SpanFromMir>, - /// The current `CoverageSpan` to compare to its `prev`, to possibly merge, discard, force the + /// The current coverage span to compare to its `prev`, to possibly merge, discard, force the /// discard of the `prev` (and or `pending_dups`), or keep both (with `prev` moved to /// `pending_dups`). If `curr` is not discarded or merged, it becomes `prev` for the next /// iteration. - some_curr: Option<CoverageSpan>, - - /// The original `span` for `curr`, in case `curr.span()` is modified. The `curr_original_span` - /// **must not be mutated** (except when advancing to the next `curr`), even if `curr.span()` - /// is mutated. - curr_original_span: Span, + some_curr: Option<CurrCovspan>, - /// The CoverageSpan from a prior iteration; typically assigned from that iteration's `curr`. + /// The coverage span from a prior iteration; typically assigned from that iteration's `curr`. /// If that `curr` was discarded, `prev` retains its value from the previous iteration. - some_prev: Option<CoverageSpan>, + some_prev: Option<PrevCovspan>, - /// Assigned from `curr_original_span` from the previous iteration. The `prev_original_span` - /// **must not be mutated** (except when advancing to the next `prev`), even if `prev.span()` - /// is mutated. - prev_original_span: Span, - - /// One or more `CoverageSpan`s with the same `Span` but different `BasicCoverageBlock`s, and + /// One or more coverage spans with the same `Span` but different `BasicCoverageBlock`s, and /// no `BasicCoverageBlock` in this list dominates another `BasicCoverageBlock` in the list. /// If a new `curr` span also fits this criteria (compared to an existing list of - /// `pending_dups`), that `curr` `CoverageSpan` moves to `prev` before possibly being added to + /// `pending_dups`), that `curr` moves to `prev` before possibly being added to /// the `pending_dups` list, on the next iteration. As a result, if `prev` and `pending_dups` /// have the same `Span`, the criteria for `pending_dups` holds for `prev` as well: a `prev` /// with a matching `Span` does not dominate any `pending_dup` and no `pending_dup` dominates a /// `prev` with a matching `Span`) - pending_dups: Vec<CoverageSpan>, + pending_dups: Vec<DuplicateCovspan>, - /// The final `CoverageSpan`s to add to the coverage map. A `Counter` or `Expression` - /// will also be injected into the MIR for each `CoverageSpan`. - refined_spans: Vec<CoverageSpan>, + /// The final coverage spans to add to the coverage map. A `Counter` or `Expression` + /// will also be injected into the MIR for each BCB that has associated spans. + refined_spans: Vec<RefinedCovspan>, } impl<'a> SpansRefiner<'a> { @@ -190,15 +244,13 @@ impl<'a> SpansRefiner<'a> { /// and carving holes in spans when they overlap in unwanted ways. fn refine_sorted_spans( basic_coverage_blocks: &'a CoverageGraph, - sorted_spans: Vec<CoverageSpan>, - ) -> Vec<CoverageSpan> { + sorted_spans: Vec<SpanFromMir>, + ) -> Vec<RefinedCovspan> { let this = Self { basic_coverage_blocks, sorted_spans_iter: sorted_spans.into_iter(), some_curr: None, - curr_original_span: DUMMY_SP, some_prev: None, - prev_original_span: DUMMY_SP, pending_dups: Vec::new(), refined_spans: Vec::with_capacity(basic_coverage_blocks.num_nodes() * 2), }; @@ -206,9 +258,9 @@ impl<'a> SpansRefiner<'a> { this.to_refined_spans() } - /// Iterate through the sorted `CoverageSpan`s, and return the refined list of merged and - /// de-duplicated `CoverageSpan`s. - fn to_refined_spans(mut self) -> Vec<CoverageSpan> { + /// Iterate through the sorted coverage spans, and return the refined list of merged and + /// de-duplicated spans. + fn to_refined_spans(mut self) -> Vec<RefinedCovspan> { while self.next_coverage_span() { // For the first span we don't have `prev` set, so most of the // span-processing steps don't make sense yet. @@ -221,16 +273,15 @@ impl<'a> SpansRefiner<'a> { let prev = self.prev(); let curr = self.curr(); - if curr.is_mergeable(prev) { + if prev.is_mergeable(curr) { debug!(" same bcb (and neither is a closure), merge with prev={prev:?}"); - let prev = self.take_prev(); - self.curr_mut().merge_from(&prev); - // Note that curr.span may now differ from curr_original_span + let curr = self.take_curr(); + self.prev_mut().merge_from(&curr); } else if prev.span.hi() <= curr.span.lo() { debug!( " different bcbs and disjoint spans, so keep curr for next iter, and add prev={prev:?}", ); - let prev = self.take_prev(); + let prev = self.take_prev().into_refined(); self.refined_spans.push(prev); } else if prev.is_closure { // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the @@ -241,9 +292,9 @@ impl<'a> SpansRefiner<'a> { self.take_curr(); // Discards curr. } else if curr.is_closure { self.carve_out_span_for_closure(); - } else if self.prev_original_span == curr.span { - // `prev` and `curr` have the same span, or would have had the - // same span before `prev` was modified by other spans. + } else if prev.original_span == prev.span && prev.span == curr.span { + // Prev and curr have the same span, and prev's span hasn't + // been modified by other spans. self.update_pending_dups(); } else { self.cutoff_prev_at_overlapping_curr(); @@ -253,14 +304,14 @@ impl<'a> SpansRefiner<'a> { // Drain any remaining dups into the output. for dup in self.pending_dups.drain(..) { debug!(" ...adding at least one pending dup={:?}", dup); - self.refined_spans.push(dup); + self.refined_spans.push(dup.into_refined()); } // There is usually a final span remaining in `prev` after the loop ends, // so add it to the output as well. if let Some(prev) = self.some_prev.take() { debug!(" AT END, adding last prev={prev:?}"); - self.refined_spans.push(prev); + self.refined_spans.push(prev.into_refined()); } // Do one last merge pass, to simplify the output. @@ -274,7 +325,7 @@ impl<'a> SpansRefiner<'a> { } }); - // Remove `CoverageSpan`s derived from closures, originally added to ensure the coverage + // Remove spans derived from closures, originally added to ensure the coverage // regions for the current function leave room for the closure's own coverage regions // (injected separately, from the closure's own MIR). self.refined_spans.retain(|covspan| !covspan.is_closure); @@ -282,34 +333,29 @@ impl<'a> SpansRefiner<'a> { } #[track_caller] - fn curr(&self) -> &CoverageSpan { + fn curr(&self) -> &CurrCovspan { self.some_curr.as_ref().unwrap_or_else(|| bug!("some_curr is None (curr)")) } - #[track_caller] - fn curr_mut(&mut self) -> &mut CoverageSpan { - self.some_curr.as_mut().unwrap_or_else(|| bug!("some_curr is None (curr_mut)")) - } - /// If called, then the next call to `next_coverage_span()` will *not* update `prev` with the /// `curr` coverage span. #[track_caller] - fn take_curr(&mut self) -> CoverageSpan { + fn take_curr(&mut self) -> CurrCovspan { self.some_curr.take().unwrap_or_else(|| bug!("some_curr is None (take_curr)")) } #[track_caller] - fn prev(&self) -> &CoverageSpan { + fn prev(&self) -> &PrevCovspan { self.some_prev.as_ref().unwrap_or_else(|| bug!("some_prev is None (prev)")) } #[track_caller] - fn prev_mut(&mut self) -> &mut CoverageSpan { + fn prev_mut(&mut self) -> &mut PrevCovspan { self.some_prev.as_mut().unwrap_or_else(|| bug!("some_prev is None (prev_mut)")) } #[track_caller] - fn take_prev(&mut self) -> CoverageSpan { + fn take_prev(&mut self) -> PrevCovspan { self.some_prev.take().unwrap_or_else(|| bug!("some_prev is None (take_prev)")) } @@ -335,7 +381,7 @@ impl<'a> SpansRefiner<'a> { if last_dup.span.hi() <= self.curr().span.lo() { for dup in self.pending_dups.drain(..) { debug!(" ...adding at least one pending={:?}", dup); - self.refined_spans.push(dup); + self.refined_spans.push(dup.into_refined()); } } else { self.pending_dups.clear(); @@ -343,11 +389,10 @@ impl<'a> SpansRefiner<'a> { assert!(self.pending_dups.is_empty()); } - /// Advance `prev` to `curr` (if any), and `curr` to the next `CoverageSpan` in sorted order. + /// Advance `prev` to `curr` (if any), and `curr` to the next coverage span in sorted order. fn next_coverage_span(&mut self) -> bool { if let Some(curr) = self.some_curr.take() { - self.some_prev = Some(curr); - self.prev_original_span = self.curr_original_span; + self.some_prev = Some(curr.into_prev()); } while let Some(curr) = self.sorted_spans_iter.next() { debug!("FOR curr={:?}", curr); @@ -362,10 +407,7 @@ impl<'a> SpansRefiner<'a> { closure?); prev={prev:?}", ); } else { - // Save a copy of the original span for `curr` in case the `CoverageSpan` is changed - // by `self.curr_mut().merge_from(prev)`. - self.curr_original_span = curr.span; - self.some_curr.replace(curr); + self.some_curr = Some(CurrCovspan::new(curr.span, curr.bcb, curr.is_closure)); self.maybe_flush_pending_dups(); return true; } @@ -388,11 +430,11 @@ impl<'a> SpansRefiner<'a> { let has_post_closure_span = prev.span.hi() > right_cutoff; if has_pre_closure_span { - let mut pre_closure = self.prev().clone(); + let mut pre_closure = self.prev().refined_copy(); pre_closure.span = pre_closure.span.with_hi(left_cutoff); debug!(" prev overlaps a closure. Adding span for pre_closure={:?}", pre_closure); - for mut dup in self.pending_dups.iter().cloned() { + for mut dup in self.pending_dups.iter().map(DuplicateCovspan::refined_copy) { dup.span = dup.span.with_hi(left_cutoff); debug!(" ...and at least one pre_closure dup={:?}", dup); self.refined_spans.push(dup); @@ -402,9 +444,7 @@ impl<'a> SpansRefiner<'a> { } if has_post_closure_span { - // Mutate `prev.span()` to start after the closure (and discard curr). - // (**NEVER** update `prev_original_span` because it affects the assumptions - // about how the `CoverageSpan`s are ordered.) + // Mutate `prev.span` to start after the closure (and discard curr). self.prev_mut().span = self.prev().span.with_lo(right_cutoff); debug!(" Mutated prev.span to start after the closure. prev={:?}", self.prev()); @@ -413,25 +453,26 @@ impl<'a> SpansRefiner<'a> { dup.span = dup.span.with_lo(right_cutoff); } - let closure_covspan = self.take_curr(); // Prevent this curr from becoming prev. + // Prevent this curr from becoming prev. + let closure_covspan = self.take_curr().into_refined(); self.refined_spans.push(closure_covspan); // since self.prev() was already updated } else { self.pending_dups.clear(); } } - /// Called if `curr.span` equals `prev_original_span` (and potentially equal to all + /// Called if `curr.span` equals `prev.original_span` (and potentially equal to all /// `pending_dups` spans, if any). Keep in mind, `prev.span()` may have been changed. /// If prev.span() was merged into other spans (with matching BCB, for instance), - /// `prev.span.hi()` will be greater than (further right of) `prev_original_span.hi()`. + /// `prev.span.hi()` will be greater than (further right of) `prev.original_span.hi()`. /// If prev.span() was split off to the right of a closure, prev.span().lo() will be - /// greater than prev_original_span.lo(). The actual span of `prev_original_span` is + /// greater than prev.original_span.lo(). The actual span of `prev.original_span` is /// not as important as knowing that `prev()` **used to have the same span** as `curr()`, /// which means their sort order is still meaningful for determining the dominator /// relationship. /// - /// When two `CoverageSpan`s have the same `Span`, dominated spans can be discarded; but if - /// neither `CoverageSpan` dominates the other, both (or possibly more than two) are held, + /// When two coverage spans have the same `Span`, dominated spans can be discarded; but if + /// neither coverage span dominates the other, both (or possibly more than two) are held, /// until their disposition is determined. In this latter case, the `prev` dup is moved into /// `pending_dups` so the new `curr` dup can be moved to `prev` for the next iteration. fn update_pending_dups(&mut self) { @@ -439,9 +480,15 @@ impl<'a> SpansRefiner<'a> { let curr_bcb = self.curr().bcb; // Equal coverage spans are ordered by dominators before dominated (if any), so it should be - // impossible for `curr` to dominate any previous `CoverageSpan`. + // impossible for `curr` to dominate any previous coverage span. debug_assert!(!self.basic_coverage_blocks.dominates(curr_bcb, prev_bcb)); + // `prev` is a duplicate of `curr`, so add it to the list of pending dups. + // If it dominates `curr`, it will be removed by the subsequent discard step. + let prev = self.take_prev().into_dup(); + debug!(?prev, "adding prev to pending dups"); + self.pending_dups.push(prev); + let initial_pending_count = self.pending_dups.len(); if initial_pending_count > 0 { self.pending_dups @@ -454,42 +501,6 @@ impl<'a> SpansRefiner<'a> { ); } } - - if self.basic_coverage_blocks.dominates(prev_bcb, curr_bcb) { - debug!( - " different bcbs but SAME spans, and prev dominates curr. Discard prev={:?}", - self.prev() - ); - self.cutoff_prev_at_overlapping_curr(); - // If one span dominates the other, associate the span with the code from the dominated - // block only (`curr`), and discard the overlapping portion of the `prev` span. (Note - // that if `prev.span` is wider than `prev_original_span`, a `CoverageSpan` will still - // be created for `prev`s block, for the non-overlapping portion, left of `curr.span`.) - // - // For example: - // match somenum { - // x if x < 1 => { ... } - // }... - // - // The span for the first `x` is referenced by both the pattern block (every time it is - // evaluated) and the arm code (only when matched). The counter will be applied only to - // the dominated block. This allows coverage to track and highlight things like the - // assignment of `x` above, if the branch is matched, making `x` available to the arm - // code; and to track and highlight the question mark `?` "try" operator at the end of - // a function call returning a `Result`, so the `?` is covered when the function returns - // an `Err`, and not counted as covered if the function always returns `Ok`. - } else { - // Save `prev` in `pending_dups`. (`curr` will become `prev` in the next iteration.) - // If the `curr` CoverageSpan is later discarded, `pending_dups` can be discarded as - // well; but if `curr` is added to refined_spans, the `pending_dups` will also be added. - debug!( - " different bcbs but SAME spans, and neither dominates, so keep curr for \ - next iter, and, pending upcoming spans (unless overlapping) add prev={:?}", - self.prev() - ); - let prev = self.take_prev(); - self.pending_dups.push(prev); - } } /// `curr` overlaps `prev`. If `prev`s span extends left of `curr`s span, keep _only_ @@ -512,7 +523,7 @@ impl<'a> SpansRefiner<'a> { debug!(" ... no non-overlapping statements to add"); } else { debug!(" ... adding modified prev={:?}", self.prev()); - let prev = self.take_prev(); + let prev = self.take_prev().into_refined(); self.refined_spans.push(prev); } } else { diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 4ac8dde03a6..9517ede288f 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -9,7 +9,6 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; use crate::coverage::graph::{ BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB, }; -use crate::coverage::spans::CoverageSpan; use crate::coverage::ExtractedHirInfo; /// Traverses the MIR body to produce an initial collection of coverage-relevant @@ -22,7 +21,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans( mir_body: &mir::Body<'_>, hir_info: &ExtractedHirInfo, basic_coverage_blocks: &CoverageGraph, -) -> Vec<CoverageSpan> { +) -> Vec<SpanFromMir> { let &ExtractedHirInfo { body_span, .. } = hir_info; let mut initial_spans = vec![]; @@ -61,7 +60,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans( .then_with(|| Ord::cmp(&a.is_closure, &b.is_closure).reverse()) }); - initial_spans.into_iter().map(SpanFromMir::into_coverage_span).collect::<Vec<_>>() + initial_spans } /// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate @@ -119,10 +118,10 @@ fn split_visible_macro_spans(initial_spans: &mut Vec<SpanFromMir>) { initial_spans.extend(extra_spans); } -// Generate a set of `CoverageSpan`s from the filtered set of `Statement`s and `Terminator`s of -// the `BasicBlock`(s) in the given `BasicCoverageBlockData`. One `CoverageSpan` is generated +// Generate a set of coverage spans from the filtered set of `Statement`s and `Terminator`s of +// the `BasicBlock`(s) in the given `BasicCoverageBlockData`. One coverage span is generated // for each `Statement` and `Terminator`. (Note that subsequent stages of coverage analysis will -// merge some `CoverageSpan`s, at which point a `CoverageSpan` may represent multiple +// merge some coverage spans, at which point a coverage span may represent multiple // `Statement`s and/or `Terminator`s.) fn bcb_to_initial_coverage_spans<'a, 'tcx>( mir_body: &'a mir::Body<'tcx>, @@ -316,7 +315,7 @@ fn unexpand_into_body_span_with_prev( } #[derive(Debug)] -struct SpanFromMir { +pub(super) struct SpanFromMir { /// A span that has been extracted from MIR and then "un-expanded" back to /// within the current function's `body_span`. After various intermediate /// processing steps, this span is emitted as part of the final coverage @@ -324,10 +323,10 @@ struct SpanFromMir { /// /// With the exception of `fn_sig_span`, this should always be contained /// within `body_span`. - span: Span, + pub(super) span: Span, visible_macro: Option<Symbol>, - bcb: BasicCoverageBlock, - is_closure: bool, + pub(super) bcb: BasicCoverageBlock, + pub(super) is_closure: bool, } impl SpanFromMir { @@ -343,9 +342,4 @@ impl SpanFromMir { ) -> Self { Self { span, visible_macro, bcb, is_closure } } - - fn into_coverage_span(self) -> CoverageSpan { - let Self { span, visible_macro: _, bcb, is_closure } = self; - CoverageSpan::new(span, bcb, is_closure) - } } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 0ac4ab61d40..2c8201b1903 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -398,7 +398,8 @@ impl<'alloc> Candidates<'alloc> { let candidates = entry.get_mut(); Self::vec_filter_candidates(p, candidates, f, at); if candidates.len() == 0 { - entry.remove(); + // FIXME(#120456) - is `swap_remove` correct? + entry.swap_remove(); } } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 8d4afd5b5dc..a080e2423d4 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -399,7 +399,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { }; for (field_index, op) in fields.into_iter().enumerate() { let field_dest = self.ecx.project_field(&variant_dest, field_index).ok()?; - self.ecx.copy_op(op, &field_dest, /*allow_transmute*/ false).ok()?; + self.ecx.copy_op(op, &field_dest).ok()?; } self.ecx.write_discriminant(variant.unwrap_or(FIRST_VARIANT), &dest).ok()?; self.ecx @@ -561,9 +561,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { .ok()?; dest.into() } - CastKind::FnPtrToPtr - | CastKind::PtrToPtr - | CastKind::PointerCoercion( + CastKind::FnPtrToPtr | CastKind::PtrToPtr => { + let src = self.evaluated[value].as_ref()?; + let src = self.ecx.read_immediate(src).ok()?; + let to = self.ecx.layout_of(to).ok()?; + let ret = self.ecx.ptr_to_ptr(&src, to).ok()?; + ret.into() + } + CastKind::PointerCoercion( ty::adjustment::PointerCoercion::MutToConstPointer | ty::adjustment::PointerCoercion::ArrayToPointer | ty::adjustment::PointerCoercion::UnsafeFnPointer, @@ -571,8 +576,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let src = self.evaluated[value].as_ref()?; let src = self.ecx.read_immediate(src).ok()?; let to = self.ecx.layout_of(to).ok()?; - let ret = self.ecx.ptr_to_ptr(&src, to).ok()?; - ret.into() + ImmTy::from_immediate(*src, to).into() } _ => return None, }, @@ -1177,8 +1181,7 @@ fn op_to_prop_const<'tcx>( } // Everything failed: create a new allocation to hold the data. - let alloc_id = - ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest, false)).ok()?; + let alloc_id = ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest)).ok()?; let value = ConstValue::Indirect { alloc_id, offset: Size::ZERO }; // Check that we do not leak a pointer. diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9f30f2836f1..b4fa7f3bea6 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -265,6 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { let body = &tcx.mir_const(def).borrow(); if body.return_ty().references_error() { + // It's possible to reach here without an error being emitted (#121103). tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors"); return Default::default(); } diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 42edbeaa622..cd434fecce2 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_type_ir::visit::TypeVisitableExt; use rustc_type_ir::{ self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy, InferCtxtLike, Interner, IntoKind, PlaceholderLike, @@ -62,8 +63,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc let value = value.fold_with(&mut canonicalizer); // FIXME: Restore these assertions. Should we uplift type flags? - // assert!(!value.has_infer(), "unexpected infer in {value:?}"); - // assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); + assert!(!value.has_infer(), "unexpected infer in {value:?}"); + assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); let (max_universe, variables) = canonicalizer.finalize(); diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index c1fe8c2133b..17ad08b0569 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -957,8 +957,9 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { // available as we'd like it to be. // FIXME: only remove `libc` when `stdbuild` is active. // FIXME: remove special casing for `test`. - remaining_lib_features.remove(&sym::libc); - remaining_lib_features.remove(&sym::test); + // FIXME(#120456) - is `swap_remove` correct? + remaining_lib_features.swap_remove(&sym::libc); + remaining_lib_features.swap_remove(&sym::test); /// For each feature in `defined_features`.. /// @@ -996,7 +997,8 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { unnecessary_stable_feature_lint(tcx, *span, feature, since); } } - remaining_lib_features.remove(&feature); + // FIXME(#120456) - is `swap_remove` correct? + remaining_lib_features.swap_remove(&feature); // `feature` is the feature doing the implying, but `implied_by` is the feature with // the attribute that establishes this relationship. `implied_by` is guaranteed to be a diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 3ef9de7da74..8d7c0ca0144 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -4,7 +4,7 @@ use crate::query::plumbing::CycleError; use crate::query::DepKind; use crate::query::{QueryContext, QueryStackFrame}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{DiagCtxt, Diagnostic, DiagnosticBuilder, Level}; +use rustc_errors::{DiagCtxt, DiagnosticBuilder}; use rustc_hir::def::DefKind; use rustc_session::Session; use rustc_span::Span; @@ -628,15 +628,15 @@ pub fn print_query_stack<Qcx: QueryContext>( }; if Some(count_printed) < num_frames || num_frames.is_none() { // Only print to stderr as many stack frames as `num_frames` when present. - let mut diag = Diagnostic::new( - Level::FailureNote, - format!( - "#{} [{:?}] {}", - count_printed, query_info.query.dep_kind, query_info.query.description - ), - ); - diag.span = query_info.job.span.into(); - dcx.force_print_diagnostic(diag); + // FIXME: needs translation + #[allow(rustc::diagnostic_outside_of_impl)] + #[allow(rustc::untranslatable_diagnostic)] + dcx.struct_failure_note(format!( + "#{} [{:?}] {}", + count_printed, query_info.query.dep_kind, query_info.query.description + )) + .with_span(query_info.job.span) + .emit(); count_printed += 1; } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 9158ba00901..754757b5de5 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -429,16 +429,16 @@ where let formatter = query.format_value(); if old_hash != new_hash { // We have an inconsistency. This can happen if one of the two - // results is tainted by errors. In this case, delay a bug to - // ensure compilation is doomed. - qcx.dep_context().sess().dcx().delayed_bug(format!( + // results is tainted by errors. + assert!( + qcx.dep_context().sess().dcx().has_errors().is_some(), "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ computed={:#?}\nfed={:#?}", query.dep_kind(), key, formatter(&result), formatter(&cached_result), - )); + ); } } } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index fc72d76c3a7..c14788b841d 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -92,7 +92,8 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { } else { // This trait import is definitely used, in a way other than // method resolution. - self.r.maybe_unused_trait_imports.remove(&def_id); + // FIXME(#120456) - is `swap_remove` correct? + self.r.maybe_unused_trait_imports.swap_remove(&def_id); if let Some(i) = self.unused_imports.get_mut(&self.base_id) { i.unused.remove(&id); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 5d712461993..cb3b95a4434 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -460,7 +460,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { return (err, Vec::new()); } - let (found, candidates) = self.try_lookup_name_relaxed( + let (found, mut candidates) = self.try_lookup_name_relaxed( &mut err, source, path, @@ -473,10 +473,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { return (err, candidates); } - let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); + if self.suggest_shadowed(&mut err, source, path, following_seg, span) { + // if there is already a shadowed name, don'suggest candidates for importing + candidates.clear(); + } - // if we have suggested using pattern matching, then don't add needless suggestions - // for typos. + let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); fallback |= self.suggest_typo(&mut err, source, path, following_seg, span, &base_error); if fallback { @@ -872,25 +874,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let ident_span = path.last().map_or(span, |ident| ident.ident.span); let typo_sugg = self.lookup_typo_candidate(path, following_seg, source.namespace(), is_expected); - let is_in_same_file = &|sp1, sp2| { - let source_map = self.r.tcx.sess.source_map(); - let file1 = source_map.span_to_filename(sp1); - let file2 = source_map.span_to_filename(sp2); - file1 == file2 - }; - // print 'you might have meant' if the candidate is (1) is a shadowed name with - // accessible definition and (2) either defined in the same crate as the typo - // (could be in a different file) or introduced in the same file as the typo - // (could belong to a different crate) - if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg - && res.opt_def_id().is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span)) - { - err.span_label( - sugg_span, - format!("you might have meant to refer to this {}", res.descr()), - ); - return true; - } let mut fallback = false; let typo_sugg = typo_sugg.to_opt_suggestion(); if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) { @@ -918,6 +901,39 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { fallback } + fn suggest_shadowed( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + path: &[Segment], + following_seg: Option<&Segment>, + span: Span, + ) -> bool { + let is_expected = &|res| source.is_expected(res); + let typo_sugg = + self.lookup_typo_candidate(path, following_seg, source.namespace(), is_expected); + let is_in_same_file = &|sp1, sp2| { + let source_map = self.r.tcx.sess.source_map(); + let file1 = source_map.span_to_filename(sp1); + let file2 = source_map.span_to_filename(sp2); + file1 == file2 + }; + // print 'you might have meant' if the candidate is (1) is a shadowed name with + // accessible definition and (2) either defined in the same crate as the typo + // (could be in a different file) or introduced in the same file as the typo + // (could belong to a different crate) + if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg + && res.opt_def_id().is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span)) + { + err.span_label( + sugg_span, + format!("you might have meant to refer to this {}", res.descr()), + ); + return true; + } + false + } + fn err_code_special_cases( &mut self, err: &mut Diagnostic, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6b07bfdec67..bf811c7a4bb 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1245,7 +1245,7 @@ impl<'tcx> Resolver<'_, 'tcx> { ); // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()` - let def_id = self.tcx.create_def(parent, name, def_kind); + let def_id = self.tcx.create_def(parent, name, def_kind).def_id(); // Create the definition. if expn_id != ExpnId::root() { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 0c084660761..25c20be8e62 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -322,10 +322,9 @@ impl Session { } } - /// Used for code paths of expensive computations that should only take place when - /// warnings or errors are emitted. If no messages are emitted ("good path"), then - /// it's likely a bug. - pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) { + /// Record the fact that we called `trimmed_def_paths`, and do some + /// checking about whether its cost was justified. + pub fn record_trimmed_def_paths(&self) { if self.opts.unstable_opts.print_type_sizes || self.opts.unstable_opts.query_dep_graph || self.opts.unstable_opts.dump_mir.is_some() @@ -336,7 +335,7 @@ impl Session { return; } - self.dcx().good_path_delayed_bug(msg) + self.dcx().set_must_produce_diag() } #[inline] @@ -546,8 +545,8 @@ impl Session { if fuel.remaining == 0 && !fuel.out_of_fuel { if self.dcx().can_emit_warnings() { // We only call `msg` in case we can actually emit warnings. - // Otherwise, this could cause a `good_path_delayed_bug` to - // trigger (issue #79546). + // Otherwise, this could cause a `must_produce_diag` ICE + // (issue #79546). self.dcx().emit_warn(errors::OptimisationFuelExhausted { msg: msg() }); } fuel.out_of_fuel = true; diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index c9e23efcb10..1e0a60bc371 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -9,6 +9,7 @@ rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle" } +rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } scoped-tls = "1.0" diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 43987fcf10f..6bb8c5452b9 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -85,6 +85,10 @@ impl<'tcx> Tables<'tcx> { stable_mir::ty::AdtDef(self.create_def_id(did)) } + pub fn foreign_module_def(&mut self, did: DefId) -> stable_mir::ty::ForeignModuleDef { + stable_mir::ty::ForeignModuleDef(self.create_def_id(did)) + } + pub fn foreign_def(&mut self, did: DefId) -> stable_mir::ty::ForeignDef { stable_mir::ty::ForeignDef(self.create_def_id(did)) } diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 70d7200bf60..b95186b0a1c 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -22,10 +22,10 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef}; use stable_mir::mir::Body; use stable_mir::target::{MachineInfo, MachineSize}; use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs, - LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef, + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, + ForeignItemKind, GenericArgs, LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef, }; -use stable_mir::{Crate, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol}; +use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol}; use std::cell::RefCell; use std::iter; @@ -67,6 +67,39 @@ impl<'tcx> Context for TablesWrapper<'tcx> { tables.tcx.is_mir_available(def_id) } + fn foreign_modules(&self, crate_num: CrateNum) -> Vec<stable_mir::ty::ForeignModuleDef> { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + tcx.foreign_modules(crate_num.internal(&mut *tables, tcx)) + .keys() + .map(|mod_def_id| tables.foreign_module_def(*mod_def_id)) + .collect() + } + + fn foreign_module( + &self, + mod_def: stable_mir::ty::ForeignModuleDef, + ) -> stable_mir::ty::ForeignModule { + let mut tables = self.0.borrow_mut(); + let def_id = tables[mod_def.def_id()]; + let mod_def = tables.tcx.foreign_modules(def_id.krate).get(&def_id).unwrap(); + mod_def.stable(&mut *tables) + } + + fn foreign_items(&self, mod_def: stable_mir::ty::ForeignModuleDef) -> Vec<ForeignDef> { + let mut tables = self.0.borrow_mut(); + let def_id = tables[mod_def.def_id()]; + tables + .tcx + .foreign_modules(def_id.krate) + .get(&def_id) + .unwrap() + .foreign_items + .iter() + .map(|item_def| tables.foreign_def(*item_def)) + .collect() + } + fn all_trait_decls(&self) -> stable_mir::TraitDecls { let mut tables = self.0.borrow_mut(); tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect() @@ -225,6 +258,21 @@ impl<'tcx> Context for TablesWrapper<'tcx> { tables.tcx.is_foreign_item(tables[item]) } + fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { + let mut tables = self.0.borrow_mut(); + let def_id = tables[def.def_id()]; + let tcx = tables.tcx; + use rustc_hir::def::DefKind; + match tcx.def_kind(def_id) { + DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)), + DefKind::Static(..) => ForeignItemKind::Static(tables.static_def(def_id)), + DefKind::ForeignTy => ForeignItemKind::Type( + tables.intern_ty(rustc_middle::ty::Ty::new_foreign(tcx, def_id)), + ), + def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind), + } + } + fn adt_kind(&self, def: AdtDef) -> AdtKind { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 959a17d24b7..29081418200 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -202,41 +202,13 @@ where impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { type T = stable_mir::ty::FnSig; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - use rustc_target::spec::abi; - use stable_mir::ty::{Abi, FnSig}; + use stable_mir::ty::FnSig; FnSig { inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(), c_variadic: self.c_variadic, unsafety: self.unsafety.stable(tables), - abi: match self.abi { - abi::Abi::Rust => Abi::Rust, - abi::Abi::C { unwind } => Abi::C { unwind }, - abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind }, - abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind }, - abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind }, - abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind }, - abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind }, - abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind }, - abi::Abi::Win64 { unwind } => Abi::Win64 { unwind }, - abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind }, - abi::Abi::PtxKernel => Abi::PtxKernel, - abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt, - abi::Abi::X86Interrupt => Abi::X86Interrupt, - abi::Abi::EfiApi => Abi::EfiApi, - abi::Abi::AvrInterrupt => Abi::AvrInterrupt, - abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt, - abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall, - abi::Abi::Wasm => Abi::Wasm, - abi::Abi::System { unwind } => Abi::System { unwind }, - abi::Abi::RustIntrinsic => Abi::RustIntrinsic, - abi::Abi::RustCall => Abi::RustCall, - abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic, - abi::Abi::Unadjusted => Abi::Unadjusted, - abi::Abi::RustCold => Abi::RustCold, - abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM, - abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS, - }, + abi: self.abi.stable(tables), } } } @@ -832,3 +804,51 @@ impl<'tcx> Stable<'tcx> for ty::Movability { } } } + +impl<'tcx> Stable<'tcx> for rustc_target::spec::abi::Abi { + type T = stable_mir::ty::Abi; + + fn stable(&self, _: &mut Tables<'_>) -> Self::T { + use rustc_target::spec::abi; + use stable_mir::ty::Abi; + match *self { + abi::Abi::Rust => Abi::Rust, + abi::Abi::C { unwind } => Abi::C { unwind }, + abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind }, + abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind }, + abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind }, + abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind }, + abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind }, + abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind }, + abi::Abi::Win64 { unwind } => Abi::Win64 { unwind }, + abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind }, + abi::Abi::PtxKernel => Abi::PtxKernel, + abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt, + abi::Abi::X86Interrupt => Abi::X86Interrupt, + abi::Abi::EfiApi => Abi::EfiApi, + abi::Abi::AvrInterrupt => Abi::AvrInterrupt, + abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt, + abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall, + abi::Abi::Wasm => Abi::Wasm, + abi::Abi::System { unwind } => Abi::System { unwind }, + abi::Abi::RustIntrinsic => Abi::RustIntrinsic, + abi::Abi::RustCall => Abi::RustCall, + abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic, + abi::Abi::Unadjusted => Abi::Unadjusted, + abi::Abi::RustCold => Abi::RustCold, + abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM, + abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS, + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule { + type T = stable_mir::ty::ForeignModule; + + fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + stable_mir::ty::ForeignModule { + def_id: tables.foreign_module_def(self.def_id), + abi: self.abi.stable(tables), + } + } +} diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index c05c9961750..81be5c09164 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -3,33 +3,27 @@ //! of our more general approach to "lazy normalization". //! //! This is done by first normalizing both sides of the goal, ending up in -//! either a concrete type, rigid projection, opaque, or an infer variable. +//! either a concrete type, rigid alias, or an infer variable. //! These are related further according to the rules below: //! -//! (1.) If we end up with a rigid projection and a rigid projection, then we -//! relate those projections structurally. +//! (1.) If we end up with two rigid aliases, then we relate them structurally. //! -//! (2.) If we end up with a rigid projection and an alias, then the opaque will -//! have its hidden type defined to be that rigid projection. -//! -//! (3.) If we end up with an opaque and an opaque, then we assemble two -//! candidates, one defining the LHS to be the hidden type of the RHS, and vice -//! versa. -//! -//! (4.) If we end up with an infer var and an opaque or rigid projection, then +//! (2.) If we end up with an infer var and a rigid alias, then //! we assign the alias to the infer var. //! -//! (5.) If we end up with an opaque and a rigid (non-projection) type, then we -//! define the hidden type of the opaque to be the rigid type. -//! -//! (6.) Otherwise, if we end with two rigid (non-projection) or infer types, +//! (3.) Otherwise, if we end with two rigid (non-projection) or infer types, //! relate them structurally. +//! +//! Subtle: when relating an opaque to another type, we emit a +//! `NormalizesTo(opaque, ?fresh_var)` goal when trying to normalize the opaque. +//! This nested goal starts out as ambiguous and does not actually define the opaque. +//! However, if `?fresh_var` ends up geteting equated to another type, we retry the +//! `NormalizesTo` goal, at which point the opaque is actually defined. use super::{EvalCtxt, GoalSource}; -use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::query::NoSolution; use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; -use rustc_middle::ty; +use rustc_middle::ty::{self, Ty}; impl<'tcx> EvalCtxt<'_, 'tcx> { #[instrument(level = "debug", skip(self), ret)] @@ -59,37 +53,32 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } - (Some(alias), None) => { + (Some(_), None) => { if rhs.is_infer() { self.relate(param_env, lhs, variance, rhs)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } else if alias.is_opaque(tcx) { - // FIXME: This doesn't account for variance. - self.define_opaque(param_env, alias, rhs) } else { Err(NoSolution) } } - (None, Some(alias)) => { + (None, Some(_)) => { if lhs.is_infer() { self.relate(param_env, lhs, variance, rhs)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } else if alias.is_opaque(tcx) { - // FIXME: This doesn't account for variance. - self.define_opaque(param_env, alias, lhs) } else { Err(NoSolution) } } (Some(alias_lhs), Some(alias_rhs)) => { - self.relate_rigid_alias_or_opaque(param_env, alias_lhs, variance, alias_rhs) + self.relate(param_env, alias_lhs, variance, alias_rhs)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } } // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var. - /// Normalize the `term` to equate it later. This does not define opaque types. + /// Normalize the `term` to equate it later. #[instrument(level = "debug", skip(self, param_env), ret)] fn try_normalize_term( &mut self, @@ -98,10 +87,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ) -> Result<Option<ty::Term<'tcx>>, NoSolution> { match term.unpack() { ty::TermKind::Ty(ty) => { - // We do no define opaque types here but instead do so in `relate_rigid_alias_or_opaque`. - Ok(self - .try_normalize_ty_recur(param_env, DefineOpaqueTypes::No, 0, ty) - .map(Into::into)) + Ok(self.try_normalize_ty_recur(param_env, 0, ty).map(Into::into)) } ty::TermKind::Const(_) => { if let Some(alias) = term.to_alias_ty(self.tcx()) { @@ -119,51 +105,34 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - fn define_opaque( + fn try_normalize_ty_recur( &mut self, param_env: ty::ParamEnv<'tcx>, - opaque: ty::AliasTy<'tcx>, - term: ty::Term<'tcx>, - ) -> QueryResult<'tcx> { - self.add_goal( - GoalSource::Misc, - Goal::new(self.tcx(), param_env, ty::NormalizesTo { alias: opaque, term }), - ); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } - - fn relate_rigid_alias_or_opaque( - &mut self, - param_env: ty::ParamEnv<'tcx>, - lhs: ty::AliasTy<'tcx>, - variance: ty::Variance, - rhs: ty::AliasTy<'tcx>, - ) -> QueryResult<'tcx> { - let tcx = self.tcx(); - let mut candidates = vec![]; - if lhs.is_opaque(tcx) { - candidates.extend( - self.probe_misc_candidate("define-lhs-opaque") - .enter(|ecx| ecx.define_opaque(param_env, lhs, rhs.to_ty(tcx).into())), - ); + depth: usize, + ty: Ty<'tcx>, + ) -> Option<Ty<'tcx>> { + if !self.tcx().recursion_limit().value_within_limit(depth) { + return None; } - if rhs.is_opaque(tcx) { - candidates.extend( - self.probe_misc_candidate("define-rhs-opaque") - .enter(|ecx| ecx.define_opaque(param_env, rhs, lhs.to_ty(tcx).into())), - ); - } - - candidates.extend(self.probe_misc_candidate("args-relate").enter(|ecx| { - ecx.relate(param_env, lhs, variance, rhs)?; - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - })); + let ty::Alias(_, alias) = *ty.kind() else { + return Some(ty); + }; - if let Some(result) = self.try_merge_responses(&candidates) { - Ok(result) - } else { - self.flounder(&candidates) + match self.commit_if_ok(|this| { + let normalized_ty = this.next_ty_infer(); + let normalizes_to_goal = Goal::new( + this.tcx(), + param_env, + ty::NormalizesTo { alias, term: normalized_ty.into() }, + ); + this.add_goal(GoalSource::Misc, normalizes_to_goal); + this.try_evaluate_added_goals()?; + let ty = this.resolve_vars_if_possible(normalized_ty); + Ok(this.try_normalize_ty_recur(param_env, depth + 1, ty)) + }) { + Ok(ty) => ty, + Err(NoSolution) => Some(ty), } } } diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 6833d2ae330..00c22e9e2c3 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -276,11 +276,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { &mut self, goal: Goal<'tcx, G>, ) -> Vec<Candidate<'tcx>> { - let Some(normalized_self_ty) = - self.try_normalize_ty(goal.param_env, goal.predicate.self_ty()) + let Ok(normalized_self_ty) = + self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty()) else { - debug!("overflow while evaluating self type"); - return self.forced_ambiguity(MaybeCause::Overflow); + return vec![]; }; if normalized_self_ty.is_ty_var() { @@ -338,6 +337,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let mut consider_impls_for_simplified_type = |simp| { if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) { for &impl_def_id in impls_for_type { + // For every `default impl`, there's always a non-default `impl` + // that will *also* apply. There's no reason to register a candidate + // for this impl, since it is *not* proof that the trait goal holds. + if tcx.defaultness(impl_def_id).is_default() { + return; + } + match G::consider_impl_candidate(self, goal, impl_def_id) { Ok(candidate) => candidates.push(candidate), Err(NoSolution) => (), @@ -441,6 +447,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let tcx = self.tcx(); let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx)); for &impl_def_id in trait_impls.blanket_impls() { + // For every `default impl`, there's always a non-default `impl` + // that will *also* apply. There's no reason to register a candidate + // for this impl, since it is *not* proof that the trait goal holds. + if tcx.defaultness(impl_def_id).is_default() { + return; + } + match G::consider_impl_candidate(self, goal, impl_def_id) { Ok(candidate) => candidates.push(candidate), Err(NoSolution) => (), @@ -635,19 +648,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return; } - match self.try_normalize_ty(goal.param_env, alias_ty.self_ty()) { - // Recurse on the self type of the projection. - Some(next_self_ty) => { - self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates); - } - // Bail if we overflow when normalizing, adding an ambiguous candidate. - None => { - if let Ok(result) = - self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW) - { - candidates.push(Candidate { source: CandidateSource::AliasBound, result }); - } + // Recurse on the self type of the projection. + match self.structurally_normalize_ty(goal.param_env, alias_ty.self_ty()) { + Ok(next_self_ty) => { + self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates) } + Err(NoSolution) => {} } } @@ -857,19 +863,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let tcx = self.tcx(); let result = self.probe_misc_candidate("coherence unknowable").enter(|ecx| { let trait_ref = goal.predicate.trait_ref(tcx); - #[derive(Debug)] - struct Overflow; - let lazily_normalize_ty = |ty| match ecx.try_normalize_ty(goal.param_env, ty) { - Some(ty) => Ok(ty), - None => Err(Overflow), - }; + let lazily_normalize_ty = |ty| ecx.structurally_normalize_ty(goal.param_env, ty); - match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty) { - Err(Overflow) => { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW) - } - Ok(Ok(())) => Err(NoSolution), - Ok(Err(_)) => { + match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty)? { + Ok(()) => Err(NoSolution), + Err(_) => { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index a7330136fe7..94a3cef8ad1 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -15,15 +15,13 @@ //! about it on zulip. use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; -use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::query::NoSolution; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::{ CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, IsNormalizesToHack, QueryResult, Response, }; -use rustc_middle::traits::Reveal; -use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, UniverseIndex}; +use rustc_middle::ty::{self, AliasRelationDirection, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{ CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate, }; @@ -267,71 +265,32 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(self.make_ambiguous_response_no_constraints(maybe_cause)) } - /// Normalize a type when it is structually matched on. + /// Normalize a type for when it is structurally matched on. /// - /// In nearly all cases this function must be used before matching on a type. + /// This function is necessary in nearly all cases before matching on a type. /// Not doing so is likely to be incomplete and therefore unsound during /// coherence. - #[instrument(level = "debug", skip(self), ret)] - fn try_normalize_ty( - &mut self, - param_env: ty::ParamEnv<'tcx>, - ty: Ty<'tcx>, - ) -> Option<Ty<'tcx>> { - self.try_normalize_ty_recur(param_env, DefineOpaqueTypes::Yes, 0, ty) - } - - fn try_normalize_ty_recur( + fn structurally_normalize_ty( &mut self, param_env: ty::ParamEnv<'tcx>, - define_opaque_types: DefineOpaqueTypes, - depth: usize, ty: Ty<'tcx>, - ) -> Option<Ty<'tcx>> { - if !self.tcx().recursion_limit().value_within_limit(depth) { - return None; - } - - let ty::Alias(kind, alias) = *ty.kind() else { - return Some(ty); - }; - - // We do no always define opaque types eagerly to allow non-defining uses - // in the defining scope. However, if we can unify this opaque to an existing - // opaque, then we should attempt to eagerly reveal the opaque, and we fall - // through. - if let DefineOpaqueTypes::No = define_opaque_types - && let Reveal::UserFacing = param_env.reveal() - && let ty::Opaque = kind - && let Some(def_id) = alias.def_id.as_local() - && self.can_define_opaque_ty(def_id) - { - if self - .unify_existing_opaque_tys( - param_env, - OpaqueTypeKey { def_id, args: alias.args }, - self.next_ty_infer(), - ) - .is_empty() - { - return Some(ty); - } - } - - match self.commit_if_ok(|this| { - let normalized_ty = this.next_ty_infer(); - let normalizes_to_goal = Goal::new( - this.tcx(), + ) -> Result<Ty<'tcx>, NoSolution> { + if let ty::Alias(..) = ty.kind() { + let normalized_ty = self.next_ty_infer(); + let alias_relate_goal = Goal::new( + self.tcx(), param_env, - ty::NormalizesTo { alias, term: normalized_ty.into() }, + ty::PredicateKind::AliasRelate( + ty.into(), + normalized_ty.into(), + AliasRelationDirection::Equate, + ), ); - this.add_goal(GoalSource::Misc, normalizes_to_goal); - this.try_evaluate_added_goals()?; - let ty = this.resolve_vars_if_possible(normalized_ty); - Ok(this.try_normalize_ty_recur(param_env, define_opaque_types, depth + 1, ty)) - }) { - Ok(ty) => ty, - Err(NoSolution) => Some(ty), + self.add_goal(GoalSource::Misc, alias_relate_goal); + self.try_evaluate_added_goals()?; + Ok(self.resolve_vars_if_possible(normalized_ty)) + } else { + Ok(ty) } } } diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaques.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaques.rs index b5d1aa06e4e..356c3776c04 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaques.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaques.rs @@ -58,21 +58,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - let expected = match self.try_normalize_ty(goal.param_env, expected) { - Some(ty) => { - if ty.is_ty_var() { - return self.evaluate_added_goals_and_make_canonical_response( - Certainty::AMBIGUOUS, - ); - } else { - ty - } - } - None => { - return self - .evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW); - } - }; + let expected = self.structurally_normalize_ty(goal.param_env, expected)?; + if expected.is_ty_var() { + return self + .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); + } // Otherwise, define a new opaque type self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?; diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 7a466241bfa..eacdd9fde51 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -584,11 +584,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let a_ty = goal.predicate.self_ty(); // We need to normalize the b_ty since it's matched structurally // in the other functions below. - let b_ty = match ecx - .try_normalize_ty(goal.param_env, goal.predicate.trait_ref.args.type_at(1)) - { - Some(b_ty) => b_ty, - None => return vec![misc_candidate(ecx, Certainty::OVERFLOW)], + let Ok(b_ty) = ecx.structurally_normalize_ty( + goal.param_env, + goal.predicate.trait_ref.args.type_at(1), + ) else { + return vec![]; }; let goal = goal.with(ecx.tcx(), (a_ty, b_ty)); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 81c72fc4b7b..fbf96833187 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -524,13 +524,15 @@ impl<'tcx> AutoTraitFinder<'tcx> { if let Entry::Occupied(v) = vid_map.entry(*smaller) { let smaller_deps = v.into_mut(); smaller_deps.larger.insert(*larger); - smaller_deps.larger.remove(&target); + // FIXME(#120456) - is `swap_remove` correct? + smaller_deps.larger.swap_remove(&target); } if let Entry::Occupied(v) = vid_map.entry(*larger) { let larger_deps = v.into_mut(); larger_deps.smaller.insert(*smaller); - larger_deps.smaller.remove(&target); + // FIXME(#120456) - is `swap_remove` correct? + larger_deps.smaller.swap_remove(&target); } } (&RegionTarget::RegionVid(v1), &RegionTarget::Region(r1)) => { @@ -543,13 +545,15 @@ impl<'tcx> AutoTraitFinder<'tcx> { if let Entry::Occupied(v) = vid_map.entry(*smaller) { let smaller_deps = v.into_mut(); smaller_deps.larger.insert(*larger); - smaller_deps.larger.remove(&target); + // FIXME(#120456) - is `swap_remove` correct? + smaller_deps.larger.swap_remove(&target); } if let Entry::Occupied(v) = vid_map.entry(*larger) { let larger_deps = v.into_mut(); larger_deps.smaller.insert(*smaller); - larger_deps.smaller.remove(&target); + // FIXME(#120456) - is `swap_remove` correct? + larger_deps.smaller.swap_remove(&target); } } } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 522c645253a..1edf6b11fc3 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -62,9 +62,10 @@ pub fn is_const_evaluatable<'tcx>( match unexpanded_ct.kind() { ty::ConstKind::Expr(_) => { - // FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but - // currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it - // is evaluatable or not. For now we just ICE until this is implemented. + // FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, + // but currently it is not possible to evaluate `ConstKind::Expr` so we are unable + // to tell if it is evaluatable or not. For now we just ICE until this is + // implemented. Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug( span, "evaluating `ConstKind::Expr` is not currently supported", diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index c7b56aac7e5..335e6ff2822 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3041,7 +3041,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { this = "the implicit `Sized` requirement on this type parameter"; } if let Some(hir::Node::TraitItem(hir::TraitItem { - ident, + generics, kind: hir::TraitItemKind::Type(bounds, None), .. })) = tcx.hir().get_if_local(item_def_id) @@ -3053,7 +3053,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let (span, separator) = if let [.., last] = bounds { (last.span().shrink_to_hi(), " +") } else { - (ident.span.shrink_to_hi(), ":") + (generics.span.shrink_to_hi(), ":") }; err.span_suggestion_verbose( span, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index c5ee0391682..73effb33560 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -236,9 +236,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - // It could be that we don't report an error because we have seen an `ErrorReported` from another source. - // We should probably be able to fix most of these, but some are delayed bugs that get a proper error - // after this function. + // It could be that we don't report an error because we have seen an `ErrorReported` from + // another source. We should probably be able to fix most of these, but some are delayed + // bugs that get a proper error after this function. reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors")) } @@ -519,7 +519,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref, span, ) { - GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"), + GetSafeTransmuteErrorAndReason::Silent => { + return self.dcx().span_delayed_bug( + span, "silent safe transmute error" + ); + } GetSafeTransmuteErrorAndReason::Error { err_msg, safe_transmute_explanation, @@ -2990,7 +2994,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { (s, " +") } else { - (span.shrink_to_hi(), ":") + (param.name.ident().span.shrink_to_hi(), ":") }; err.span_suggestion_verbose( span, @@ -3112,10 +3116,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation.param_env, trait_ref.args.const_at(3), ) else { - span_bug!( + self.dcx().span_delayed_bug( span, - "Unable to construct rustc_transmute::Assume where it was previously possible" + "Unable to construct rustc_transmute::Assume where it was previously possible", ); + return GetSafeTransmuteErrorAndReason::Silent; }; match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 5ef7a202a12..7ad94274634 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -423,6 +423,21 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::AliasRelate(..) => { bug!("AliasRelate is only used by the new solver") } + // Compute `ConstArgHasType` above the overflow check below. + // This is because this is not ever a useful obligation to report + // as the cause of an overflow. + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { + match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( + DefineOpaqueTypes::No, + ct.ty(), + ty, + ) { + Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())), + Err(_) => ProcessResult::Error(FulfillmentErrorCode::SelectionError( + SelectionError::Unimplemented, + )), + } + } // General case overflow check. Allow `process_trait_obligation` // and `process_projection_obligation` to handle checking for @@ -650,18 +665,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } } - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( - DefineOpaqueTypes::No, - ct.ty(), - ty, - ) { - Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())), - Err(_) => ProcessResult::Error(FulfillmentErrorCode::SelectionError( - SelectionError::Unimplemented, - )), - } - } }, } } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 29a4a078fe0..7b715984c2b 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -555,7 +555,7 @@ fn virtual_call_violations_for_method<'tcx>( // NOTE: This check happens last, because it results in a lint, and not a // hard error. - if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, span)| { + if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, _span)| { // dyn Trait is okay: // // trait Trait { @@ -594,7 +594,10 @@ fn virtual_call_violations_for_method<'tcx>( // would already have reported an error at the definition of the // auto trait. if pred_trait_ref.args.len() != 1 { - tcx.dcx().span_delayed_bug(span, "auto traits cannot have generic parameters"); + assert!( + tcx.dcx().has_errors().is_some(), + "auto traits cannot have generic parameters" + ); } return false; } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 31a0d6271fa..149dc4c75a7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -566,6 +566,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { return; } + + // For every `default impl`, there's always a non-default `impl` + // that will *also* apply. There's no reason to register a candidate + // for this impl, since it is *not* proof that the trait goal holds. + if self.tcx().defaultness(impl_def_id).is_default() { + return; + } + if self.reject_fn_ptr_impls( impl_def_id, obligation, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2ce33a4d122..e4a70c537d2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -192,13 +192,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut obligations, ); - obligations.extend(self.infcx.commit_if_ok(|_| { + obligations.extend( self.infcx .at(&obligation.cause, obligation.param_env) .sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) .map(|InferOk { obligations, .. }| obligations) - .map_err(|_| Unimplemented) - })?); + .map_err(|_| Unimplemented)?, + ); // FIXME(compiler-errors): I don't think this is needed. if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() { @@ -532,13 +532,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut nested, ); - nested.extend(self.infcx.commit_if_ok(|_| { + nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) .sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref) .map(|InferOk { obligations, .. }| obligations) - .map_err(|_| Unimplemented) - })?); + .map_err(|_| Unimplemented)?, + ); // Check supertraits hold. This is so that their associated type bounds // will be checked in the code below. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 185b735594f..ab0c53e6a9b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1605,6 +1605,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { on_ambiguity: impl FnOnce(), ) -> ControlFlow<T, ()> { let mut idx = 0; + let mut in_parent_alias_type = false; + loop { let (kind, alias_ty) = match *self_ty.kind() { ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty), @@ -1618,6 +1620,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for bound in self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) { + // HACK: On subsequent recursions, we only care about bounds that don't + // share the same type as `self_ty`. This is because for truly rigid + // projections, we will never be able to equate, e.g. `<T as Tr>::A` + // with `<<T as Tr>::A as Tr>::A`. + if in_parent_alias_type { + match bound.kind().skip_binder() { + ty::ClauseKind::Trait(tr) if tr.self_ty() == self_ty => continue, + ty::ClauseKind::Projection(p) if p.self_ty() == self_ty => continue, + _ => {} + } + } + for_each(self, bound, idx)?; idx += 1; } @@ -1627,6 +1641,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else { return ControlFlow::Continue(()); } + + in_parent_alias_type = true; } } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 73df1be6b55..e1a49ecf1b6 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -522,7 +522,8 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti for (p, _) in predicates { if let Some(poly_trait_ref) = p.as_trait_clause() { if Some(poly_trait_ref.def_id()) == sized_trait { - types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder()); + // FIXME(#120456) - is `swap_remove` correct? + types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); continue; } } diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 89459f377dd..e6b42f15d51 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,7 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use rustc_span::Span; use std::ops::ControlFlow; /// This method traverses the structure of `ty`, trying to find an @@ -30,19 +29,16 @@ use std::ops::ControlFlow; /// that arose when the requirement was not enforced completely, see /// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. pub fn search_for_structural_match_violation<'tcx>( - span: Span, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, ) -> Option<Ty<'tcx>> { - ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value() + ty.visit_with(&mut Search { tcx, seen: FxHashSet::default() }).break_value() } /// This implements the traversal over the structure of a given type to try to /// find instances of ADTs (specifically structs or enums) that do not implement /// `StructuralPartialEq`. struct Search<'tcx> { - span: Span, - tcx: TyCtxt<'tcx>, /// Tracks ADTs previously encountered during search, so that @@ -138,7 +134,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> { bug!("unexpected type during structural-match checking: {:?}", ty); } ty::Error(_) => { - self.tcx.dcx().span_delayed_bug(self.span, "ty::Error in structural-match check"); // We still want to check other types after encountering an error, // as this may still emit relevant errors. return ControlFlow::Continue(()); diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs new file mode 100644 index 00000000000..57f961ac97e --- /dev/null +++ b/compiler/rustc_type_ir/src/binder.rs @@ -0,0 +1,7 @@ +use crate::Interner; + +pub trait BoundVars<I: Interner> { + fn bound_vars(&self) -> I::BoundVars; + + fn has_no_bound_vars(&self) -> bool; +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 188910ecc52..7728ee0e842 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -2,9 +2,10 @@ use smallvec::SmallVec; use std::fmt::Debug; use std::hash::Hash; +use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{ - BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind, - UniverseIndex, + BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, + TyKind, UniverseIndex, }; pub trait Interner: Sized { @@ -19,7 +20,10 @@ pub trait Interner: Sized { type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord; type Term: Copy + Debug + Hash + Ord; - type Binder<T>; + type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>; + type BoundVars: IntoIterator<Item = Self::BoundVar>; + type BoundVar; + type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>; // Kinds of tys @@ -28,7 +32,9 @@ pub trait Interner: Sized { + Hash + Ord + Into<Self::GenericArg> - + IntoKind<Kind = TyKind<Self>>; + + IntoKind<Kind = TyKind<Self>> + + TypeSuperVisitable<Self> + + Flags; type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>; type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord; type ParamTy: Copy + Debug + Hash + Ord; @@ -48,7 +54,9 @@ pub trait Interner: Sized { + Ord + Into<Self::GenericArg> + IntoKind<Kind = ConstKind<Self>> - + ConstTy<Self>; + + ConstTy<Self> + + TypeSuperVisitable<Self> + + Flags; type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord; type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike; type ParamConst: Copy + Debug + Hash + Ord; @@ -62,7 +70,8 @@ pub trait Interner: Sized { + Hash + Ord + Into<Self::GenericArg> - + IntoKind<Kind = RegionKind<Self>>; + + IntoKind<Kind = RegionKind<Self>> + + Flags; type EarlyParamRegion: Copy + Debug + Hash + Ord; type LateParamRegion: Copy + Debug + Hash + Ord; type BoundRegion: Copy + Debug + Hash + Ord; @@ -70,7 +79,7 @@ pub trait Interner: Sized { type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike; // Predicates - type Predicate: Copy + Debug + Hash + Eq; + type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags; type TraitPredicate: Copy + Debug + Hash + Eq; type RegionOutlivesPredicate: Copy + Debug + Hash + Eq; type TypeOutlivesPredicate: Copy + Debug + Hash + Eq; @@ -86,6 +95,9 @@ pub trait Interner: Sized { fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty; fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region; fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const; + + /// Assert that an error has been delayed or emitted. + fn expect_error_or_delayed_bug(); } /// Common capabilities of placeholder kinds diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index f498c5531fc..94ccbcbd8a5 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -30,6 +30,7 @@ pub mod visit; #[macro_use] mod macros; +mod binder; mod canonical; mod const_kind; mod debug; @@ -39,6 +40,7 @@ mod interner; mod predicate_kind; mod region_kind; +pub use binder::*; pub use canonical::*; #[cfg(feature = "nightly")] pub use codec::*; diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 7aa99004667..638fb9f7fa9 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -45,8 +45,7 @@ use rustc_index::{Idx, IndexVec}; use std::fmt; use std::ops::ControlFlow; -use crate::Interner; -use crate::Lrc; +use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -88,38 +87,28 @@ pub trait TypeVisitor<I: Interner>: Sized { #[cfg(not(feature = "nightly"))] type BreakTy; - fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy> - where - I::Binder<T>: TypeSuperVisitable<I>, - { + fn visit_binder<T: TypeVisitable<I>>( + &mut self, + t: &I::Binder<T>, + ) -> ControlFlow<Self::BreakTy> { t.super_visit_with(self) } - fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> - where - I::Ty: TypeSuperVisitable<I>, - { + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> { t.super_visit_with(self) } // The default region visitor is a no-op because `Region` is non-recursive - // and has no `super_visit_with` method to call. That also explains the - // lack of `I::Region: TypeSuperVisitable<I>` bound. + // and has no `super_visit_with` method to call. fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> { ControlFlow::Continue(()) } - fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> - where - I::Const: TypeSuperVisitable<I>, - { + fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> { c.super_visit_with(self) } - fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> - where - I::Predicate: TypeSuperVisitable<I>, - { + fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> { p.super_visit_with(self) } } @@ -200,3 +189,363 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix self.iter().try_for_each(|t| t.visit_with(visitor)) } } + +pub trait Flags { + fn flags(&self) -> TypeFlags; + fn outer_exclusive_binder(&self) -> ty::DebruijnIndex; +} + +pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> { + fn has_type_flags(&self, flags: TypeFlags) -> bool; + + /// Returns `true` if `self` has any late-bound regions that are either + /// bound by `binder` or bound by some binder outside of `binder`. + /// If `binder` is `ty::INNERMOST`, this indicates whether + /// there are any late-bound regions that appear free. + fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool; + + /// Returns `true` if this type has any regions that escape `binder` (and + /// hence are not bound by it). + fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool { + self.has_vars_bound_at_or_above(binder.shifted_in(1)) + } + + /// Return `true` if this type has regions that are not a part of the type. + /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)` + /// would return `true`. The latter can occur when traversing through the + /// former. + /// + /// See [`HasEscapingVarsVisitor`] for more information. + fn has_escaping_bound_vars(&self) -> bool { + self.has_vars_bound_at_or_above(ty::INNERMOST) + } + + fn has_projections(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PROJECTION) + } + + fn has_inherent_projections(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INHERENT) + } + + fn has_opaque_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) + } + + fn has_coroutines(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_COROUTINE) + } + + fn references_error(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_ERROR) + } + + fn error_reported(&self) -> Result<(), I::ErrorGuaranteed>; + + fn has_non_region_param(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM) + } + + fn has_infer_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_INFER) + } + + fn has_infer_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INFER) + } + + fn has_non_region_infer(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER) + } + + fn has_infer(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_INFER) + } + + fn has_placeholders(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PLACEHOLDER) + } + + fn has_non_region_placeholders(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER) + } + + fn has_param(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PARAM) + } + + /// "Free" regions in this context means that it has any region + /// that is not (a) erased or (b) late-bound. + fn has_free_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) + } + + fn has_erased_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_ERASED) + } + + /// True if there are any un-erased free regions. + fn has_erasable_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) + } + + /// Indicates whether this value references only 'global' + /// generic parameters that are the same regardless of what fn we are + /// in. This is used for caching. + fn is_global(&self) -> bool { + !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES) + } + + /// True if there are any late-bound regions + fn has_bound_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_BOUND) + } + /// True if there are any late-bound non-region variables + fn has_non_region_bound_vars(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND) + } + /// True if there are any bound variables + fn has_bound_vars(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_BOUND_VARS) + } + + /// Indicates whether this value still has parameters/placeholders/inference variables + /// which could be replaced later, in a way that would change the results of `impl` + /// specialization. + fn still_further_specializable(&self) -> bool { + self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + let res = + self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags); + res + } + + fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { + self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break() + } + + fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> { + if self.references_error() { + if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) { + Err(guar) + } else { + panic!("type flags said there was an error, but now there is not") + } + } else { + Ok(()) + } + } +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +struct FoundFlags; + +// FIXME: Optimize for checking for infer flags +struct HasTypeFlagsVisitor { + flags: ty::TypeFlags, +} + +impl std::fmt::Debug for HasTypeFlagsVisitor { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.flags.fmt(fmt) + } +} + +// Note: this visitor traverses values down to the level of +// `Ty`/`Const`/`Predicate`, but not within those types. This is because the +// type flags at the outer layer are enough. So it's faster than it first +// looks, particular for `Ty`/`Predicate` where it's just a field access. +// +// N.B. The only case where this isn't totally true is binders, which also +// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that +// are present, regardless of whether those bound variables are used. This +// is important for anonymization of binders in `TyCtxt::erase_regions`. We +// specifically detect this case in `visit_binder`. +impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor { + type BreakTy = FoundFlags; + + fn visit_binder<T: TypeVisitable<I>>( + &mut self, + t: &I::Binder<T>, + ) -> ControlFlow<Self::BreakTy> { + // If we're looking for the HAS_BINDER_VARS flag, check if the + // binder has vars. This won't be present in the binder's bound + // value, so we need to check here too. + if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.has_no_bound_vars() { + return ControlFlow::Break(FoundFlags); + } + + t.super_visit_with(self) + } + + #[inline] + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call. + let flags = t.flags(); + if flags.intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call, as usual for `Region`. + let flags = r.flags(); + if flags.intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call. + if c.flags().intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call. + if predicate.flags().intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +struct FoundEscapingVars; + +/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a +/// bound region or a bound type. +/// +/// So, for example, consider a type like the following, which has two binders: +/// +/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope +/// +/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the +/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner +/// fn type*, that type has an escaping region: `'a`. +/// +/// Note that what I'm calling an "escaping var" is often just called a "free var". However, +/// we already use the term "free var". It refers to the regions or types that we use to represent +/// bound regions or type params on a fn definition while we are type checking its body. +/// +/// To clarify, conceptually there is no particular difference between +/// an "escaping" var and a "free" var. However, there is a big +/// difference in practice. Basically, when "entering" a binding +/// level, one is generally required to do some sort of processing to +/// a bound var, such as replacing it with a fresh/placeholder +/// var, or making an entry in the environment to represent the +/// scope to which it is attached, etc. An escaping var represents +/// a bound var for which this processing has not yet been done. +struct HasEscapingVarsVisitor { + /// Anything bound by `outer_index` or "above" is escaping. + outer_index: ty::DebruijnIndex, +} + +impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor { + type BreakTy = FoundEscapingVars; + + fn visit_binder<T: TypeVisitable<I>>( + &mut self, + t: &I::Binder<T>, + ) -> ControlFlow<Self::BreakTy> { + self.outer_index.shift_in(1); + let result = t.super_visit_with(self); + self.outer_index.shift_out(1); + result + } + + #[inline] + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> { + // If the outer-exclusive-binder is *strictly greater* than + // `outer_index`, that means that `t` contains some content + // bound at `outer_index` or above (because + // `outer_exclusive_binder` is always 1 higher than the + // content in `t`). Therefore, `t` has some escaping vars. + if t.outer_exclusive_binder() > self.outer_index { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> { + // If the region is bound by `outer_index` or anything outside + // of outer index, then it escapes the binders we have + // visited. + if r.outer_exclusive_binder() > self.outer_index { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_const(&mut self, ct: I::Const) -> ControlFlow<Self::BreakTy> { + // If the outer-exclusive-binder is *strictly greater* than + // `outer_index`, that means that `ct` contains some content + // bound at `outer_index` or above (because + // `outer_exclusive_binder` is always 1 higher than the + // content in `t`). Therefore, `t` has some escaping vars. + if ct.outer_exclusive_binder() > self.outer_index { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> { + if predicate.outer_exclusive_binder() > self.outer_index { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } +} + +struct HasErrorVisitor; + +impl<I: Interner> TypeVisitor<I> for HasErrorVisitor { + type BreakTy = I::ErrorGuaranteed; + + fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy> { + if let ty::Error(guar) = t.kind() { + ControlFlow::Break(guar) + } else { + t.super_visit_with(self) + } + } + + fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy> { + if let ty::ConstKind::Error(guar) = c.kind() { + ControlFlow::Break(guar) + } else { + c.super_visit_with(self) + } + } + + fn visit_region(&mut self, r: <I as Interner>::Region) -> ControlFlow<Self::BreakTy> { + if let ty::ReError(guar) = r.kind() { + ControlFlow::Break(guar) + } else { + ControlFlow::Continue(()) + } + } +} diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index de045f6b56c..6272f793f40 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -11,9 +11,10 @@ use crate::mir::mono::{Instance, InstanceDef, StaticDef}; use crate::mir::Body; use crate::target::MachineInfo; use crate::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs, - GenericPredicates, Generics, ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, - TraitDef, Ty, TyKind, VariantDef, + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, + ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics, + ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, TyKind, + VariantDef, }; use crate::{ mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind, @@ -31,6 +32,9 @@ pub trait Context { fn mir_body(&self, item: DefId) -> mir::Body; /// Check whether the body of a function is available. fn has_body(&self, item: DefId) -> bool; + fn foreign_modules(&self, crate_num: CrateNum) -> Vec<ForeignModuleDef>; + fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule; + fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec<ForeignDef>; fn all_trait_decls(&self) -> TraitDecls; fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls; fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl; @@ -66,6 +70,9 @@ pub trait Context { /// Returns whether this is a foreign item. fn is_foreign_item(&self, item: DefId) -> bool; + /// Returns the kind of a given foreign item. + fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind; + /// Returns the kind of a given algebraic data type fn adt_kind(&self, def: AdtDef) -> AdtKind; diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 4f57f532a40..d849c834ae0 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -30,7 +30,7 @@ pub use crate::error::*; use crate::mir::pretty::function_name; use crate::mir::Body; use crate::mir::Mutability; -use crate::ty::{ImplDef, IndexedVal, Span, TraitDef, Ty}; +use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty}; pub mod abi; #[macro_use] @@ -86,6 +86,11 @@ pub struct Crate { } impl Crate { + /// The list of foreign modules in this crate. + pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> { + with(|cx| cx.foreign_modules(self.id)) + } + /// The list of traits declared in this crate. pub fn trait_decls(&self) -> TraitDecls { with(|cx| cx.trait_decls(self.id)) diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index bdda9295347..658e8aa28b5 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -4,9 +4,9 @@ use super::{ with, DefId, Error, Symbol, }; use crate::abi::Layout; -use crate::crate_def::CrateDef; use crate::mir::alloc::{read_target_int, read_target_uint, AllocId}; use crate::target::MachineInfo; +use crate::{crate_def::CrateDef, mir::mono::StaticDef}; use crate::{Filename, Opaque}; use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Range; @@ -540,10 +540,44 @@ pub enum Movability { } crate_def! { + pub ForeignModuleDef; +} + +impl ForeignModuleDef { + pub fn module(&self) -> ForeignModule { + with(|cx| cx.foreign_module(*self)) + } +} + +pub struct ForeignModule { + pub def_id: ForeignModuleDef, + pub abi: Abi, +} + +impl ForeignModule { + pub fn items(&self) -> Vec<ForeignDef> { + with(|cx| cx.foreign_items(self.def_id)) + } +} + +crate_def! { /// Hold information about a ForeignItem in a crate. pub ForeignDef; } +impl ForeignDef { + pub fn kind(&self) -> ForeignItemKind { + with(|cx| cx.foreign_item_kind(*self)) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub enum ForeignItemKind { + Fn(FnDef), + Static(StaticDef), + Type(Ty), +} + crate_def! { /// Hold information about a function definition in a crate. pub FnDef; diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 2b8ddf14ff3..addcc71a2d4 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3247,9 +3247,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> { #[unstable(feature = "btree_cursors", issue = "107540")] pub fn remove_next(&mut self) -> Option<(K, V)> { let current = self.current.take()?; + if current.reborrow().next_kv().is_err() { + self.current = Some(current); + return None; + } let mut emptied_internal_root = false; let (kv, pos) = current .next_kv() + // This should be unwrap(), but that doesn't work because NodeRef + // doesn't implement Debug. The condition is checked above. .ok()? .remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone()); self.current = Some(pos); @@ -3270,9 +3276,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> { #[unstable(feature = "btree_cursors", issue = "107540")] pub fn remove_prev(&mut self) -> Option<(K, V)> { let current = self.current.take()?; + if current.reborrow().next_back_kv().is_err() { + self.current = Some(current); + return None; + } let mut emptied_internal_root = false; let (kv, pos) = current .next_back_kv() + // This should be unwrap(), but that doesn't work because NodeRef + // doesn't implement Debug. The condition is checked above. .ok()? .remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone()); self.current = Some(pos); diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 0338565980c..2cc38d90ffe 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1184,12 +1184,19 @@ impl<T: ?Sized> Rc<T> { /// Constructs an `Rc<T>` from a raw pointer. /// /// The raw pointer must have been previously returned by a call to - /// [`Rc<U>::into_raw`][into_raw] where `U` must have the same size - /// and alignment as `T`. This is trivially true if `U` is `T`. - /// Note that if `U` is not `T` but has the same size and alignment, this is - /// basically like transmuting references of different types. See - /// [`mem::transmute`][transmute] for more information on what - /// restrictions apply in this case. + /// [`Rc<U>::into_raw`][into_raw] with the following requirements: + /// + /// * If `U` is sized, it must have the same size and alignment as `T`. This + /// is trivially true if `U` is `T`. + /// * If `U` is unsized, its data pointer must have the same size and + /// alignment as `T`. This is trivially true if `Rc<U>` was constructed + /// through `Rc<T>` and then converted to `Rc<U>` through an [unsized + /// coercion]. + /// + /// Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. /// /// The raw pointer must point to a block of memory allocated by the global allocator /// @@ -1201,6 +1208,7 @@ impl<T: ?Sized> Rc<T> { /// /// [into_raw]: Rc::into_raw /// [transmute]: core::mem::transmute + /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// /// # Examples /// @@ -1220,6 +1228,20 @@ impl<T: ?Sized> Rc<T> { /// /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! /// ``` + /// + /// Convert a slice back into its original array: + /// + /// ``` + /// use std::rc::Rc; + /// + /// let x: Rc<[u32]> = Rc::new([1, 2, 3]); + /// let x_ptr: *const [u32] = Rc::into_raw(x); + /// + /// unsafe { + /// let x: Rc<[u32; 3]> = Rc::from_raw(x_ptr.cast::<[u32; 3]>()); + /// assert_eq!(&*x, &[1, 2, 3]); + /// } + /// ``` #[inline] #[stable(feature = "rc_raw", since = "1.17.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { @@ -1344,13 +1366,20 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// Constructs an `Rc<T, A>` from a raw pointer in the provided allocator. /// - /// The raw pointer must have been previously returned by a call to - /// [`Rc<U, A>::into_raw`][into_raw] where `U` must have the same size - /// and alignment as `T`. This is trivially true if `U` is `T`. - /// Note that if `U` is not `T` but has the same size and alignment, this is - /// basically like transmuting references of different types. See - /// [`mem::transmute`] for more information on what - /// restrictions apply in this case. + /// The raw pointer must have been previously returned by a call to [`Rc<U, + /// A>::into_raw`][into_raw] with the following requirements: + /// + /// * If `U` is sized, it must have the same size and alignment as `T`. This + /// is trivially true if `U` is `T`. + /// * If `U` is unsized, its data pointer must have the same size and + /// alignment as `T`. This is trivially true if `Rc<U>` was constructed + /// through `Rc<T>` and then converted to `Rc<U>` through an [unsized + /// coercion]. + /// + /// Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. /// /// The raw pointer must point to a block of memory allocated by `alloc` /// @@ -1361,6 +1390,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// even if the returned `Rc<T>` is never accessed. /// /// [into_raw]: Rc::into_raw + /// [transmute]: core::mem::transmute + /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// /// # Examples /// @@ -1383,6 +1414,23 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! /// ``` + /// + /// Convert a slice back into its original array: + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::rc::Rc; + /// use std::alloc::System; + /// + /// let x: Rc<[u32], _> = Rc::new_in([1, 2, 3], System); + /// let x_ptr: *const [u32] = Rc::into_raw(x); + /// + /// unsafe { + /// let x: Rc<[u32; 3], _> = Rc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System); + /// assert_eq!(&*x, &[1, 2, 3]); + /// } + /// ``` #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { let offset = unsafe { data_offset(ptr) }; diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index e16574f3d80..e1211da4c61 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1333,12 +1333,19 @@ impl<T: ?Sized> Arc<T> { /// Constructs an `Arc<T>` from a raw pointer. /// /// The raw pointer must have been previously returned by a call to - /// [`Arc<U>::into_raw`][into_raw] where `U` must have the same size and - /// alignment as `T`. This is trivially true if `U` is `T`. - /// Note that if `U` is not `T` but has the same size and alignment, this is - /// basically like transmuting references of different types. See - /// [`mem::transmute`][transmute] for more information on what - /// restrictions apply in this case. + /// [`Arc<U>::into_raw`][into_raw] with the following requirements: + /// + /// * If `U` is sized, it must have the same size and alignment as `T`. This + /// is trivially true if `U` is `T`. + /// * If `U` is unsized, its data pointer must have the same size and + /// alignment as `T`. This is trivially true if `Arc<U>` was constructed + /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized + /// coercion]. + /// + /// Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. /// /// The user of `from_raw` has to make sure a specific value of `T` is only /// dropped once. @@ -1348,6 +1355,7 @@ impl<T: ?Sized> Arc<T> { /// /// [into_raw]: Arc::into_raw /// [transmute]: core::mem::transmute + /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// /// # Examples /// @@ -1367,6 +1375,20 @@ impl<T: ?Sized> Arc<T> { /// /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! /// ``` + /// + /// Convert a slice back into its original array: + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x: Arc<[u32]> = Arc::new([1, 2, 3]); + /// let x_ptr: *const [u32] = Arc::into_raw(x); + /// + /// unsafe { + /// let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>()); + /// assert_eq!(&*x, &[1, 2, 3]); + /// } + /// ``` #[inline] #[stable(feature = "rc_raw", since = "1.17.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { @@ -1496,13 +1518,20 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// Constructs an `Arc<T, A>` from a raw pointer. /// - /// The raw pointer must have been previously returned by a call to - /// [`Arc<U, A>::into_raw`][into_raw] where `U` must have the same size and - /// alignment as `T`. This is trivially true if `U` is `T`. - /// Note that if `U` is not `T` but has the same size and alignment, this is - /// basically like transmuting references of different types. See - /// [`mem::transmute`] for more information on what - /// restrictions apply in this case. + /// The raw pointer must have been previously returned by a call to [`Arc<U, + /// A>::into_raw`][into_raw] with the following requirements: + /// + /// * If `U` is sized, it must have the same size and alignment as `T`. This + /// is trivially true if `U` is `T`. + /// * If `U` is unsized, its data pointer must have the same size and + /// alignment as `T`. This is trivially true if `Arc<U>` was constructed + /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized + /// coercion]. + /// + /// Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. /// /// The raw pointer must point to a block of memory allocated by `alloc` /// @@ -1513,6 +1542,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// even if the returned `Arc<T>` is never accessed. /// /// [into_raw]: Arc::into_raw + /// [transmute]: core::mem::transmute + /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// /// # Examples /// @@ -1535,6 +1566,23 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! /// ``` + /// + /// Convert a slice back into its original array: + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let x: Arc<[u32], _> = Arc::new_in([1, 2, 3], System); + /// let x_ptr: *const [u32] = Arc::into_raw(x); + /// + /// unsafe { + /// let x: Arc<[u32; 3], _> = Arc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System); + /// assert_eq!(&*x, &[1, 2, 3]); + /// } + /// ``` #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 87db8629ad0..b214f4946b1 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -19,7 +19,7 @@ use core::task::Waker; /// The implementation of waking a task on an executor. /// /// This trait can be used to create a [`Waker`]. An executor can define an -/// implementation of this trait, and use that to construct a Waker to pass +/// implementation of this trait, and use that to construct a [`Waker`] to pass /// to the tasks that are executed on that executor. /// /// This trait is a memory-safe and ergonomic alternative to constructing a @@ -28,7 +28,14 @@ use core::task::Waker; /// those for embedded systems) cannot use this API, which is why [`RawWaker`] /// exists as an alternative for those systems. /// -/// [arc]: ../../std/sync/struct.Arc.html +/// To construct a [`Waker`] from some type `W` implementing this trait, +/// wrap it in an [`Arc<W>`](Arc) and call `Waker::from()` on that. +/// It is also possible to convert to [`RawWaker`] in the same way. +/// +/// <!-- Ideally we'd link to the `From` impl, but rustdoc doesn't generate any page for it within +/// `alloc` because `alloc` neither defines nor re-exports `From` or `Waker`, and we can't +/// link ../../std/task/struct.Waker.html#impl-From%3CArc%3CW,+Global%3E%3E-for-Waker +/// without getting a link-checking error in CI. --> /// /// # Examples /// @@ -100,7 +107,7 @@ pub trait Wake { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "wake_trait", since = "1.51.0")] impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker { - /// Use a `Wake`-able type as a `Waker`. + /// Use a [`Wake`]-able type as a `Waker`. /// /// No heap allocations or atomic operations are used for this conversion. fn from(waker: Arc<W>) -> Waker { diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 78091c01729..1c8e6676544 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -95,8 +95,10 @@ impl fmt::Display for AllocError { /// # Safety /// /// * Memory blocks returned from an allocator that are [*currently allocated*] must point to -/// valid memory and retain their validity while they are [*currently allocated*] and at -/// least one of the instance and all of its clones has not been dropped. +/// valid memory and retain their validity while they are [*currently allocated*] and the shorter +/// of: +/// - the borrow-checker lifetime of the allocator type itself. +/// - as long as at least one of the instance and all of its clones has not been dropped. /// /// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this /// allocator. A copied or cloned allocator must behave like the same allocator, and @@ -114,6 +116,10 @@ pub unsafe trait Allocator { /// The returned block may have a larger size than specified by `layout.size()`, and may or may /// not have its contents initialized. /// + /// The returned block of memory remains valid as long as it is [*currently allocated*] and the shorter of: + /// - the borrow-checker lifetime of the allocator type itself. + /// - as long as at the allocator and all its clones has not been dropped. + /// /// # Errors /// /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index 5f758af1624..34a05ac3888 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -58,7 +58,7 @@ use crate::mem::transmute; #[unstable(feature = "ascii_char", issue = "110998")] #[repr(u8)] pub enum AsciiChar { - /// U+0000 + /// U+0000 (The default variant) #[unstable(feature = "ascii_char_variants", issue = "110998")] Null = 0, /// U+0001 diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 16618b38769..a1303fcd821 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -2,6 +2,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::ascii::Char as AsciiChar; + /// A trait for giving a type a useful default value. /// /// Sometimes, you want to fall back to some kind of default value, and @@ -158,6 +160,7 @@ macro_rules! default_impl { default_impl! { (), (), "Returns the default value of `()`" } default_impl! { bool, false, "Returns the default value of `false`" } default_impl! { char, '\x00', "Returns the default value of `\\x00`" } +default_impl! { AsciiChar, AsciiChar::Null, "Returns the default value of `Null`" } default_impl! { usize, 0, "Returns the default value of `0`" } default_impl! { u8, 0, "Returns the default value of `0`" } diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 9bbaf62a5ca..d818889f364 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -969,6 +969,14 @@ pub(crate) mod builtin { /// let s = fmt::format(format_args!("hello {}", "world")); /// assert_eq!(s, format!("hello {}", "world")); /// ``` + /// + /// # Lifetime limitation + /// + /// Except when no formatting arguments are used, + /// the produced `fmt::Arguments` value borrows temporary values, + /// which means it can only be used within the same expression + /// and cannot be stored for later use. + /// This is a known limitation, see [#92698](https://github.com/rust-lang/rust/issues/92698). #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "format_args_macro")] #[allow_internal_unsafe] diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 1dec2bf40cc..e9a0d9e1d28 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -27,8 +27,9 @@ //! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`. //! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating //! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference -//! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not* -//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.) +//! ends. A Rust atomic type that is exclusively owned or behind a mutable reference does *not* +//! correspond to an “atomic object” in C++, since the underlying primitive can be mutably accessed, +//! for example with `get_mut`, to perform non-atomic operations. //! //! [cpp]: https://en.cppreference.com/w/cpp/atomic //! diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 09f3f2f02ea..b9895f7edea 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -9,10 +9,14 @@ use crate::ptr; /// A `RawWaker` allows the implementor of a task executor to create a [`Waker`] /// or a [`LocalWaker`] which provides customized wakeup behavior. /// -/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table -/// /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] /// that customizes the behavior of the `RawWaker`. +/// +/// `RawWaker`s are unsafe to use. +/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation. +/// +/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table +/// [`Wake`]: ../../alloc/task/trait.Wake.html #[derive(PartialEq, Debug)] #[stable(feature = "futures_api", since = "1.36.0")] pub struct RawWaker { @@ -355,8 +359,12 @@ impl<'a> ContextBuilder<'a> { /// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker /// unnecessarily if the two wakers [wake the same task](Self::will_wake). /// +/// Constructing a `Waker` from a [`RawWaker`] is unsafe. +/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation. +/// /// [`Future::poll()`]: core::future::Future::poll /// [`Poll::Pending`]: core::task::Poll::Pending +/// [`Wake`]: ../../alloc/task/trait.Wake.html #[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401 #[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { @@ -438,9 +446,15 @@ impl Waker { /// Creates a new `Waker` from [`RawWaker`]. /// + /// # Safety + /// /// The behavior of the returned `Waker` is undefined if the contract defined /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. - /// Therefore this method is unsafe. + /// + /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the + /// cost of a required heap allocation.) + /// + /// [`Wake`]: ../../alloc/task/trait.Wake.html #[inline] #[must_use] #[stable(feature = "futures_api", since = "1.36.0")] diff --git a/library/std/build.rs b/library/std/build.rs index 35b183c47d7..ee3f3612d2e 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -7,7 +7,9 @@ fn main() { let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set"); let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set"); - + if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() { + println!("cargo:rustc-cfg=netbsd10"); + } if target_os == "linux" || target_os == "android" || target_os == "netbsd" diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 4a7f5d8e0be..669affa266a 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -171,7 +171,7 @@ pub struct Child { /// The handle for writing to the child's standard input (stdin), if it /// has been captured. You might find it helpful to do /// - /// ```compile_fail,E0425 + /// ```ignore (incomplete) /// let stdin = child.stdin.take().unwrap(); /// ``` /// @@ -183,7 +183,7 @@ pub struct Child { /// The handle for reading from the child's standard output (stdout), if it /// has been captured. You might find it helpful to do /// - /// ```compile_fail,E0425 + /// ```ignore (incomplete) /// let stdout = child.stdout.take().unwrap(); /// ``` /// @@ -195,7 +195,7 @@ pub struct Child { /// The handle for reading from the child's standard error (stderr), if it /// has been captured. You might find it helpful to do /// - /// ```compile_fail,E0425 + /// ```ignore (incomplete) /// let stderr = child.stderr.take().unwrap(); /// ``` /// diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index b8873a3b59a..6d068613f8f 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -13,7 +13,7 @@ use crate::sync::Once; /// /// # Examples /// -/// Using `OnceCell` to store a function’s previously computed value (a.k.a. +/// Using `OnceLock` to store a function’s previously computed value (a.k.a. /// ‘lazy static’ or ‘memoizing’): /// /// ``` diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs index 741312d5537..1e978bec4b4 100644 --- a/library/std/src/sync/poison.rs +++ b/library/std/src/sync/poison.rs @@ -1,9 +1,13 @@ use crate::error::Error; use crate::fmt; + +#[cfg(panic = "unwind")] use crate::sync::atomic::{AtomicBool, Ordering}; +#[cfg(panic = "unwind")] use crate::thread; pub struct Flag { + #[cfg(panic = "unwind")] failed: AtomicBool, } @@ -21,7 +25,10 @@ pub struct Flag { impl Flag { #[inline] pub const fn new() -> Flag { - Flag { failed: AtomicBool::new(false) } + Flag { + #[cfg(panic = "unwind")] + failed: AtomicBool::new(false), + } } /// Check the flag for an unguarded borrow, where we only care about existing poison. @@ -33,11 +40,15 @@ impl Flag { /// Check the flag for a guarded borrow, where we may also set poison when `done`. #[inline] pub fn guard(&self) -> LockResult<Guard> { - let ret = Guard { panicking: thread::panicking() }; + let ret = Guard { + #[cfg(panic = "unwind")] + panicking: thread::panicking(), + }; if self.get() { Err(PoisonError::new(ret)) } else { Ok(ret) } } #[inline] + #[cfg(panic = "unwind")] pub fn done(&self, guard: &Guard) { if !guard.panicking && thread::panicking() { self.failed.store(true, Ordering::Relaxed); @@ -45,17 +56,30 @@ impl Flag { } #[inline] + #[cfg(not(panic = "unwind"))] + pub fn done(&self, _guard: &Guard) {} + + #[inline] + #[cfg(panic = "unwind")] pub fn get(&self) -> bool { self.failed.load(Ordering::Relaxed) } + #[inline(always)] + #[cfg(not(panic = "unwind"))] + pub fn get(&self) -> bool { + false + } + #[inline] pub fn clear(&self) { + #[cfg(panic = "unwind")] self.failed.store(false, Ordering::Relaxed) } } pub struct Guard { + #[cfg(panic = "unwind")] panicking: bool, } @@ -95,6 +119,8 @@ pub struct Guard { #[stable(feature = "rust1", since = "1.0.0")] pub struct PoisonError<T> { guard: T, + #[cfg(not(panic = "unwind"))] + _never: !, } /// An enumeration of possible errors associated with a [`TryLockResult`] which @@ -165,11 +191,27 @@ impl<T> PoisonError<T> { /// /// This is generally created by methods like [`Mutex::lock`](crate::sync::Mutex::lock) /// or [`RwLock::read`](crate::sync::RwLock::read). + /// + /// This method may panic if std was built with `panic="abort"`. + #[cfg(panic = "unwind")] #[stable(feature = "sync_poison", since = "1.2.0")] pub fn new(guard: T) -> PoisonError<T> { PoisonError { guard } } + /// Creates a `PoisonError`. + /// + /// This is generally created by methods like [`Mutex::lock`](crate::sync::Mutex::lock) + /// or [`RwLock::read`](crate::sync::RwLock::read). + /// + /// This method may panic if std was built with `panic="abort"`. + #[cfg(not(panic = "unwind"))] + #[stable(feature = "sync_poison", since = "1.2.0")] + #[track_caller] + pub fn new(_guard: T) -> PoisonError<T> { + panic!("PoisonError created in a libstd built with panic=\"abort\"") + } + /// Consumes this error indicating that a lock is poisoned, returning the /// underlying guard to allow access regardless. /// @@ -225,6 +267,7 @@ impl<T> From<PoisonError<T>> for TryLockError<T> { impl<T> fmt::Debug for TryLockError<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { + #[cfg(panic = "unwind")] TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f), TryLockError::WouldBlock => "WouldBlock".fmt(f), } @@ -235,6 +278,7 @@ impl<T> fmt::Debug for TryLockError<T> { impl<T> fmt::Display for TryLockError<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { + #[cfg(panic = "unwind")] TryLockError::Poisoned(..) => "poisoned lock: another task failed inside", TryLockError::WouldBlock => "try_lock failed because the operation would block", } @@ -247,6 +291,7 @@ impl<T> Error for TryLockError<T> { #[allow(deprecated, deprecated_in_future)] fn description(&self) -> &str { match *self { + #[cfg(panic = "unwind")] TryLockError::Poisoned(ref p) => p.description(), TryLockError::WouldBlock => "try_lock failed because the operation would block", } @@ -255,6 +300,7 @@ impl<T> Error for TryLockError<T> { #[allow(deprecated)] fn cause(&self) -> Option<&dyn Error> { match *self { + #[cfg(panic = "unwind")] TryLockError::Poisoned(ref p) => Some(p), _ => None, } @@ -267,6 +313,7 @@ where { match result { Ok(t) => Ok(f(t)), + #[cfg(panic = "unwind")] Err(PoisonError { guard }) => Err(PoisonError::new(f(guard))), } } diff --git a/library/std/src/sys/pal/common/thread_local/fast_local.rs b/library/std/src/sys/pal/common/thread_local/fast_local.rs index 0fdca27852c..04c0dd6f750 100644 --- a/library/std/src/sys/pal/common/thread_local/fast_local.rs +++ b/library/std/src/sys/pal/common/thread_local/fast_local.rs @@ -94,7 +94,8 @@ pub macro thread_local_inner { if let $crate::option::Option::Some(init) = init { if let $crate::option::Option::Some(value) = init.take() { return value; - } else if $crate::cfg!(debug_assertions) { + } + if $crate::cfg!(debug_assertions) { $crate::unreachable!("missing default value"); } } diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs index 1dba1ccf64e..5c32957bc51 100644 --- a/library/std/src/sys/pal/unix/rand.rs +++ b/library/std/src/sys/pal/unix/rand.rs @@ -62,7 +62,7 @@ mod imp { unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) } } - #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd"))] + #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))] fn getrandom(buf: &mut [u8]) -> libc::ssize_t { unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } } @@ -72,7 +72,8 @@ mod imp { target_os = "android", target_os = "espidf", target_os = "horizon", - target_os = "freebsd" + target_os = "freebsd", + netbsd10 )))] fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { false @@ -83,7 +84,8 @@ mod imp { target_os = "android", target_os = "espidf", target_os = "horizon", - target_os = "freebsd" + target_os = "freebsd", + netbsd10 ))] fn getrandom_fill_bytes(v: &mut [u8]) -> bool { use crate::sync::atomic::{AtomicBool, Ordering}; @@ -230,7 +232,7 @@ mod imp { } // FIXME: once the 10.x release becomes the minimum, this can be dropped for simplification. -#[cfg(target_os = "netbsd")] +#[cfg(all(target_os = "netbsd", not(netbsd10)))] mod imp { use crate::ptr; diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 7e4a01a5ecd..ba8d31c23a5 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -847,11 +847,31 @@ pub mod guard { let stackptr = get_stack_start_aligned()?; let guardaddr = stackptr.addr(); // Technically the number of guard pages is tunable and controlled - // by the security.bsd.stack_guard_page sysctl, but there are - // few reasons to change it from the default. The default value has - // been 1 ever since FreeBSD 11.1 and 10.4. - const GUARD_PAGES: usize = 1; - let guard = guardaddr..guardaddr + GUARD_PAGES * page_size; + // by the security.bsd.stack_guard_page sysctl. + // By default it is 1, checking once is enough since it is + // a boot time config value. + static LOCK: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new(); + let guard = guardaddr + ..guardaddr + + *LOCK.get_or_init(|| { + use crate::sys::weak::dlsym; + dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int); + let mut guard: usize = 0; + let mut size = crate::mem::size_of_val(&guard); + let oid = crate::ffi::CStr::from_bytes_with_nul( + b"security.bsd.stack_guard_page\0", + ) + .unwrap(); + match sysctlbyname.get() { + Some(fcn) => { + if fcn(oid.as_ptr(), &mut guard as *mut _ as *mut _, &mut size as *mut _ as *mut _, crate::ptr::null_mut(), 0) == 0 { + return guard; + } + return 1; + }, + _ => { return 1; } + } + }) * page_size; Some(guard) } else if cfg!(target_os = "openbsd") { // OpenBSD stack already includes a guard page, and stack is diff --git a/library/std/src/sys/pal/windows/c/README.md b/library/std/src/sys/pal/windows/c/README.md new file mode 100644 index 00000000000..d458e55efbc --- /dev/null +++ b/library/std/src/sys/pal/windows/c/README.md @@ -0,0 +1,9 @@ +The `windows_sys.rs` file is autogenerated from `bindings.txt` and must not +be edited manually. + +To add bindings, edit `bindings.txt` then regenerate using the following command: + + ./x run generate-windows-sys && ./x fmt library/std + +If you need to override generated functions or types then add them to +`library/std/src/sys/pal/windows/c.rs`. diff --git a/library/std/src/sys/pal/windows/c/windows_sys.lst b/library/std/src/sys/pal/windows/c/bindings.txt index f91e1054a04..726f1c3df82 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.lst +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -1,7 +1,6 @@ --out windows_sys.rs --config flatten std --filter -// tidy-alphabetical-start !Windows.Win32.Foundation.INVALID_HANDLE_VALUE Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION @@ -2592,5 +2591,3 @@ Windows.Win32.System.Threading.WakeAllConditionVariable Windows.Win32.System.Threading.WakeConditionVariable Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE Windows.Win32.UI.Shell.GetUserProfileDirectoryW -// tidy-alphabetical-end - diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index b38b70c8983..c386b66a722 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -1,9 +1,3 @@ -// This file is autogenerated. -// -// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to -// regenerate the bindings. -// -// ignore-tidy-filelength // Bindings generated by `windows-bindgen` 0.52.0 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)] @@ -4351,3 +4345,4 @@ impl ::core::clone::Clone for XSAVE_FORMAT { *self } } +// ignore-tidy-filelength diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 36f9ee6aff6..0e9a9791fb2 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -86,6 +86,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[ (Some(Mode::Std), "no_global_oom_handling", None), (Some(Mode::Std), "no_rc", None), (Some(Mode::Std), "no_sync", None), + (Some(Mode::Std), "netbsd10", None), (Some(Mode::Std), "backtrace_in_libstd", None), /* Extra values not defined in the built-in targets yet, but used in std */ (Some(Mode::Std), "target_env", Some(&["libnx"])), diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock index e983edf205c..a579ea965f2 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock +++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "r-efi" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575fc2d9b3da54adbdfaddf6eca48fec256d977c8630a1750b8991347d1ac911" +checksum = "0e244f96e03a3067f9e521d3167bd42657594cb8588c8d3a2db01545dc1af2e0" [[package]] name = "uefi_qemu_test" diff --git a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md index 72157b5cd9b..f7a749744e0 100644 --- a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md +++ b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md @@ -151,3 +151,21 @@ will be given, even if the link fails to resolve. For example, any link containi characters will be ignored. [#72243]: https://github.com/rust-lang/rust/issues/72243 + +## What happens in case an intra-doc link cannot be generated + +In some cases (items behind a `cfg` for example), an intra-doc link cannot be generated to item. +There are different ways to create a link in markdown, and depending on the one you use, it will +render differently in this case: + +```md +1. [a] +2. [b][c] +3. [d](e) +4. [f] + +[f]: g +``` + +`1.` and `2.` will will be displayed as is in the rendered documentation (ie, `[a]` and `[b][c]`) +whereas `3.` and `4.` will be replaced by a link targetting `e` for `[d](e)` and `g` for `[f]`. diff --git a/src/doc/rustdoc/src/write-documentation/re-exports.md b/src/doc/rustdoc/src/write-documentation/re-exports.md index 8ce059cc29c..34688545c74 100644 --- a/src/doc/rustdoc/src/write-documentation/re-exports.md +++ b/src/doc/rustdoc/src/write-documentation/re-exports.md @@ -170,3 +170,32 @@ There are a few attributes which are not inlined though: All other attributes are inherited when inlined, so that the documentation matches the behavior if the inlined item was directly defined at the spot where it's shown. + +These rules also apply if the item is inlined with a glob re-export: + +```rust,ignore (inline) +mod private_mod { + /// First + #[cfg(a)] + pub struct InPrivate; +} + +#[cfg(c)] +pub use self::private_mod::*; +``` + +Otherwise, the attributes displayed will be from the re-exported item and the attributes on the +re-export itself will be ignored: + +```rust,ignore (inline) +mod private_mod { + /// First + #[cfg(a)] + pub struct InPrivate; +} + +#[cfg(c)] +pub use self::private_mod::InPrivate; +``` + +In the above case, `cfg(c)` will not be displayed in the docs. diff --git a/src/doc/unstable-book/book.toml b/src/doc/unstable-book/book.toml index 0cd56d09404..cef93760b33 100644 --- a/src/doc/unstable-book/book.toml +++ b/src/doc/unstable-book/book.toml @@ -4,3 +4,4 @@ author = "The Rust Community" [output.html] git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book" +edit-url-template = "https://github.com/rust-lang/rust/edit/master/src/doc/unstable-book/{path}" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 9de547ba6dc..8cc4201c3fc 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -334,7 +334,7 @@ where match br { // We only care about named late bound regions, as we need to add them // to the 'for<>' section - ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)), + ty::BrNamed(def_id, name) => Some(GenericParamDef::lifetime(def_id, name)), _ => None, } }) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 23a059c6e03..e2f2c9a5e56 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -18,8 +18,8 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ - self, clean_bound_vars, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, - clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, + self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item, + clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_bindings, clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type, }; @@ -72,7 +72,9 @@ pub(crate) fn try_inline( } Res::Def(DefKind::Fn, did) => { record_extern_fqn(cx, did, ItemType::Function); - cx.with_param_env(did, |cx| clean::FunctionItem(build_external_function(cx, did))) + cx.with_param_env(did, |cx| { + clean::enter_impl_trait(cx, |cx| clean::FunctionItem(build_function(cx, did))) + }) } Res::Def(DefKind::Struct, did) => { record_extern_fqn(cx, did, ItemType::Struct); @@ -274,18 +276,38 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } } -fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> { - let sig = cx.tcx.fn_sig(did).instantiate_identity(); - let predicates = cx.tcx.explicit_predicates_of(did); +pub(crate) fn build_function<'tcx>( + cx: &mut DocContext<'tcx>, + def_id: DefId, +) -> Box<clean::Function> { + let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + // The generics need to be cleaned before the signature. + let mut generics = + clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id)); + let bound_vars = clean_bound_vars(sig.bound_vars()); + + // At the time of writing early & late-bound params are stored separately in rustc, + // namely in `generics.params` and `bound_vars` respectively. + // + // To reestablish the original source code order of the generic parameters, we + // need to manually sort them by their definition span after concatenation. + // + // See also: + // * https://rustc-dev-guide.rust-lang.org/bound-vars-and-params.html + // * https://rustc-dev-guide.rust-lang.org/what-does-early-late-bound-mean.html + let has_early_bound_params = !generics.params.is_empty(); + let has_late_bound_params = !bound_vars.is_empty(); + generics.params.extend(bound_vars); + if has_early_bound_params && has_late_bound_params { + // If this ever becomes a performances bottleneck either due to the sorting + // or due to the query calls, consider inserting the late-bound lifetime params + // right after the last early-bound lifetime param followed by only sorting + // the slice of lifetime params. + generics.params.sort_by_key(|param| cx.tcx.def_ident_span(param.def_id).unwrap()); + } + + let decl = clean_poly_fn_sig(cx, Some(def_id), sig); - let (generics, decl) = clean::enter_impl_trait(cx, |cx| { - // NOTE: generics need to be cleaned before the decl! - let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); - // FIXME: This does not place parameters in source order (late-bound ones come last) - generics.params.extend(clean_bound_vars(sig.bound_vars())); - let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig); - (generics, decl) - }); Box::new(clean::Function { decl, generics }) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f4527d1e55e..b32d3ad562d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -254,16 +254,14 @@ fn clean_poly_trait_ref_with_bindings<'tcx>( } fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime { - let def = cx.tcx.named_bound_var(lifetime.hir_id); if let Some( - rbv::ResolvedArg::EarlyBound(node_id) - | rbv::ResolvedArg::LateBound(_, _, node_id) - | rbv::ResolvedArg::Free(_, node_id), - ) = def + rbv::ResolvedArg::EarlyBound(did) + | rbv::ResolvedArg::LateBound(_, _, did) + | rbv::ResolvedArg::Free(_, did), + ) = cx.tcx.named_bound_var(lifetime.hir_id) + && let Some(lt) = cx.args.get(&did).and_then(|arg| arg.as_lt()) { - if let Some(lt) = cx.args.get(&node_id).and_then(|p| p.as_lt()).cloned() { - return lt; - } + return lt.clone(); } Lifetime(lifetime.ident.name) } @@ -525,7 +523,6 @@ fn clean_generic_param_def<'tcx>( ( def.name, GenericParamDefKind::Type { - did: def.def_id, bounds: ThinVec::new(), // These are filled in from the where-clauses. default: default.map(Box::new), synthetic, @@ -557,7 +554,7 @@ fn clean_generic_param_def<'tcx>( ), }; - GenericParamDef { name, kind } + GenericParamDef { name, def_id: def.def_id, kind } } fn clean_generic_param<'tcx>( @@ -596,7 +593,6 @@ fn clean_generic_param<'tcx>( ( param.name.ident().name, GenericParamDefKind::Type { - did: param.def_id.to_def_id(), bounds, default: default.map(|t| clean_ty(t, cx)).map(Box::new), synthetic, @@ -614,7 +610,7 @@ fn clean_generic_param<'tcx>( ), }; - GenericParamDef { name, kind } + GenericParamDef { name, def_id: param.def_id.to_def_id(), kind } } /// Synthetic type-parameters are inserted after normal ones. @@ -646,8 +642,8 @@ pub(crate) fn clean_generics<'tcx>( let param = clean_generic_param(cx, Some(gens), param); match param.kind { GenericParamDefKind::Lifetime { .. } => unreachable!(), - GenericParamDefKind::Type { did, ref bounds, .. } => { - cx.impl_trait_bounds.insert(did.into(), bounds.to_vec()); + GenericParamDefKind::Type { ref bounds, .. } => { + cx.impl_trait_bounds.insert(param.def_id.into(), bounds.to_vec()); } GenericParamDefKind::Const { .. } => unreachable!(), } @@ -1064,8 +1060,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib match literal.kind { ast::LitKind::Int(a, _) => { let gen = func.generics.params.remove(0); - if let GenericParamDef { name, kind: GenericParamDefKind::Const { ty, .. } } = - gen + if let GenericParamDef { + name, + kind: GenericParamDefKind::Const { ty, .. }, + .. + } = gen { func.decl .inputs @@ -1169,7 +1168,7 @@ fn clean_fn_decl_with_args<'tcx>( FnDecl { inputs: args, output, c_variadic: decl.c_variadic } } -fn clean_fn_decl_from_did_and_sig<'tcx>( +fn clean_poly_fn_sig<'tcx>( cx: &mut DocContext<'tcx>, did: Option<DefId>, sig: ty::PolyFnSig<'tcx>, @@ -1359,16 +1358,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } } ty::AssocKind::Fn => { - let sig = tcx.fn_sig(assoc_item.def_id).instantiate_identity(); - let mut generics = clean_ty_generics( - cx, - tcx.generics_of(assoc_item.def_id), - tcx.explicit_predicates_of(assoc_item.def_id), - ); - // FIXME: This does not place parameters in source order (late-bound ones come last) - generics.params.extend(clean_bound_vars(sig.bound_vars())); - - let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig); + let mut item = inline::build_function(cx, assoc_item.def_id); if assoc_item.fn_has_self_parameter { let self_ty = match assoc_item.container { @@ -1377,12 +1367,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } ty::TraitContainer => tcx.types.self_param, }; - let self_arg_ty = sig.input(0).skip_binder(); + let self_arg_ty = + tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder(); if self_arg_ty == self_ty { - decl.inputs.values[0].type_ = Generic(kw::SelfUpper); + item.decl.inputs.values[0].type_ = Generic(kw::SelfUpper); } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() { if ty == self_ty { - match decl.inputs.values[0].type_ { + match item.decl.inputs.values[0].type_ { BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper), _ => unreachable!(), } @@ -1399,9 +1390,9 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( ty::ImplContainer => Some(assoc_item.defaultness(tcx)), ty::TraitContainer => None, }; - MethodItem(Box::new(Function { generics, decl }), defaultness) + MethodItem(item, defaultness) } else { - TyMethodItem(Box::new(Function { generics, decl })) + TyMethodItem(item) } } ty::AssocKind::Type => { @@ -1791,12 +1782,12 @@ fn maybe_expand_private_type_alias<'tcx>( _ => None, }); if let Some(lt) = lifetime { - let cleaned = if !lt.is_anonymous() { + let lt = if !lt.is_anonymous() { clean_lifetime(lt, cx) } else { Lifetime::elided() }; - args.insert(param.def_id.to_def_id(), InstantiationParam::Lifetime(cleaned)); + args.insert(param.def_id.to_def_id(), GenericArg::Lifetime(lt)); } indices.lifetimes += 1; } @@ -1805,44 +1796,20 @@ fn maybe_expand_private_type_alias<'tcx>( let type_ = generic_args.args.iter().find_map(|arg| match arg { hir::GenericArg::Type(ty) => { if indices.types == j { - return Some(ty); + return Some(*ty); } j += 1; None } _ => None, }); - if let Some(ty) = type_ { - args.insert( - param.def_id.to_def_id(), - InstantiationParam::Type(clean_ty(ty, cx)), - ); - } else if let Some(default) = *default { - args.insert( - param.def_id.to_def_id(), - InstantiationParam::Type(clean_ty(default, cx)), - ); + if let Some(ty) = type_.or(*default) { + args.insert(param.def_id.to_def_id(), GenericArg::Type(clean_ty(ty, cx))); } indices.types += 1; } - hir::GenericParamKind::Const { .. } => { - let mut j = 0; - let const_ = generic_args.args.iter().find_map(|arg| match arg { - hir::GenericArg::Const(ct) => { - if indices.consts == j { - return Some(ct); - } - j += 1; - None - } - _ => None, - }); - if let Some(_) = const_ { - args.insert(param.def_id.to_def_id(), InstantiationParam::Constant); - } - // FIXME(const_generics_defaults) - indices.consts += 1; - } + // FIXME(#82852): Instantiate const parameters. + hir::GenericParamKind::Const { .. } => {} } } @@ -2109,7 +2076,7 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::FnDef(..) | ty::FnPtr(_) => { // FIXME: should we merge the outer and inner binders somehow? let sig = bound_ty.skip_binder().fn_sig(cx.tcx); - let decl = clean_fn_decl_from_did_and_sig(cx, None, sig); + let decl = clean_poly_fn_sig(cx, None, sig); let generic_params = clean_bound_vars(sig.bound_vars()); BareFunction(Box::new(BareFunctionDecl { @@ -2192,10 +2159,10 @@ pub(crate) fn clean_middle_ty<'tcx>( .iter() .flat_map(|pred| pred.bound_vars()) .filter_map(|var| match var { - ty::BoundVariableKind::Region(ty::BrNamed(_, name)) + ty::BoundVariableKind::Region(ty::BrNamed(def_id, name)) if name != kw::UnderscoreLifetime => { - Some(GenericParamDef::lifetime(name)) + Some(GenericParamDef::lifetime(def_id, name)) } _ => None, }) @@ -2736,7 +2703,7 @@ fn add_without_unwanted_attributes<'hir>( if ident == sym::doc { filter_doc_attr(normal, is_inline); attrs.push((Cow::Owned(attr), import_parent)); - } else if ident != sym::cfg { + } else if is_inline || ident != sym::cfg { // If it's not a `cfg()` attribute, we keep it. attrs.push((Cow::Owned(attr), import_parent)); } @@ -3167,20 +3134,22 @@ fn clean_bound_vars<'tcx>( bound_vars .into_iter() .filter_map(|var| match var { - ty::BoundVariableKind::Region(ty::BrNamed(_, name)) + ty::BoundVariableKind::Region(ty::BrNamed(def_id, name)) if name != kw::UnderscoreLifetime => { - Some(GenericParamDef::lifetime(name)) + Some(GenericParamDef::lifetime(def_id, name)) + } + ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, name)) => { + Some(GenericParamDef { + name, + def_id, + kind: GenericParamDefKind::Type { + bounds: ThinVec::new(), + default: None, + synthetic: false, + }, + }) } - ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(did, name)) => Some(GenericParamDef { - name, - kind: GenericParamDefKind::Type { - did, - bounds: ThinVec::new(), - default: None, - synthetic: false, - }, - }), // FIXME(non_lifetime_binders): Support higher-ranked const parameters. ty::BoundVariableKind::Const => None, _ => None, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 96b4d1a45f6..85e7a915c53 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1326,7 +1326,7 @@ impl WherePredicate { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericParamDefKind { Lifetime { outlives: ThinVec<Lifetime> }, - Type { did: DefId, bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool }, + Type { bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool }, // Option<Box<String>> makes this type smaller than `Option<String>` would. Const { ty: Box<Type>, default: Option<Box<String>>, is_host_effect: bool }, } @@ -1340,12 +1340,13 @@ impl GenericParamDefKind { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) struct GenericParamDef { pub(crate) name: Symbol, + pub(crate) def_id: DefId, pub(crate) kind: GenericParamDefKind, } impl GenericParamDef { - pub(crate) fn lifetime(name: Symbol) -> Self { - Self { name, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } } + pub(crate) fn lifetime(def_id: DefId, name: Symbol) -> Self { + Self { name, def_id, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } } } pub(crate) fn is_synthetic_param(&self) -> bool { @@ -2228,6 +2229,16 @@ pub(crate) enum GenericArg { Infer, } +impl GenericArg { + pub(crate) fn as_lt(&self) -> Option<&Lifetime> { + if let Self::Lifetime(lt) = self { Some(lt) } else { None } + } + + pub(crate) fn as_ty(&self) -> Option<&Type> { + if let Self::Type(ty) = self { Some(ty) } else { None } + } +} + #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericArgs { AngleBracketed { args: Box<[GenericArg]>, bindings: ThinVec<TypeBinding> }, @@ -2530,35 +2541,6 @@ pub(crate) enum TypeBindingKind { Constraint { bounds: Vec<GenericBound> }, } -/// The type, lifetime, or constant that a private type alias's parameter should be -/// replaced with when expanding a use of that type alias. -/// -/// For example: -/// -/// ``` -/// type PrivAlias<T> = Vec<T>; -/// -/// pub fn public_fn() -> PrivAlias<i32> { vec![] } -/// ``` -/// -/// `public_fn`'s docs will show it as returning `Vec<i32>`, since `PrivAlias` is private. -/// [`InstantiationParam`] is used to record that `T` should be mapped to `i32`. -pub(crate) enum InstantiationParam { - Type(Type), - Lifetime(Lifetime), - Constant, -} - -impl InstantiationParam { - pub(crate) fn as_ty(&self) -> Option<&Type> { - if let Self::Type(ty) = self { Some(ty) } else { None } - } - - pub(crate) fn as_lt(&self) -> Option<&Lifetime> { - if let Self::Lifetime(lt) = self { Some(lt) } else { None } - } -} - // Some nodes are used a lot. Make sure they don't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 28ccda39e4d..efad5a8d808 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -44,10 +44,13 @@ pub(crate) struct DocContext<'tcx> { /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. pub(crate) active_extern_traits: DefIdSet, - // The current set of parameter instantiations, - // for expanding type aliases at the HIR level: - /// Table `DefId` of type, lifetime, or const parameter -> instantiated type, lifetime, or const - pub(crate) args: DefIdMap<clean::InstantiationParam>, + /// The current set of parameter instantiations for expanding type aliases at the HIR level. + /// + /// Maps from the `DefId` of a lifetime or type parameter to the + /// generic argument it's currently instantiated to in this context. + // FIXME(#82852): We don't record const params since we don't visit const exprs at all and + // therefore wouldn't use the corresp. generic arg anyway. Add support for them. + pub(crate) args: DefIdMap<clean::GenericArg>, pub(crate) current_type_aliases: DefIdMap<usize>, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds pub(crate) impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>, @@ -87,7 +90,7 @@ impl<'tcx> DocContext<'tcx> { /// the generic parameters for a type alias' RHS. pub(crate) fn enter_alias<F, R>( &mut self, - args: DefIdMap<clean::InstantiationParam>, + args: DefIdMap<clean::GenericArg>, def_id: DefId, f: F, ) -> R diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 32d7a80863d..cb50a27326f 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind { Lifetime { outlives } => GenericParamDefKind::Lifetime { outlives: outlives.into_iter().map(convert_lifetime).collect(), }, - Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type { + Type { bounds, default, synthetic } => GenericParamDefKind::Type { bounds: bounds.into_tcx(tcx), default: default.map(|x| (*x).into_tcx(tcx)), synthetic, @@ -486,19 +486,16 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate { outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(), } } - clean::GenericParamDefKind::Type { - did: _, - bounds, - default, - synthetic, - } => GenericParamDefKind::Type { - bounds: bounds - .into_iter() - .map(|bound| bound.into_tcx(tcx)) - .collect(), - default: default.map(|ty| (*ty).into_tcx(tcx)), - synthetic, - }, + clean::GenericParamDefKind::Type { bounds, default, synthetic } => { + GenericParamDefKind::Type { + bounds: bounds + .into_iter() + .map(|bound| bound.into_tcx(tcx)) + .collect(), + default: default.map(|ty| (*ty).into_tcx(tcx)), + synthetic, + } + } clean::GenericParamDefKind::Const { ty, default, diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs index bd07c19a2d8..247048bbc49 100644 --- a/src/tools/clippy/clippy_lints/src/copies.rs +++ b/src/tools/clippy/clippy_lints/src/copies.rs @@ -511,7 +511,8 @@ fn scan_block_for_eq<'tcx>( for stmt in &stmts[stmts.len() - init..=stmts.len() - offset] { if let StmtKind::Local(l) = stmt.kind { l.pat.each_binding_or_first(&mut |_, id, _, _| { - eq.locals.remove(&id); + // FIXME(rust/#120456) - is `swap_remove` correct? + eq.locals.swap_remove(&id); }); } } diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 064bac2e7dc..8857cb8e382 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -138,7 +138,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) { if cmt.place.projections.is_empty() { if let PlaceBase::Local(lid) = cmt.place.base { - self.set.remove(&lid); + // FIXME(rust/#120456) - is `swap_remove` correct? + self.set.swap_remove(&lid); } } } @@ -146,7 +147,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { if cmt.place.projections.is_empty() { if let PlaceBase::Local(lid) = cmt.place.base { - self.set.remove(&lid); + // FIXME(rust/#120456) - is `swap_remove` correct? + self.set.swap_remove(&lid); } } } diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 51b4f26b6d1..41e9d5b1c2e 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -106,7 +106,8 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir } if sub_pat.is_some() { removed_pat.insert(value_hir_id); - slices.remove(&value_hir_id); + // FIXME(rust/#120456) - is `swap_remove` correct? + slices.swap_remove(&value_hir_id); return; } @@ -259,7 +260,8 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { } // The slice was used for something other than indexing - self.slice_lint_info.remove(&local_id); + // FIXME(rust/#120456) - is `swap_remove` correct? + self.slice_lint_info.swap_remove(&local_id); } intravisit::walk_expr(self, expr); } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index d645e6c6c05..6595658b769 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -415,6 +415,7 @@ fn pat_contains_local(pat: &Pat<'_>, id: HirId) -> bool { /// Returns true if all the bindings in the `Pat` are in `ids` and vice versa fn bindings_eq(pat: &Pat<'_>, mut ids: HirIdSet) -> bool { let mut result = true; - pat.each_binding_or_first(&mut |_, id, _, _| result &= ids.remove(&id)); + // FIXME(rust/#120456) - is `swap_remove` correct? + pat.each_binding_or_first(&mut |_, id, _, _| result &= ids.swap_remove(&id)); result && ids.is_empty() } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 149d440ecac..710ecd745f8 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -382,7 +382,8 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> { self.add_mutably_used_var(*vid); } self.prev_bind = None; - self.prev_move_to_closure.remove(vid); + // FIXME(rust/#120456) - is `swap_remove` correct? + self.prev_move_to_closure.swap_remove(vid); } } diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index 580160efeb7..6a5555ca383 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -98,7 +98,8 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect { fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) { for hir_id in self.local_bindings.pop().unwrap() { - if let Some(span) = self.underscore_bindings.remove(&hir_id) { + // FIXME(rust/#120456) - is `swap_remove` correct? + if let Some(span) = self.underscore_bindings.swap_remove(&hir_id) { span_lint_hir( cx, NO_EFFECT_UNDERSCORE_BINDING, @@ -112,7 +113,8 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect { fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) { if let Some(def_id) = path_to_local(expr) { - self.underscore_bindings.remove(&def_id); + // FIXME(rust/#120456) - is `swap_remove` correct? + self.underscore_bindings.swap_remove(&def_id); } } } diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index ae14016f482..a568392ecc4 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -153,7 +153,8 @@ impl Params { param.uses = Vec::new(); let key = (param.fn_id, param.idx); self.by_fn.remove(&key); - self.by_id.remove(&id); + // FIXME(rust/#120456) - is `swap_remove` correct? + self.by_id.swap_remove(&id); } } diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs index dc95d969aed..c8913910bd6 100644 --- a/src/tools/generate-windows-sys/src/main.rs +++ b/src/tools/generate-windows-sys/src/main.rs @@ -1,34 +1,49 @@ use std::env; use std::error::Error; use std::fs; -use std::io::{self, Read, Seek, Write}; +use std::io::{Read, Seek, SeekFrom, Write}; use std::path::PathBuf; -/// This is printed to the file before the rest of the contents. -const PRELUDE: &str = r#"// This file is autogenerated. -// -// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to -// regenerate the bindings. -// -// ignore-tidy-filelength -"#; - fn main() -> Result<(), Box<dyn Error>> { let mut path: PathBuf = env::args_os().nth(1).expect("a path to the rust repository is required").into(); path.push("library/std/src/sys/pal/windows/c"); env::set_current_dir(&path)?; - let info = windows_bindgen::bindgen(["--etc", "windows_sys.lst"])?; + sort_bindings("bindings.txt")?; + + let info = windows_bindgen::bindgen(["--etc", "bindings.txt"])?; println!("{info}"); - // add some gunk to the output file. - let mut f = fs::File::options().read(true).write(true).open("windows_sys.rs")?; + let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?; + writeln!(&mut f, "// ignore-tidy-filelength")?; + + Ok(()) +} + +fn sort_bindings(file_name: &str) -> Result<(), Box<dyn Error>> { + let mut f = fs::File::options().read(true).write(true).open(file_name)?; let mut bindings = String::new(); f.read_to_string(&mut bindings)?; - f.seek(io::SeekFrom::Start(0))?; - f.write_all(PRELUDE.as_bytes())?; - f.write_all(bindings.as_bytes())?; + f.set_len(0)?; + f.seek(SeekFrom::Start(0))?; + let mut lines = bindings.split_inclusive('\n'); + for line in &mut lines { + f.write(line.as_bytes())?; + if line.contains("--filter") { + break; + } + } + let mut bindings = Vec::new(); + for line in &mut lines { + if !line.trim().is_empty() { + bindings.push(line); + } + } + bindings.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase())); + for line in bindings { + f.write(line.as_bytes())?; + } Ok(()) } diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index e34fb118f72..df2761bfaf4 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -108,12 +108,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "volatile_load" => { let [place] = check_arg_count(args)?; let place = this.deref_pointer(place)?; - this.copy_op(&place, dest, /*allow_transmute*/ false)?; + this.copy_op(&place, dest)?; } "volatile_store" => { let [place, dest] = check_arg_count(args)?; let place = this.deref_pointer(place)?; - this.copy_op(dest, &place, /*allow_transmute*/ false)?; + this.copy_op(dest, &place)?; } "write_bytes" | "volatile_set_memory" => { diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 1aaf820f460..b24ea8aec84 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -299,7 +299,6 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( this.copy_op( &this.project_index(&left, i)?, &this.project_index(&dest, i)?, - /*allow_transmute*/ false, )?; } @@ -424,7 +423,6 @@ fn unary_op_ss<'tcx>( this.copy_op( &this.project_index(&op, i)?, &this.project_index(&dest, i)?, - /*allow_transmute*/ false, )?; } @@ -484,7 +482,6 @@ fn round_first<'tcx, F: rustc_apfloat::Float>( this.copy_op( &this.project_index(&left, i)?, &this.project_index(&dest, i)?, - /*allow_transmute*/ false, )?; } diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 1e9afc1e9e0..9fb947cb2a3 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -211,7 +211,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.copy_op( &this.project_index(&left, i)?, &this.project_index(&dest, i)?, - /*allow_transmute*/ false, )?; } } diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 49bf7547ab0..e5c8267320a 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -443,7 +443,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.copy_op( &this.project_index(&op, i)?, &this.project_index(&dest, i)?, - /*allow_transmute*/ false, )?; } } @@ -584,7 +583,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.copy_op( &this.project_index(&left, i)?, &this.project_index(&dest, i)?, - /*allow_transmute*/ false, )?; } } diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index 67bb63f0a3d..2abd10fa7a7 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -60,7 +60,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.copy_op( &this.project_index(&left, i)?, &dest, - /*allow_transmute*/ false, )?; } } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index aaef80f4aef..4cd8e6a703e 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -537,18 +537,29 @@ impl Rewrite for ast::Lifetime { impl Rewrite for ast::GenericBound { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> { match *self { - ast::GenericBound::Trait(ref poly_trait_ref, modifiers) => { + ast::GenericBound::Trait( + ref poly_trait_ref, + ast::TraitBoundModifiers { + constness, + asyncness, + polarity, + }, + ) => { let snippet = context.snippet(self.span()); let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); - let mut constness = modifiers.constness.as_str().to_string(); + let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); } - let polarity = modifiers.polarity.as_str(); + let mut asyncness = asyncness.as_str().to_string(); + if !asyncness.is_empty() { + asyncness.push(' '); + } + let polarity = polarity.as_str(); let shape = shape.offset_left(constness.len() + polarity.len())?; poly_trait_ref .rewrite(context, shape) - .map(|s| format!("{constness}{polarity}{s}")) + .map(|s| format!("{constness}{asyncness}{polarity}{s}")) .map(|s| if has_paren { format!("({})", s) } else { s }) } ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape), diff --git a/src/tools/rustfmt/tests/target/asyncness.rs b/src/tools/rustfmt/tests/target/asyncness.rs new file mode 100644 index 00000000000..d91ac960499 --- /dev/null +++ b/src/tools/rustfmt/tests/target/asyncness.rs @@ -0,0 +1,3 @@ +// rustfmt-edition: 2018 + +fn foo() -> impl async Fn() {} diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index acb70328ba2..d4642deb2c6 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -13,8 +13,10 @@ const LICENSES: &[&str] = &[ "0BSD OR MIT OR Apache-2.0", // adler license "0BSD", "Apache-2.0 / MIT", + "Apache-2.0 OR ISC OR MIT", "Apache-2.0 OR MIT", "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license + "Apache-2.0", "Apache-2.0/MIT", "BSD-2-Clause OR Apache-2.0 OR MIT", // zerocopy "ISC", @@ -217,6 +219,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "darling_core", "darling_macro", "datafrog", + "deranged", "derivative", "derive_more", "derive_setters", @@ -258,7 +261,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "indexmap", "intl-memoizer", "intl_pluralrules", - "is-terminal", "itertools", "itoa", "jemalloc-sys", @@ -278,6 +280,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "memoffset", "miniz_oxide", "nu-ansi-term", + "num-conv", "num_cpus", "object", "odht", @@ -290,6 +293,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "pin-project-lite", "polonius-engine", "portable-atomic", // dependency for platforms doesn't support `AtomicU64` in std + "powerfmt", "ppv-lite86", "proc-macro-hack", "proc-macro2", diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 03f8a701627..1dbd221fde5 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; // #73494. const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: usize = 1794; +const ISSUES_ENTRY_LIMIT: usize = 1781; const ROOT_ENTRY_LIMIT: usize = 870; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index 9c8cf8763fd..2f7c4f7d402 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -110,7 +110,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, bb0: { _39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))); - switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb9]; + switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; } bb1: { @@ -165,10 +165,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageDead(_10); PlaceMention(_9); _16 = discriminant(_9); - switchInt(move _16) -> [0: bb10, 1: bb8, otherwise: bb9]; + switchInt(move _16) -> [0: bb10, 1: bb9, otherwise: bb8]; } bb8: { + unreachable; + } + + bb9: { _8 = const (); StorageDead(_14); StorageDead(_12); @@ -186,10 +190,6 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, return; } - bb9: { - unreachable; - } - bb10: { StorageLive(_17); _17 = ((_9 as Ready).0: ()); @@ -267,7 +267,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageDead(_26); PlaceMention(_25); _32 = discriminant(_25); - switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb9]; + switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb8]; } bb20: { diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 57f8cca9abc..028d7ee7cd8 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -27,13 +27,13 @@ fn main() -> () { StorageLive(_5); PlaceMention(_1); _6 = discriminant(_1); - switchInt(move _6) -> [1: bb4, otherwise: bb3]; + switchInt(move _6) -> [1: bb5, otherwise: bb4]; } bb1: { StorageLive(_3); StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb7; + _4 = begin_panic::<&str>(const "explicit panic") -> bb8; } bb2: { @@ -43,14 +43,19 @@ fn main() -> () { } bb3: { - goto -> bb6; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb4: { - falseEdge -> [real: bb5, imaginary: bb3]; + goto -> bb7; } bb5: { + falseEdge -> [real: bb6, imaginary: bb4]; + } + + bb6: { _5 = ((_1 as Some).0: u8); _0 = const (); StorageDead(_5); @@ -58,12 +63,12 @@ fn main() -> () { return; } - bb6: { + bb7: { StorageDead(_5); goto -> bb1; } - bb7 (cleanup): { + bb8 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir index ac50b388910..7c1f5a6ec72 100644 --- a/tests/mir-opt/building/issue_49232.main.built.after.mir +++ b/tests/mir-opt/building/issue_49232.main.built.after.mir @@ -17,7 +17,7 @@ fn main() -> () { } bb1: { - falseUnwind -> [real: bb2, unwind: bb11]; + falseUnwind -> [real: bb2, unwind: bb12]; } bb2: { @@ -25,41 +25,46 @@ fn main() -> () { StorageLive(_3); _3 = const true; PlaceMention(_3); - switchInt(_3) -> [0: bb3, otherwise: bb4]; + switchInt(_3) -> [0: bb4, otherwise: bb5]; } bb3: { - falseEdge -> [real: bb5, imaginary: bb4]; + FakeRead(ForMatchedPlace(None), _3); + unreachable; } bb4: { - _0 = const (); - goto -> bb10; + falseEdge -> [real: bb6, imaginary: bb5]; } bb5: { - _2 = const 4_i32; - goto -> bb8; + _0 = const (); + goto -> bb11; } bb6: { - unreachable; + _2 = const 4_i32; + goto -> bb9; } bb7: { - goto -> bb8; + unreachable; } bb8: { + goto -> bb9; + } + + bb9: { FakeRead(ForLet(None), _2); StorageDead(_3); StorageLive(_5); StorageLive(_6); _6 = &_2; - _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; + _5 = std::mem::drop::<&i32>(move _6) -> [return: bb10, unwind: bb12]; } - bb9: { + bb10: { StorageDead(_6); StorageDead(_5); _1 = const (); @@ -67,13 +72,13 @@ fn main() -> () { goto -> bb1; } - bb10: { + bb11: { StorageDead(_3); StorageDead(_2); return; } - bb11 (cleanup): { + bb12 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index 7407e7a8b2a..d7c758d8876 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,168 +19,178 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb31]; + _2 = E::f() -> [return: bb1, unwind: bb33]; } bb1: { PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb2, otherwise: bb3]; + switchInt(move _3) -> [0: bb4, otherwise: bb3]; } bb2: { - falseEdge -> [real: bb4, imaginary: bb3]; + FakeRead(ForMatchedPlace(None), _2); + unreachable; } bb3: { - goto -> bb19; + goto -> bb20; } bb4: { - StorageLive(_4); - _4 = always_true() -> [return: bb5, unwind: bb31]; + falseEdge -> [real: bb5, imaginary: bb3]; } bb5: { - switchInt(move _4) -> [0: bb7, otherwise: bb6]; + StorageLive(_4); + _4 = always_true() -> [return: bb6, unwind: bb33]; } bb6: { + switchInt(move _4) -> [0: bb8, otherwise: bb7]; + } + + bb7: { StorageLive(_5); StorageLive(_6); StorageLive(_7); _7 = Droppy(const 0_u8); _6 = (_7.0: u8); _5 = Gt(move _6, const 0_u8); - switchInt(move _5) -> [0: bb9, otherwise: bb8]; - } - - bb7: { - goto -> bb13; + switchInt(move _5) -> [0: bb10, otherwise: bb9]; } bb8: { - drop(_7) -> [return: bb10, unwind: bb31]; + goto -> bb14; } bb9: { - goto -> bb11; + drop(_7) -> [return: bb11, unwind: bb33]; } bb10: { - StorageDead(_7); - StorageDead(_6); - goto -> bb16; + goto -> bb12; } bb11: { - drop(_7) -> [return: bb12, unwind: bb31]; + StorageDead(_7); + StorageDead(_6); + goto -> bb17; } bb12: { + drop(_7) -> [return: bb13, unwind: bb33]; + } + + bb13: { StorageDead(_7); StorageDead(_6); - goto -> bb13; + goto -> bb14; } - bb13: { + bb14: { StorageLive(_8); StorageLive(_9); StorageLive(_10); _10 = Droppy(const 1_u8); _9 = (_10.0: u8); _8 = Gt(move _9, const 1_u8); - switchInt(move _8) -> [0: bb15, otherwise: bb14]; - } - - bb14: { - drop(_10) -> [return: bb16, unwind: bb31]; + switchInt(move _8) -> [0: bb16, otherwise: bb15]; } bb15: { - goto -> bb17; + drop(_10) -> [return: bb17, unwind: bb33]; } bb16: { + goto -> bb18; + } + + bb17: { StorageDead(_10); StorageDead(_9); _1 = const (); - goto -> bb20; + goto -> bb21; } - bb17: { - drop(_10) -> [return: bb18, unwind: bb31]; + bb18: { + drop(_10) -> [return: bb19, unwind: bb33]; } - bb18: { + bb19: { StorageDead(_10); StorageDead(_9); - goto -> bb19; + goto -> bb20; } - bb19: { + bb20: { _1 = const (); - goto -> bb20; + goto -> bb21; } - bb20: { + bb21: { StorageDead(_8); StorageDead(_5); StorageDead(_4); StorageDead(_2); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb21, unwind: bb31]; - } - - bb21: { - switchInt(move _11) -> [0: bb23, otherwise: bb22]; + _11 = always_true() -> [return: bb22, unwind: bb33]; } bb22: { - goto -> bb29; + switchInt(move _11) -> [0: bb24, otherwise: bb23]; } bb23: { - goto -> bb24; + goto -> bb31; } bb24: { - StorageLive(_12); - _12 = E::f() -> [return: bb25, unwind: bb31]; + goto -> bb25; } bb25: { - PlaceMention(_12); - _13 = discriminant(_12); - switchInt(move _13) -> [1: bb27, otherwise: bb26]; + StorageLive(_12); + _12 = E::f() -> [return: bb26, unwind: bb33]; } bb26: { - goto -> bb29; + PlaceMention(_12); + _13 = discriminant(_12); + switchInt(move _13) -> [1: bb29, otherwise: bb28]; } bb27: { - falseEdge -> [real: bb28, imaginary: bb26]; + FakeRead(ForMatchedPlace(None), _12); + unreachable; } bb28: { - _0 = const (); - goto -> bb30; + goto -> bb31; } bb29: { - _0 = const (); - goto -> bb30; + falseEdge -> [real: bb30, imaginary: bb28]; } bb30: { + _0 = const (); + goto -> bb32; + } + + bb31: { + _0 = const (); + goto -> bb32; + } + + bb32: { StorageDead(_11); StorageDead(_12); return; } - bb31 (cleanup): { + bb33 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir index b99b0b99559..88292dd0597 100644 --- a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir @@ -28,25 +28,25 @@ fn full_tested_match() -> () { _2 = Option::<i32>::Some(const 42_i32); PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - _1 = (const 3_i32, const 3_i32); - goto -> bb11; + FakeRead(ForMatchedPlace(None), _2); + unreachable; } bb2: { - falseEdge -> [real: bb5, imaginary: bb3]; + _1 = (const 3_i32, const 3_i32); + goto -> bb11; } bb3: { - falseEdge -> [real: bb10, imaginary: bb1]; + falseEdge -> [real: bb5, imaginary: bb4]; } bb4: { - FakeRead(ForMatchedPlace(None), _2); - unreachable; + falseEdge -> [real: bb10, imaginary: bb2]; } bb5: { @@ -54,7 +54,7 @@ fn full_tested_match() -> () { _6 = &((_2 as Some).0: i32); _4 = &fake _2; StorageLive(_7); - _7 = guard() -> [return: bb6, unwind: bb12]; + _7 = guard() -> [return: bb6, unwind: bb13]; } bb6: { @@ -83,7 +83,7 @@ fn full_tested_match() -> () { bb9: { StorageDead(_7); StorageDead(_6); - goto -> bb3; + goto -> bb4; } bb10: { @@ -105,7 +105,12 @@ fn full_tested_match() -> () { return; } - bb12 (cleanup): { + bb12: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb13 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir index d1d86b55d68..205bb4980d9 100644 --- a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir @@ -28,18 +28,23 @@ fn full_tested_match2() -> () { _2 = Option::<i32>::Some(const 42_i32); PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - falseEdge -> [real: bb10, imaginary: bb3]; + FakeRead(ForMatchedPlace(None), _2); + unreachable; } bb2: { - falseEdge -> [real: bb5, imaginary: bb1]; + falseEdge -> [real: bb10, imaginary: bb4]; } bb3: { + falseEdge -> [real: bb5, imaginary: bb2]; + } + + bb4: { StorageLive(_9); _9 = ((_2 as Some).0: i32); StorageLive(_10); @@ -50,17 +55,12 @@ fn full_tested_match2() -> () { goto -> bb11; } - bb4: { - FakeRead(ForMatchedPlace(None), _2); - unreachable; - } - bb5: { StorageLive(_6); _6 = &((_2 as Some).0: i32); _4 = &fake _2; StorageLive(_7); - _7 = guard() -> [return: bb6, unwind: bb12]; + _7 = guard() -> [return: bb6, unwind: bb13]; } bb6: { @@ -89,7 +89,7 @@ fn full_tested_match2() -> () { bb9: { StorageDead(_7); StorageDead(_6); - falseEdge -> [real: bb3, imaginary: bb1]; + falseEdge -> [real: bb4, imaginary: bb2]; } bb10: { @@ -105,7 +105,12 @@ fn full_tested_match2() -> () { return; } - bb12 (cleanup): { + bb12: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb13 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match_false_edges.main.built.after.mir index 1d4fe67f350..21f377a6404 100644 --- a/tests/mir-opt/building/match_false_edges.main.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.main.built.after.mir @@ -39,55 +39,60 @@ fn main() -> () { _2 = Option::<i32>::Some(const 1_i32); PlaceMention(_2); _4 = discriminant(_2); - switchInt(move _4) -> [1: bb2, otherwise: bb1]; + switchInt(move _4) -> [1: bb7, otherwise: bb2]; } bb1: { - falseEdge -> [real: bb13, imaginary: bb6]; + FakeRead(ForMatchedPlace(None), _2); + unreachable; } bb2: { - falseEdge -> [real: bb8, imaginary: bb1]; + falseEdge -> [real: bb14, imaginary: bb5]; } bb3: { - goto -> bb1; - } - - bb4: { _3 = discriminant(_2); - switchInt(move _3) -> [1: bb6, otherwise: bb5]; + switchInt(move _3) -> [1: bb5, otherwise: bb4]; } - bb5: { + bb4: { StorageLive(_14); _14 = _2; _1 = const 4_i32; StorageDead(_14); - goto -> bb19; + goto -> bb20; + } + + bb5: { + falseEdge -> [real: bb15, imaginary: bb4]; } bb6: { - falseEdge -> [real: bb14, imaginary: bb5]; + goto -> bb4; } bb7: { - goto -> bb5; + falseEdge -> [real: bb9, imaginary: bb2]; } bb8: { + goto -> bb2; + } + + bb9: { StorageLive(_7); _7 = &((_2 as Some).0: i32); _5 = &fake _2; StorageLive(_8); - _8 = guard() -> [return: bb9, unwind: bb20]; + _8 = guard() -> [return: bb10, unwind: bb22]; } - bb9: { - switchInt(move _8) -> [0: bb11, otherwise: bb10]; + bb10: { + switchInt(move _8) -> [0: bb12, otherwise: bb11]; } - bb10: { + bb11: { StorageDead(_8); FakeRead(ForMatchGuard, _5); FakeRead(ForGuardBinding, _7); @@ -96,42 +101,42 @@ fn main() -> () { _1 = const 1_i32; StorageDead(_6); StorageDead(_7); - goto -> bb19; + goto -> bb20; } - bb11: { - goto -> bb12; + bb12: { + goto -> bb13; } - bb12: { + bb13: { StorageDead(_8); StorageDead(_7); - falseEdge -> [real: bb3, imaginary: bb1]; + falseEdge -> [real: bb8, imaginary: bb2]; } - bb13: { + bb14: { StorageLive(_9); _9 = _2; _1 = const 2_i32; StorageDead(_9); - goto -> bb19; + goto -> bb20; } - bb14: { + bb15: { StorageLive(_11); _11 = &((_2 as Some).0: i32); _5 = &fake _2; StorageLive(_12); StorageLive(_13); _13 = (*_11); - _12 = guard2(move _13) -> [return: bb15, unwind: bb20]; + _12 = guard2(move _13) -> [return: bb16, unwind: bb22]; } - bb15: { - switchInt(move _12) -> [0: bb17, otherwise: bb16]; + bb16: { + switchInt(move _12) -> [0: bb18, otherwise: bb17]; } - bb16: { + bb17: { StorageDead(_13); StorageDead(_12); FakeRead(ForMatchGuard, _5); @@ -141,21 +146,21 @@ fn main() -> () { _1 = const 3_i32; StorageDead(_10); StorageDead(_11); - goto -> bb19; + goto -> bb20; } - bb17: { - goto -> bb18; + bb18: { + goto -> bb19; } - bb18: { + bb19: { StorageDead(_13); StorageDead(_12); StorageDead(_11); - falseEdge -> [real: bb7, imaginary: bb5]; + falseEdge -> [real: bb6, imaginary: bb4]; } - bb19: { + bb20: { PlaceMention(_1); StorageDead(_2); StorageDead(_1); @@ -163,7 +168,12 @@ fn main() -> () { return; } - bb20 (cleanup): { + bb21: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb22 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/simple_match.match_bool.built.after.mir index 06de4c51051..cd51c942bee 100644 --- a/tests/mir-opt/building/simple_match.match_bool.built.after.mir +++ b/tests/mir-opt/building/simple_match.match_bool.built.after.mir @@ -6,24 +6,29 @@ fn match_bool(_1: bool) -> usize { bb0: { PlaceMention(_1); - switchInt(_1) -> [0: bb2, otherwise: bb1]; + switchInt(_1) -> [0: bb2, otherwise: bb3]; } bb1: { - falseEdge -> [real: bb3, imaginary: bb2]; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb2: { _0 = const 20_usize; - goto -> bb4; + goto -> bb5; } bb3: { - _0 = const 10_usize; - goto -> bb4; + falseEdge -> [real: bb4, imaginary: bb2]; } bb4: { + _0 = const 10_usize; + goto -> bb5; + } + + bb5: { return; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir index 82424de0392..282c9704ffc 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir @@ -30,7 +30,7 @@ fn move_out_by_subslice() -> () { StorageLive(_2); _3 = SizeOf(i32); _4 = AlignOf(i32); - _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; + _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13]; } bb1: { @@ -38,7 +38,7 @@ fn move_out_by_subslice() -> () { _6 = ShallowInitBox(move _5, i32); (*_6) = const 1_i32; _2 = move _6; - drop(_6) -> [return: bb2, unwind: bb11]; + drop(_6) -> [return: bb2, unwind: bb12]; } bb2: { @@ -46,7 +46,7 @@ fn move_out_by_subslice() -> () { StorageLive(_7); _8 = SizeOf(i32); _9 = AlignOf(i32); - _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; + _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12]; } bb3: { @@ -54,18 +54,18 @@ fn move_out_by_subslice() -> () { _11 = ShallowInitBox(move _10, i32); (*_11) = const 2_i32; _7 = move _11; - drop(_11) -> [return: bb4, unwind: bb10]; + drop(_11) -> [return: bb4, unwind: bb11]; } bb4: { StorageDead(_11); _1 = [move _2, move _7]; - drop(_7) -> [return: bb5, unwind: bb11]; + drop(_7) -> [return: bb5, unwind: bb12]; } bb5: { StorageDead(_7); - drop(_2) -> [return: bb6, unwind: bb12]; + drop(_2) -> [return: bb6, unwind: bb13]; } bb6: { @@ -75,32 +75,37 @@ fn move_out_by_subslice() -> () { StorageLive(_12); _12 = move _1[0..2]; _0 = const (); - drop(_12) -> [return: bb7, unwind: bb9]; + drop(_12) -> [return: bb8, unwind: bb10]; } bb7: { - StorageDead(_12); - drop(_1) -> [return: bb8, unwind: bb12]; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb8: { - StorageDead(_1); - return; + StorageDead(_12); + drop(_1) -> [return: bb9, unwind: bb13]; } - bb9 (cleanup): { - drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + bb9: { + StorageDead(_1); + return; } bb10 (cleanup): { - drop(_7) -> [return: bb11, unwind terminate(cleanup)]; + drop(_1) -> [return: bb13, unwind terminate(cleanup)]; } bb11 (cleanup): { - drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + drop(_7) -> [return: bb12, unwind terminate(cleanup)]; } bb12 (cleanup): { + drop(_2) -> [return: bb13, unwind terminate(cleanup)]; + } + + bb13 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir index 0872d1b6ac0..d1956c91b88 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir @@ -30,7 +30,7 @@ fn move_out_from_end() -> () { StorageLive(_2); _3 = SizeOf(i32); _4 = AlignOf(i32); - _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; + _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13]; } bb1: { @@ -38,7 +38,7 @@ fn move_out_from_end() -> () { _6 = ShallowInitBox(move _5, i32); (*_6) = const 1_i32; _2 = move _6; - drop(_6) -> [return: bb2, unwind: bb11]; + drop(_6) -> [return: bb2, unwind: bb12]; } bb2: { @@ -46,7 +46,7 @@ fn move_out_from_end() -> () { StorageLive(_7); _8 = SizeOf(i32); _9 = AlignOf(i32); - _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; + _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12]; } bb3: { @@ -54,18 +54,18 @@ fn move_out_from_end() -> () { _11 = ShallowInitBox(move _10, i32); (*_11) = const 2_i32; _7 = move _11; - drop(_11) -> [return: bb4, unwind: bb10]; + drop(_11) -> [return: bb4, unwind: bb11]; } bb4: { StorageDead(_11); _1 = [move _2, move _7]; - drop(_7) -> [return: bb5, unwind: bb11]; + drop(_7) -> [return: bb5, unwind: bb12]; } bb5: { StorageDead(_7); - drop(_2) -> [return: bb6, unwind: bb12]; + drop(_2) -> [return: bb6, unwind: bb13]; } bb6: { @@ -75,32 +75,37 @@ fn move_out_from_end() -> () { StorageLive(_12); _12 = move _1[1 of 2]; _0 = const (); - drop(_12) -> [return: bb7, unwind: bb9]; + drop(_12) -> [return: bb8, unwind: bb10]; } bb7: { - StorageDead(_12); - drop(_1) -> [return: bb8, unwind: bb12]; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb8: { - StorageDead(_1); - return; + StorageDead(_12); + drop(_1) -> [return: bb9, unwind: bb13]; } - bb9 (cleanup): { - drop(_1) -> [return: bb12, unwind terminate(cleanup)]; + bb9: { + StorageDead(_1); + return; } bb10 (cleanup): { - drop(_7) -> [return: bb11, unwind terminate(cleanup)]; + drop(_1) -> [return: bb13, unwind terminate(cleanup)]; } bb11 (cleanup): { - drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + drop(_7) -> [return: bb12, unwind terminate(cleanup)]; } bb12 (cleanup): { + drop(_2) -> [return: bb13, unwind terminate(cleanup)]; + } + + bb13 (cleanup): { resume; } } diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff index a802d0256d4..51390e2abbe 100644 --- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff +++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff @@ -79,10 +79,14 @@ bb4: { StorageDead(_12); _14 = discriminant(_11); - switchInt(move _14) -> [0: bb7, 1: bb5, otherwise: bb6]; + switchInt(move _14) -> [0: bb7, 1: bb6, otherwise: bb5]; } bb5: { + unreachable; + } + + bb6: { - StorageLive(_16); _16 = ((_11 as Some).0: usize); StorageLive(_17); @@ -95,10 +99,6 @@ + assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> [success: bb8, unwind unreachable]; } - bb6: { - unreachable; - } - bb7: { _0 = const (); StorageDead(_13); diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff index 35f852098c3..8a2cbb68824 100644 --- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff +++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff @@ -79,10 +79,14 @@ bb4: { StorageDead(_12); _14 = discriminant(_11); - switchInt(move _14) -> [0: bb7, 1: bb5, otherwise: bb6]; + switchInt(move _14) -> [0: bb7, 1: bb6, otherwise: bb5]; } bb5: { + unreachable; + } + + bb6: { - StorageLive(_16); _16 = ((_11 as Some).0: usize); StorageLive(_17); @@ -95,10 +99,6 @@ + assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> [success: bb8, unwind continue]; } - bb6: { - unreachable; - } - bb7: { _0 = const (); StorageDead(_13); diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff index f50a763ef9a..fc814f7e7a9 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff @@ -26,12 +26,16 @@ _1 = const _; StorageLive(_2); - _3 = discriminant(_1); -- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; +- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; + _3 = const 0_isize; -+ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = ((_1 as V2).0: i32); _2 = _5; @@ -39,10 +43,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_4); - _4 = ((_1 as V1).0: i32); diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff index f50a763ef9a..fc814f7e7a9 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff @@ -26,12 +26,16 @@ _1 = const _; StorageLive(_2); - _3 = discriminant(_1); -- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; +- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; + _3 = const 0_isize; -+ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = ((_1 as V2).0: i32); _2 = _5; @@ -39,10 +43,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_4); - _4 = ((_1 as V1).0: i32); diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff index 6bf702b8568..10d33767c90 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff @@ -49,16 +49,16 @@ StorageDead(_4); StorageLive(_6); _7 = discriminant(_3); - switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb5]; + switchInt(move _7) -> [0: bb5, 1: bb6, otherwise: bb4]; } bb4: { - _6 = const 0_u8; - goto -> bb7; + unreachable; } bb5: { - unreachable; + _6 = const 0_u8; + goto -> bb7; } bb6: { diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff index 6bf702b8568..10d33767c90 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff @@ -49,16 +49,16 @@ StorageDead(_4); StorageLive(_6); _7 = discriminant(_3); - switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb5]; + switchInt(move _7) -> [0: bb5, 1: bb6, otherwise: bb4]; } bb4: { - _6 = const 0_u8; - goto -> bb7; + unreachable; } bb5: { - unreachable; + _6 = const 0_u8; + goto -> bb7; } bb6: { diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 7ad64d05be4..78410e49d2a 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -20,7 +20,7 @@ fn simple() { // CHECK: [[e]] = const E::V1(0_i32); let e = E::V1(0); - // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb2, otherwise: bb1]; // CHECK: [[target_bb]]: { // CHECK: [[x]] = const 0_i32; let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; @@ -36,7 +36,7 @@ fn constant() { // CHECK: [[e]] = const _; let e = C; - // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb2, otherwise: bb1]; // CHECK: [[target_bb]]: { // CHECK: [[x]] = const 0_i32; let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; @@ -55,7 +55,7 @@ fn statics() { // CHECK: [[e1]] = const E::V1(0_i32); let e1 = C; - // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb2, otherwise: bb1]; // CHECK: [[target_bb]]: { // CHECK: [[x1]] = const 0_i32; let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 }; diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff index b31f98460e4..89ed26f065b 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff @@ -27,12 +27,16 @@ + _1 = const E::V1(0_i32); StorageLive(_2); - _3 = discriminant(_1); -- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; +- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; + _3 = const 0_isize; -+ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = ((_1 as V2).0: i32); _2 = _5; @@ -40,10 +44,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_4); - _4 = ((_1 as V1).0: i32); diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff index b31f98460e4..89ed26f065b 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff @@ -27,12 +27,16 @@ + _1 = const E::V1(0_i32); StorageLive(_2); - _3 = discriminant(_1); -- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; +- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; + _3 = const 0_isize; -+ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = ((_1 as V2).0: i32); _2 = _5; @@ -40,10 +44,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_4); - _4 = ((_1 as V1).0: i32); diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff index 44e8d39cca3..fe8ed011489 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff @@ -49,12 +49,16 @@ StorageDead(_2); StorageLive(_3); - _4 = discriminant(_1); -- switchInt(move _4) -> [0: bb3, 1: bb1, otherwise: bb2]; +- switchInt(move _4) -> [0: bb3, 1: bb2, otherwise: bb1]; + _4 = const 0_isize; -+ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_6); _6 = ((_1 as V2).0: i32); _3 = _6; @@ -62,10 +66,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_5); - _5 = ((_1 as V1).0: i32); @@ -84,7 +84,7 @@ StorageDead(_8); StorageLive(_9); _10 = discriminant((*_7)); - switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb2]; + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff index ac4ca086d0f..df3a989d09e 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff @@ -49,12 +49,16 @@ StorageDead(_2); StorageLive(_3); - _4 = discriminant(_1); -- switchInt(move _4) -> [0: bb3, 1: bb1, otherwise: bb2]; +- switchInt(move _4) -> [0: bb3, 1: bb2, otherwise: bb1]; + _4 = const 0_isize; -+ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_6); _6 = ((_1 as V2).0: i32); _3 = _6; @@ -62,10 +66,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_5); - _5 = ((_1 as V1).0: i32); @@ -84,7 +84,7 @@ StorageDead(_8); StorageLive(_9); _10 = discriminant((*_7)); - switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb2]; + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff index 5c4fc06a2ba..938b9bb14ad 100644 --- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff +++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff @@ -25,58 +25,66 @@ _7 = Len((*_2)); _8 = const 4_usize; _9 = Ge(move _7, move _8); - switchInt(move _9) -> [0: bb6, otherwise: bb2]; +- switchInt(move _9) -> [0: bb2, otherwise: bb7]; ++ switchInt(move _9) -> [0: bb2, otherwise: bb6]; } bb2: { - switchInt((*_2)[0 of 4]) -> [47: bb3, otherwise: bb6]; + _4 = Len((*_2)); + _5 = const 3_usize; + _6 = Ge(move _4, move _5); +- switchInt(move _6) -> [0: bb3, otherwise: bb4]; ++ switchInt(move _6) -> [0: bb10, otherwise: bb3]; } bb3: { - switchInt((*_2)[1 of 4]) -> [47: bb4, otherwise: bb6]; +- _0 = const false; +- goto -> bb14; ++ switchInt((*_2)[0 of 3]) -> [47: bb4, otherwise: bb10]; } bb4: { - switchInt((*_2)[2 of 4]) -> [47: bb5, otherwise: bb6]; +- switchInt((*_2)[0 of 3]) -> [47: bb5, otherwise: bb3]; ++ switchInt((*_2)[1 of 3]) -> [47: bb5, otherwise: bb10]; } bb5: { -- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb6]; -+ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb6]; +- switchInt((*_2)[1 of 3]) -> [47: bb6, otherwise: bb3]; ++ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; } bb6: { - _4 = Len((*_2)); - _5 = const 3_usize; - _6 = Ge(move _4, move _5); - switchInt(move _6) -> [0: bb10, otherwise: bb7]; +- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb3]; ++ switchInt((*_2)[0 of 4]) -> [47: bb7, otherwise: bb2]; } bb7: { - switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10]; +- switchInt((*_2)[0 of 4]) -> [47: bb8, otherwise: bb2]; ++ switchInt((*_2)[1 of 4]) -> [47: bb8, otherwise: bb2]; } bb8: { - switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10]; +- switchInt((*_2)[1 of 4]) -> [47: bb9, otherwise: bb2]; ++ switchInt((*_2)[2 of 4]) -> [47: bb9, otherwise: bb2]; } bb9: { -- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb10]; -+ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; +- switchInt((*_2)[2 of 4]) -> [47: bb10, otherwise: bb2]; ++ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb2]; } bb10: { +- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb2]; +- } +- +- bb11: { _0 = const false; - goto -> bb14; + goto -> bb12; } - bb11: { -- _0 = const false; -- goto -> bb14; -- } -- - bb12: { ++ bb11: { _0 = const true; - goto -> bb14; + goto -> bb12; diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff index 3d9aa829052..ce89694076b 100644 --- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff +++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff @@ -25,58 +25,66 @@ _7 = Len((*_2)); _8 = const 4_usize; _9 = Ge(move _7, move _8); - switchInt(move _9) -> [0: bb6, otherwise: bb2]; +- switchInt(move _9) -> [0: bb2, otherwise: bb7]; ++ switchInt(move _9) -> [0: bb2, otherwise: bb6]; } bb2: { - switchInt((*_2)[0 of 4]) -> [47: bb3, otherwise: bb6]; + _4 = Len((*_2)); + _5 = const 3_usize; + _6 = Ge(move _4, move _5); +- switchInt(move _6) -> [0: bb3, otherwise: bb4]; ++ switchInt(move _6) -> [0: bb10, otherwise: bb3]; } bb3: { - switchInt((*_2)[1 of 4]) -> [47: bb4, otherwise: bb6]; +- _0 = const false; +- goto -> bb14; ++ switchInt((*_2)[0 of 3]) -> [47: bb4, otherwise: bb10]; } bb4: { - switchInt((*_2)[2 of 4]) -> [47: bb5, otherwise: bb6]; +- switchInt((*_2)[0 of 3]) -> [47: bb5, otherwise: bb3]; ++ switchInt((*_2)[1 of 3]) -> [47: bb5, otherwise: bb10]; } bb5: { -- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb6]; -+ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb6]; +- switchInt((*_2)[1 of 3]) -> [47: bb6, otherwise: bb3]; ++ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; } bb6: { - _4 = Len((*_2)); - _5 = const 3_usize; - _6 = Ge(move _4, move _5); - switchInt(move _6) -> [0: bb10, otherwise: bb7]; +- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb3]; ++ switchInt((*_2)[0 of 4]) -> [47: bb7, otherwise: bb2]; } bb7: { - switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10]; +- switchInt((*_2)[0 of 4]) -> [47: bb8, otherwise: bb2]; ++ switchInt((*_2)[1 of 4]) -> [47: bb8, otherwise: bb2]; } bb8: { - switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10]; +- switchInt((*_2)[1 of 4]) -> [47: bb9, otherwise: bb2]; ++ switchInt((*_2)[2 of 4]) -> [47: bb9, otherwise: bb2]; } bb9: { -- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb10]; -+ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; +- switchInt((*_2)[2 of 4]) -> [47: bb10, otherwise: bb2]; ++ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb2]; } bb10: { +- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb2]; +- } +- +- bb11: { _0 = const false; - goto -> bb14; + goto -> bb12; } - bb11: { -- _0 = const false; -- goto -> bb14; -- } -- - bb12: { ++ bb11: { _0 = const true; - goto -> bb14; + goto -> bb12; diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff index 0fad716a2cb..6654e710625 100644 --- a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff +++ b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff @@ -55,10 +55,14 @@ StorageDead(_8); PlaceMention(_7); _10 = discriminant(_7); - switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb4]; } bb4: { + unreachable; + } + + bb5: { StorageLive(_12); - _12 = (*((_7 as Some).0: &i32)); + _15 = deref_copy ((_7 as Some).0: &i32); @@ -68,10 +72,6 @@ _6 = std::mem::drop::<i32>(move _13) -> [return: bb7, unwind: bb8]; } - bb5: { - unreachable; - } - bb6: { _0 = const (); StorageDead(_9); diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff index ae5656f02a5..18fc27e7cf7 100644 --- a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff +++ b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff @@ -55,10 +55,14 @@ StorageDead(_8); PlaceMention(_7); _10 = discriminant(_7); - switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb4]; } bb4: { + unreachable; + } + + bb5: { StorageLive(_12); - _12 = (*((_7 as Some).0: &i32)); + _15 = deref_copy ((_7 as Some).0: &i32); @@ -68,10 +72,6 @@ _6 = std::mem::drop::<i32>(move _13) -> [return: bb7, unwind continue]; } - bb5: { - unreachable; - } - bb6: { _0 = const (); StorageDead(_9); diff --git a/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff index b91a469225c..32a8dd8b8b4 100644 --- a/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff @@ -30,7 +30,7 @@ StorageDead(_5); StorageDead(_4); _8 = discriminant((_3.0: std::option::Option<u32>)); -- switchInt(move _8) -> [0: bb1, 1: bb3, otherwise: bb2]; +- switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1]; + StorageLive(_11); + _11 = discriminant((_3.1: std::option::Option<u32>)); + StorageLive(_12); @@ -40,24 +40,23 @@ } bb1: { -- _6 = discriminant((_3.1: std::option::Option<u32>)); -- switchInt(move _6) -> [0: bb5, otherwise: bb2]; -- } -- -- bb2: { + StorageDead(_12); _0 = const 1_u32; - goto -> bb6; + goto -> bb4; } + bb2: { +- _6 = discriminant((_3.1: std::option::Option<u32>)); +- switchInt(move _6) -> [0: bb5, otherwise: bb1]; +- } +- - bb3: { - _7 = discriminant((_3.1: std::option::Option<u32>)); -- switchInt(move _7) -> [1: bb4, otherwise: bb2]; +- switchInt(move _7) -> [1: bb4, otherwise: bb1]; - } - - bb4: { -+ bb2: { StorageLive(_10); _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); StorageLive(_9); diff --git a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index 79cf1c0e34a..6179bab11fe 100644 --- a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -78,16 +78,10 @@ StorageDead(_5); _34 = deref_copy (_4.0: &ViewportPercentageLength); _11 = discriminant((*_34)); - switchInt(move _11) -> [0: bb1, 1: bb3, 2: bb4, 3: bb5, otherwise: bb2]; + switchInt(move _11) -> [0: bb2, 1: bb3, 2: bb4, 3: bb5, otherwise: bb1]; } bb1: { - _35 = deref_copy (_4.1: &ViewportPercentageLength); - _7 = discriminant((*_35)); - switchInt(move _7) -> [0: bb6, otherwise: bb2]; - } - - bb2: { StorageLive(_33); _33 = (); _0 = Result::<ViewportPercentageLength, ()>::Err(move _33); @@ -97,22 +91,28 @@ goto -> bb11; } + bb2: { + _35 = deref_copy (_4.1: &ViewportPercentageLength); + _7 = discriminant((*_35)); + switchInt(move _7) -> [0: bb6, otherwise: bb1]; + } + bb3: { _36 = deref_copy (_4.1: &ViewportPercentageLength); _8 = discriminant((*_36)); - switchInt(move _8) -> [1: bb7, otherwise: bb2]; + switchInt(move _8) -> [1: bb7, otherwise: bb1]; } bb4: { _37 = deref_copy (_4.1: &ViewportPercentageLength); _9 = discriminant((*_37)); - switchInt(move _9) -> [2: bb8, otherwise: bb2]; + switchInt(move _9) -> [2: bb8, otherwise: bb1]; } bb5: { _38 = deref_copy (_4.1: &ViewportPercentageLength); _10 = discriminant((*_38)); - switchInt(move _10) -> [3: bb9, otherwise: bb2]; + switchInt(move _10) -> [3: bb9, otherwise: bb1]; } bb6: { diff --git a/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff index af0337d0a7e..d7908ab3cd2 100644 --- a/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff @@ -36,26 +36,26 @@ StorageDead(_5); StorageDead(_4); _8 = discriminant((_3.0: std::option::Option<u32>)); - switchInt(move _8) -> [0: bb1, 1: bb4, otherwise: bb3]; + switchInt(move _8) -> [0: bb2, 1: bb4, otherwise: bb1]; } bb1: { - _6 = discriminant((_3.1: std::option::Option<u32>)); - switchInt(move _6) -> [0: bb2, 1: bb7, otherwise: bb3]; + unreachable; } bb2: { - _0 = const 3_u32; - goto -> bb8; + _6 = discriminant((_3.1: std::option::Option<u32>)); + switchInt(move _6) -> [0: bb3, 1: bb7, otherwise: bb1]; } bb3: { - unreachable; + _0 = const 3_u32; + goto -> bb8; } bb4: { _7 = discriminant((_3.1: std::option::Option<u32>)); - switchInt(move _7) -> [0: bb6, 1: bb5, otherwise: bb3]; + switchInt(move _7) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { diff --git a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff index 62710ba8fbf..a5c29c191ad 100644 --- a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff @@ -21,18 +21,18 @@ + _2 = Option::<T>::Some(_1); StorageDead(_3); - _4 = discriminant(_2); -- switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2]; +- switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb1]; + _4 = const 1_isize; -+ switchInt(const 1_isize) -> [0: bb1, 1: bb3, otherwise: bb2]; ++ switchInt(const 1_isize) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - StorageLive(_6); - _6 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; + unreachable; } bb2: { - unreachable; + StorageLive(_6); + _6 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } bb3: { diff --git a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff index ad46a065b1e..6f2e5248271 100644 --- a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff @@ -21,18 +21,18 @@ + _2 = Option::<T>::Some(_1); StorageDead(_3); - _4 = discriminant(_2); -- switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2]; +- switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb1]; + _4 = const 1_isize; -+ switchInt(const 1_isize) -> [0: bb1, 1: bb3, otherwise: bb2]; ++ switchInt(const 1_isize) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - StorageLive(_6); - _6 = begin_panic::<&str>(const "explicit panic") -> unwind continue; + unreachable; } bb2: { - unreachable; + StorageLive(_6); + _6 = begin_panic::<&str>(const "explicit panic") -> unwind continue; } bb3: { diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff index 9358a64b4fa..52688c2e867 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff @@ -28,18 +28,18 @@ + StorageLive(_3); + StorageLive(_5); + _3 = discriminant(_2); -+ switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2]; ++ switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { -+ StorageLive(_4); -+ _4 = cfg!(debug_assertions); -+ assume(_4); -+ _5 = unreachable_unchecked::precondition_check() -> [return: bb2, unwind unreachable]; ++ unreachable; + } + + bb2: { -+ unreachable; ++ StorageLive(_4); ++ _4 = cfg!(debug_assertions); ++ assume(_4); ++ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff index ac33c126155..fd83f1cb331 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff @@ -28,22 +28,22 @@ + StorageLive(_3); + StorageLive(_5); + _3 = discriminant(_2); -+ switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2]; ++ switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - StorageDead(_2); - return; -+ StorageLive(_4); -+ _4 = cfg!(debug_assertions); -+ assume(_4); -+ _5 = unreachable_unchecked::precondition_check() -> [return: bb2, unwind unreachable]; ++ unreachable; } - bb2 (cleanup): { - resume; + bb2: { -+ unreachable; ++ StorageLive(_4); ++ _4 = cfg!(debug_assertions); ++ assume(_4); ++ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { diff --git a/tests/mir-opt/issue_120925_unsafefncast.rs b/tests/mir-opt/issue_120925_unsafefncast.rs new file mode 100644 index 00000000000..f80ae66efda --- /dev/null +++ b/tests/mir-opt/issue_120925_unsafefncast.rs @@ -0,0 +1,25 @@ +// Verify that we do not ICE when attempting to interpret casts between fn types. +// skip-filecheck + +static FOO: fn() = || assert_ne!(42, 43); +static BAR: fn(i32, i32) = |a, b| assert_ne!(a, b); + +fn main() { + FOO(); + + let bar: unsafe fn(i32, i32) = BAR; + + let f: fn() = || {}; + f(); + + f(); + + f(); + + let g: fn(i32) = |i| assert_eq!(i, 2); + g(2); + + g(2); + + g(2); +} diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir index fadfdfc87be..91dee82fde0 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir @@ -47,10 +47,14 @@ fn test() -> Option<Box<u32>> { StorageDead(_7); PlaceMention(_6); _8 = discriminant(_6); - switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb4]; + switchInt(move _8) -> [0: bb4, 1: bb5, otherwise: bb3]; } bb3: { + unreachable; + } + + bb4: { StorageLive(_12); _12 = ((_6 as Continue).0: u32); (*_5) = _12; @@ -59,10 +63,6 @@ fn test() -> Option<Box<u32>> { drop(_5) -> [return: bb7, unwind: bb11]; } - bb4: { - unreachable; - } - bb5: { StorageLive(_9); _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir index 8f94165a108..ff7fc74ff61 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir @@ -47,10 +47,14 @@ fn test() -> Option<Box<u32>> { StorageDead(_7); PlaceMention(_6); _8 = discriminant(_6); - switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb4]; + switchInt(move _8) -> [0: bb4, 1: bb5, otherwise: bb3]; } bb3: { + unreachable; + } + + bb4: { StorageLive(_12); _12 = ((_6 as Continue).0: u32); (*_5) = _12; @@ -59,10 +63,6 @@ fn test() -> Option<Box<u32>> { drop(_5) -> [return: bb7, unwind: bb11]; } - bb4: { - unreachable; - } - bb5: { StorageLive(_9); _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); diff --git a/tests/mir-opt/issue_72181.bar.built.after.mir b/tests/mir-opt/issue_72181.bar.built.after.mir index c2e4e2072de..b6cc7d22195 100644 --- a/tests/mir-opt/issue_72181.bar.built.after.mir +++ b/tests/mir-opt/issue_72181.bar.built.after.mir @@ -14,4 +14,9 @@ fn bar(_1: [(Never, u32); 1]) -> u32 { StorageDead(_2); return; } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } } diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir index 4e4071536b1..12c4a2b6325 100644 --- a/tests/mir-opt/issue_72181.main.built.after.mir +++ b/tests/mir-opt/issue_72181.main.built.after.mir @@ -22,7 +22,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; + _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb5]; } bb1: { @@ -42,10 +42,15 @@ fn main() -> () { _6 = const 0_usize; _7 = Len(_2); _8 = Lt(_6, _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; + assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb5]; } bb2: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb3: { _5 = (_2[_6].0: u64); PlaceMention(_5); StorageDead(_6); @@ -55,7 +60,12 @@ fn main() -> () { return; } - bb3 (cleanup): { + bb4: { + FakeRead(ForMatchedPlace(None), _5); + unreachable; + } + + bb5 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_72181_1.f.built.after.mir b/tests/mir-opt/issue_72181_1.f.built.after.mir index 89da9a80113..674a4013fe7 100644 --- a/tests/mir-opt/issue_72181_1.f.built.after.mir +++ b/tests/mir-opt/issue_72181_1.f.built.after.mir @@ -6,11 +6,15 @@ fn f(_1: Void) -> ! { bb0: { PlaceMention(_1); + goto -> bb1; + } + + bb1: { FakeRead(ForMatchedPlace(None), _1); unreachable; } - bb1: { + bb2: { return; } } diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir index cce1a1fd2ef..53829588a1b 100644 --- a/tests/mir-opt/issue_91633.bar.built.after.mir +++ b/tests/mir-opt/issue_91633.bar.built.after.mir @@ -12,7 +12,7 @@ fn bar(_1: Box<[T]>) -> () { StorageLive(_2); StorageLive(_3); _3 = &(*_1); - _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; + _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb4]; } bb1: { @@ -20,18 +20,23 @@ fn bar(_1: Box<[T]>) -> () { PlaceMention((*_2)); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb2, unwind: bb4]; + drop(_1) -> [return: bb3, unwind: bb5]; } bb2: { - return; + FakeRead(ForMatchedPlace(None), (*_2)); + unreachable; } - bb3 (cleanup): { - drop(_1) -> [return: bb4, unwind terminate(cleanup)]; + bb3: { + return; } bb4 (cleanup): { + drop(_1) -> [return: bb5, unwind terminate(cleanup)]; + } + + bb5 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir index aa8f31f8156..a537e509996 100644 --- a/tests/mir-opt/issue_91633.hey.built.after.mir +++ b/tests/mir-opt/issue_91633.hey.built.after.mir @@ -14,7 +14,7 @@ fn hey(_1: &[T]) -> () { StorageLive(_3); StorageLive(_4); _4 = &(*_1); - _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; + _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb3]; } bb1: { @@ -27,7 +27,12 @@ fn hey(_1: &[T]) -> () { return; } - bb2 (cleanup): { + bb2: { + FakeRead(ForMatchedPlace(None), _2); + unreachable; + } + + bb3 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index a10061ed941..53254f76dbc 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -67,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb21]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23]; } bb1: { @@ -91,24 +91,29 @@ fn main() -> () { _11 = &(*_8); StorageLive(_12); _12 = &(*_9); - _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb2, unwind: bb21]; + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23]; } bb2: { - switchInt(move _10) -> [0: bb4, otherwise: bb3]; + FakeRead(ForMatchedPlace(None), _2); + unreachable; } bb3: { - StorageDead(_12); - StorageDead(_11); - goto -> bb8; + switchInt(move _10) -> [0: bb5, otherwise: bb4]; } bb4: { - goto -> bb5; + StorageDead(_12); + StorageDead(_11); + goto -> bb9; } bb5: { + goto -> bb6; + } + + bb6: { StorageDead(_12); StorageDead(_11); StorageLive(_14); @@ -127,10 +132,10 @@ fn main() -> () { _19 = &(*_20); StorageLive(_21); _21 = Option::<Arguments<'_>>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb21; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb23; } - bb6: { + bb7: { StorageDead(_21); StorageDead(_19); StorageDead(_17); @@ -142,23 +147,23 @@ fn main() -> () { unreachable; } - bb7: { - goto -> bb9; + bb8: { + goto -> bb10; } - bb8: { + bb9: { _1 = const (); - goto -> bb9; + goto -> bb10; } - bb9: { + bb10: { StorageDead(_10); StorageDead(_9); StorageDead(_8); - goto -> bb10; + goto -> bb11; } - bb10: { + bb11: { StorageDead(_7); StorageDead(_6); StorageDead(_4); @@ -168,10 +173,10 @@ fn main() -> () { StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb11, unwind: bb21]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; } - bb11: { + bb12: { _24 = &_25; StorageLive(_26); StorageLive(_27); @@ -190,24 +195,29 @@ fn main() -> () { _31 = &(*_28); StorageLive(_32); _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb12, unwind: bb21]; + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; } - bb12: { - switchInt(move _30) -> [0: bb14, otherwise: bb13]; + bb13: { + FakeRead(ForMatchedPlace(None), _23); + unreachable; } - bb13: { + bb14: { + switchInt(move _30) -> [0: bb16, otherwise: bb15]; + } + + bb15: { StorageDead(_32); StorageDead(_31); - goto -> bb18; + goto -> bb20; } - bb14: { - goto -> bb15; + bb16: { + goto -> bb17; } - bb15: { + bb17: { StorageDead(_32); StorageDead(_31); StorageLive(_34); @@ -226,10 +236,10 @@ fn main() -> () { _39 = &(*_40); StorageLive(_41); _41 = Option::<Arguments<'_>>::None; - _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb21; + _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb23; } - bb16: { + bb18: { StorageDead(_41); StorageDead(_39); StorageDead(_37); @@ -241,23 +251,23 @@ fn main() -> () { unreachable; } - bb17: { - goto -> bb19; + bb19: { + goto -> bb21; } - bb18: { + bb20: { _22 = const (); - goto -> bb19; + goto -> bb21; } - bb19: { + bb21: { StorageDead(_30); StorageDead(_29); StorageDead(_28); - goto -> bb20; + goto -> bb22; } - bb20: { + bb22: { StorageDead(_27); StorageDead(_25); StorageDead(_23); @@ -266,7 +276,7 @@ fn main() -> () { return; } - bb21 (cleanup): { + bb23 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index a10061ed941..53254f76dbc 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -67,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb21]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23]; } bb1: { @@ -91,24 +91,29 @@ fn main() -> () { _11 = &(*_8); StorageLive(_12); _12 = &(*_9); - _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb2, unwind: bb21]; + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23]; } bb2: { - switchInt(move _10) -> [0: bb4, otherwise: bb3]; + FakeRead(ForMatchedPlace(None), _2); + unreachable; } bb3: { - StorageDead(_12); - StorageDead(_11); - goto -> bb8; + switchInt(move _10) -> [0: bb5, otherwise: bb4]; } bb4: { - goto -> bb5; + StorageDead(_12); + StorageDead(_11); + goto -> bb9; } bb5: { + goto -> bb6; + } + + bb6: { StorageDead(_12); StorageDead(_11); StorageLive(_14); @@ -127,10 +132,10 @@ fn main() -> () { _19 = &(*_20); StorageLive(_21); _21 = Option::<Arguments<'_>>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb21; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb23; } - bb6: { + bb7: { StorageDead(_21); StorageDead(_19); StorageDead(_17); @@ -142,23 +147,23 @@ fn main() -> () { unreachable; } - bb7: { - goto -> bb9; + bb8: { + goto -> bb10; } - bb8: { + bb9: { _1 = const (); - goto -> bb9; + goto -> bb10; } - bb9: { + bb10: { StorageDead(_10); StorageDead(_9); StorageDead(_8); - goto -> bb10; + goto -> bb11; } - bb10: { + bb11: { StorageDead(_7); StorageDead(_6); StorageDead(_4); @@ -168,10 +173,10 @@ fn main() -> () { StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb11, unwind: bb21]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; } - bb11: { + bb12: { _24 = &_25; StorageLive(_26); StorageLive(_27); @@ -190,24 +195,29 @@ fn main() -> () { _31 = &(*_28); StorageLive(_32); _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb12, unwind: bb21]; + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; } - bb12: { - switchInt(move _30) -> [0: bb14, otherwise: bb13]; + bb13: { + FakeRead(ForMatchedPlace(None), _23); + unreachable; } - bb13: { + bb14: { + switchInt(move _30) -> [0: bb16, otherwise: bb15]; + } + + bb15: { StorageDead(_32); StorageDead(_31); - goto -> bb18; + goto -> bb20; } - bb14: { - goto -> bb15; + bb16: { + goto -> bb17; } - bb15: { + bb17: { StorageDead(_32); StorageDead(_31); StorageLive(_34); @@ -226,10 +236,10 @@ fn main() -> () { _39 = &(*_40); StorageLive(_41); _41 = Option::<Arguments<'_>>::None; - _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb21; + _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb23; } - bb16: { + bb18: { StorageDead(_41); StorageDead(_39); StorageDead(_37); @@ -241,23 +251,23 @@ fn main() -> () { unreachable; } - bb17: { - goto -> bb19; + bb19: { + goto -> bb21; } - bb18: { + bb20: { _22 = const (); - goto -> bb19; + goto -> bb21; } - bb19: { + bb21: { StorageDead(_30); StorageDead(_29); StorageDead(_28); - goto -> bb20; + goto -> bb22; } - bb20: { + bb22: { StorageDead(_27); StorageDead(_25); StorageDead(_23); @@ -266,7 +276,7 @@ fn main() -> () { return; } - bb21 (cleanup): { + bb23 (cleanup): { resume; } } diff --git a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff index ad5846c97de..bbbfe90691f 100644 --- a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff @@ -24,20 +24,20 @@ bb1: { _4 = discriminant(_1); - switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3]; + switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb3, otherwise: bb2]; } bb2: { + unreachable; + } + + bb3: { _0 = const (); StorageDead(_2); StorageDead(_1); return; } - bb3: { - unreachable; - } - bb4: { StorageLive(_5); _5 = DFA::B; diff --git a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff index ad5846c97de..bbbfe90691f 100644 --- a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff @@ -24,20 +24,20 @@ bb1: { _4 = discriminant(_1); - switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3]; + switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb3, otherwise: bb2]; } bb2: { + unreachable; + } + + bb3: { _0 = const (); StorageDead(_2); StorageDead(_1); return; } - bb3: { - unreachable; - } - bb4: { StorageLive(_5); _5 = DFA::B; diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff index 9cc4385f60b..d67477ab1b9 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff @@ -56,10 +56,14 @@ StorageLive(_11); StorageLive(_12); _10 = discriminant(_4); - switchInt(move _10) -> [0: bb7, 1: bb6, otherwise: bb2]; + switchInt(move _10) -> [0: bb7, 1: bb6, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_9); _9 = ((_3 as Continue).0: i32); _2 = _9; @@ -70,10 +74,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_6); _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); @@ -103,8 +103,8 @@ StorageDead(_10); StorageDead(_4); _5 = discriminant(_3); -- switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; -+ goto -> bb1; +- switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1]; ++ goto -> bb2; } bb6: { diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff index 9cc4385f60b..d67477ab1b9 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff @@ -56,10 +56,14 @@ StorageLive(_11); StorageLive(_12); _10 = discriminant(_4); - switchInt(move _10) -> [0: bb7, 1: bb6, otherwise: bb2]; + switchInt(move _10) -> [0: bb7, 1: bb6, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_9); _9 = ((_3 as Continue).0: i32); _2 = _9; @@ -70,10 +74,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { StorageLive(_6); _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); @@ -103,8 +103,8 @@ StorageDead(_10); StorageDead(_4); _5 = discriminant(_3); -- switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; -+ goto -> bb1; +- switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1]; ++ goto -> bb2; } bb6: { diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs index a66fe8b57e7..512aebd857a 100644 --- a/tests/mir-opt/jump_threading.rs +++ b/tests/mir-opt/jump_threading.rs @@ -12,12 +12,12 @@ use std::ops::ControlFlow; fn too_complex(x: Result<i32, usize>) -> Option<i32> { // CHECK-LABEL: fn too_complex( // CHECK: bb0: { - // CHECK: switchInt(move {{_.*}}) -> [0: bb3, 1: bb1, otherwise: bb2]; + // CHECK: switchInt(move {{_.*}}) -> [0: bb3, 1: bb2, otherwise: bb1]; // CHECK: bb1: { + // CHECK: unreachable; + // CHECK: bb2: { // CHECK: [[controlflow:_.*]] = ControlFlow::<usize, i32>::Break( // CHECK: goto -> bb8; - // CHECK: bb2: { - // CHECK: unreachable; // CHECK: bb3: { // CHECK: [[controlflow]] = ControlFlow::<usize, i32>::Continue( // CHECK: goto -> bb4; @@ -50,13 +50,13 @@ fn identity(x: Result<i32, i32>) -> Result<i32, i32> { // CHECK-LABEL: fn identity( // CHECK: bb0: { // CHECK: [[x:_.*]] = _1; - // CHECK: switchInt(move {{_.*}}) -> [0: bb7, 1: bb6, otherwise: bb2]; + // CHECK: switchInt(move {{_.*}}) -> [0: bb7, 1: bb6, otherwise: bb1]; // CHECK: bb1: { + // CHECK: unreachable; + // CHECK: bb2: { // CHECK: {{_.*}} = (([[controlflow:_.*]] as Continue).0: i32); // CHECK: _0 = Result::<i32, i32>::Ok( // CHECK: goto -> bb4; - // CHECK: bb2: { - // CHECK: unreachable; // CHECK: bb3: { // CHECK: {{_.*}} = (([[controlflow]] as Break).0: std::result::Result<std::convert::Infallible, i32>); // CHECK: _0 = Result::<i32, i32>::Err( @@ -64,7 +64,7 @@ fn identity(x: Result<i32, i32>) -> Result<i32, i32> { // CHECK: bb4: { // CHECK: return; // CHECK: bb5: { - // CHECK: goto -> bb1; + // CHECK: goto -> bb2; // CHECK: bb6: { // CHECK: {{_.*}} = move (([[x]] as Err).0: i32); // CHECK: [[controlflow]] = ControlFlow::<Result<Infallible, i32>, i32>::Break( @@ -93,11 +93,11 @@ fn dfa() { // CHECK: {{_.*}} = DFA::A; // CHECK: goto -> bb1; // CHECK: bb1: { - // CHECK: switchInt({{.*}}) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3]; + // CHECK: switchInt({{.*}}) -> [0: bb4, 1: bb5, 2: bb6, 3: bb3, otherwise: bb2]; // CHECK: bb2: { - // CHECK: return; - // CHECK: bb3: { // CHECK: unreachable; + // CHECK: bb3: { + // CHECK: return; // CHECK: bb4: { // CHECK: {{_.*}} = DFA::B; // CHECK: goto -> bb1; diff --git a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff index f5eade4a914..365d9d6b32b 100644 --- a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff @@ -30,10 +30,14 @@ bb0: { StorageLive(_2); _3 = discriminant(_1); - switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; + switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_6); _6 = ((_1 as Err).0: usize); StorageLive(_7); @@ -45,10 +49,6 @@ + goto -> bb8; } - bb2: { - unreachable; - } - bb3: { StorageLive(_4); _4 = ((_1 as Ok).0: i32); @@ -62,7 +62,7 @@ bb4: { _8 = discriminant(_2); -- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2]; +- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1]; + goto -> bb6; } diff --git a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff index f5eade4a914..365d9d6b32b 100644 --- a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff @@ -30,10 +30,14 @@ bb0: { StorageLive(_2); _3 = discriminant(_1); - switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; + switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_6); _6 = ((_1 as Err).0: usize); StorageLive(_7); @@ -45,10 +49,6 @@ + goto -> bb8; } - bb2: { - unreachable; - } - bb3: { StorageLive(_4); _4 = ((_1 as Ok).0: i32); @@ -62,7 +62,7 @@ bb4: { _8 = discriminant(_2); -- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2]; +- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1]; + goto -> bb6; } diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff index b4bd45ba597..307f7105dd2 100644 --- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -32,33 +32,25 @@ bb0: { PlaceMention(_2); -- switchInt((_2.0: bool)) -> [0: bb1, otherwise: bb2]; +- switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb1]; + switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1]; } bb1: { -- falseEdge -> [real: bb8, imaginary: bb3]; +- switchInt((_2.1: bool)) -> [0: bb5, otherwise: bb2]; + switchInt((_2.1: bool)) -> [0: bb10, otherwise: bb2]; } bb2: { -- switchInt((_2.1: bool)) -> [0: bb3, otherwise: bb4]; +- switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3]; + switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17]; } bb3: { -- falseEdge -> [real: bb13, imaginary: bb5]; +- falseEdge -> [real: bb20, imaginary: bb4]; - } - - bb4: { -- switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb5]; -- } -- -- bb5: { -- falseEdge -> [real: bb20, imaginary: bb6]; -- } -- -- bb6: { StorageLive(_15); _15 = (_2.1: bool); StorageLive(_16); @@ -67,6 +59,14 @@ + goto -> bb16; } +- bb5: { +- falseEdge -> [real: bb13, imaginary: bb3]; +- } +- +- bb6: { +- falseEdge -> [real: bb8, imaginary: bb5]; +- } +- - bb7: { + bb4: { _0 = const 1_i32; @@ -127,7 +127,7 @@ StorageDead(_9); StorageDead(_8); StorageDead(_6); -- falseEdge -> [real: bb2, imaginary: bb3]; +- falseEdge -> [real: bb1, imaginary: bb5]; + goto -> bb1; } @@ -184,7 +184,7 @@ StorageDead(_12); StorageDead(_8); StorageDead(_6); -- falseEdge -> [real: bb4, imaginary: bb5]; +- falseEdge -> [real: bb2, imaginary: bb3]; + goto -> bb2; } diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff index b4bd45ba597..307f7105dd2 100644 --- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -32,33 +32,25 @@ bb0: { PlaceMention(_2); -- switchInt((_2.0: bool)) -> [0: bb1, otherwise: bb2]; +- switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb1]; + switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1]; } bb1: { -- falseEdge -> [real: bb8, imaginary: bb3]; +- switchInt((_2.1: bool)) -> [0: bb5, otherwise: bb2]; + switchInt((_2.1: bool)) -> [0: bb10, otherwise: bb2]; } bb2: { -- switchInt((_2.1: bool)) -> [0: bb3, otherwise: bb4]; +- switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3]; + switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17]; } bb3: { -- falseEdge -> [real: bb13, imaginary: bb5]; +- falseEdge -> [real: bb20, imaginary: bb4]; - } - - bb4: { -- switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb5]; -- } -- -- bb5: { -- falseEdge -> [real: bb20, imaginary: bb6]; -- } -- -- bb6: { StorageLive(_15); _15 = (_2.1: bool); StorageLive(_16); @@ -67,6 +59,14 @@ + goto -> bb16; } +- bb5: { +- falseEdge -> [real: bb13, imaginary: bb3]; +- } +- +- bb6: { +- falseEdge -> [real: bb8, imaginary: bb5]; +- } +- - bb7: { + bb4: { _0 = const 1_i32; @@ -127,7 +127,7 @@ StorageDead(_9); StorageDead(_8); StorageDead(_6); -- falseEdge -> [real: bb2, imaginary: bb3]; +- falseEdge -> [real: bb1, imaginary: bb5]; + goto -> bb1; } @@ -184,7 +184,7 @@ StorageDead(_12); StorageDead(_8); StorageDead(_6); -- falseEdge -> [real: bb4, imaginary: bb5]; +- falseEdge -> [real: bb2, imaginary: bb3]; + goto -> bb2; } diff --git a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir index 5bf78b6150f..107f56f7f69 100644 --- a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir @@ -32,12 +32,12 @@ fn main() -> () { } bb1: { - falseEdge -> [real: bb9, imaginary: bb4]; + _3 = const 3_i32; + goto -> bb14; } bb2: { - _3 = const 3_i32; - goto -> bb14; + falseEdge -> [real: bb9, imaginary: bb4]; } bb3: { @@ -50,11 +50,11 @@ fn main() -> () { } bb5: { - switchInt(_1) -> [4294967295: bb6, otherwise: bb2]; + switchInt(_1) -> [4294967295: bb6, otherwise: bb1]; } bb6: { - falseEdge -> [real: bb13, imaginary: bb2]; + falseEdge -> [real: bb13, imaginary: bb1]; } bb7: { @@ -64,7 +64,7 @@ fn main() -> () { bb8: { _7 = Lt(_1, const 10_i32); - switchInt(move _7) -> [0: bb3, otherwise: bb1]; + switchInt(move _7) -> [0: bb3, otherwise: bb2]; } bb9: { @@ -83,7 +83,7 @@ fn main() -> () { bb11: { StorageDead(_9); - falseEdge -> [real: bb2, imaginary: bb4]; + falseEdge -> [real: bb1, imaginary: bb4]; } bb12: { diff --git a/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff index fec58556366..157f9c98353 100644 --- a/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff +++ b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff @@ -8,16 +8,16 @@ bb0: { _2 = discriminant(_1); - switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; + switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { - _0 = const 1_u8; - goto -> bb4; + unreachable; } bb2: { - unreachable; + _0 = const 1_u8; + goto -> bb4; } bb3: { diff --git a/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff index 94d3ce6c971..19083771fd9 100644 --- a/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff +++ b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff @@ -8,16 +8,16 @@ bb0: { _2 = discriminant(_1); - switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; + switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { - _0 = const 1_i8; - goto -> bb4; + unreachable; } bb2: { - unreachable; + _0 = const 1_i8; + goto -> bb4; } bb3: { diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir index 08695523646..31a6a1d8b3d 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -15,16 +15,16 @@ fn unwrap(_1: Option<T>) -> T { bb0: { _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; + switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; + unreachable; } bb2: { - unreachable; + StorageLive(_4); + _4 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } bb3: { diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir index 6276d854846..53352fbb19f 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -15,16 +15,16 @@ fn unwrap(_1: Option<T>) -> T { bb0: { _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; + switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb4; + unreachable; } bb2: { - unreachable; + StorageLive(_4); + _4 = begin_panic::<&str>(const "explicit panic") -> bb4; } bb3: { diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff index 1648f5dd8ca..84350b0dc51 100644 --- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff @@ -67,10 +67,14 @@ StorageLive(_7); _7 = Option::<i32>::Some(const 0_i32); _8 = discriminant(_7); - switchInt(move _8) -> [0: bb3, 1: bb1, otherwise: bb2]; + switchInt(move _8) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_9); _27 = const _; _9 = &(((*_27) as Some).0: i32); @@ -79,10 +83,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { - _6 = const (); goto -> bb4; diff --git a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff index 8804e671527..14762b9c40f 100644 --- a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff +++ b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-abort.diff @@ -55,10 +55,14 @@ bb3: { - StorageDead(_8); _10 = discriminant(_7); - switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb4]; } bb4: { + unreachable; + } + + bb5: { - StorageLive(_12); _12 = ((_7 as Some).0: i32); - StorageLive(_13); @@ -74,10 +78,6 @@ goto -> bb2; } - bb5: { - unreachable; - } - bb6: { _0 = const (); - StorageDead(_9); diff --git a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff index faaebc300ef..24797424b5c 100644 --- a/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff +++ b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.panic-unwind.diff @@ -55,10 +55,14 @@ bb3: { - StorageDead(_8); _10 = discriminant(_7); - switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb4]; } bb4: { + unreachable; + } + + bb5: { - StorageLive(_12); _12 = ((_7 as Some).0: i32); - StorageLive(_13); @@ -74,10 +78,6 @@ goto -> bb2; } - bb5: { - unreachable; - } - bb6: { _0 = const (); - StorageDead(_9); diff --git a/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff index 9ff32b26b77..5611d679b78 100644 --- a/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff +++ b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff @@ -18,10 +18,14 @@ - _5 = const false; - _5 = const true; _2 = discriminant(_1); - switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; + switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_3); _3 = move ((_1 as Some).0: std::boxed::Box<()>); StorageLive(_4); @@ -32,10 +36,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { _0 = Option::<Box<()>>::None; goto -> bb4; diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff index 7919450cdc5..5a3544f8538 100644 --- a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff @@ -30,11 +30,15 @@ StorageLive(_4); _4 = &(_1.1: Test3); _5 = discriminant((*_4)); -- switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb1, otherwise: bb2]; -+ switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb1, otherwise: bb12]; +- switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb2, otherwise: bb1]; ++ switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb2, otherwise: bb12]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_8); _8 = const "D"; _3 = &(*_8); @@ -42,10 +46,6 @@ goto -> bb6; } - bb2: { - unreachable; - } - bb3: { _3 = const "A(Empty)"; goto -> bb6; @@ -72,7 +72,7 @@ StorageDead(_3); StorageLive(_9); _10 = discriminant((_1.1: Test3)); -- switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb2]; +- switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb1]; + switchInt(move _10) -> [0: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12]; } diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff index 5e15298a78c..121374553ed 100644 --- a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff @@ -13,11 +13,15 @@ StorageLive(_2); _2 = Test2::D; _3 = discriminant(_2); -- switchInt(move _3) -> [4: bb3, 5: bb1, otherwise: bb2]; -+ switchInt(move _3) -> [4: bb3, 5: bb1, otherwise: bb5]; +- switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1]; ++ switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb5]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_4); _4 = const "E"; _1 = &(*_4); @@ -25,10 +29,6 @@ goto -> bb4; } - bb2: { - unreachable; - } - bb3: { _1 = const "D"; goto -> bb4; diff --git a/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/uninhabited_enum_branching.rs index 60389117b16..65552fb058a 100644 --- a/tests/mir-opt/uninhabited_enum_branching.rs +++ b/tests/mir-opt/uninhabited_enum_branching.rs @@ -32,7 +32,7 @@ struct Plop { fn simple() { // CHECK-LABEL: fn simple( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb1, otherwise: [[unreachable]]]; + // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb2, otherwise: [[unreachable]]]; // CHECK: [[unreachable]]: { // CHECK-NEXT: unreachable; match Test1::C { @@ -46,7 +46,7 @@ fn simple() { fn custom_discriminant() { // CHECK-LABEL: fn custom_discriminant( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb1, otherwise: bb5]; + // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb2, otherwise: bb5]; // CHECK: bb5: { // CHECK-NEXT: unreachable; match Test2::D { @@ -61,7 +61,7 @@ fn byref() { let plop = Plop { xx: 51, test3: Test3::C }; // CHECK: [[ref_discr:_.*]] = discriminant((* - // CHECK: switchInt(move [[ref_discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb5, 3: bb1, otherwise: [[unreachable]]]; + // CHECK: switchInt(move [[ref_discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb5, 3: bb2, otherwise: [[unreachable]]]; match &plop.test3 { Test3::A(_) => "A(Empty)", Test3::B(_) => "B(Empty)", diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff index 410db79802e..6ce61e15287 100644 --- a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff @@ -14,11 +14,15 @@ StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); -- switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb1, otherwise: bb2]; -+ switchInt(move _3) -> [0: bb6, 1: bb6, 2: bb1, otherwise: bb6]; +- switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb2, otherwise: bb1]; ++ switchInt(move _3) -> [0: bb6, 1: bb6, 2: bb2, otherwise: bb6]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = const "C"; _1 = &(*_5); @@ -26,10 +30,6 @@ goto -> bb5; } - bb2: { - unreachable; - } - bb3: { _1 = const "A(Empty)"; goto -> bb5; diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff index f6e594ffac7..da7a2bd10e0 100644 --- a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff +++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff @@ -19,20 +19,20 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [0: bb4, 1: bb2, otherwise: bb3]; +- switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb2]; + _5 = Eq(_2, const 0_isize); + assume(move _5); + goto -> bb4; } bb2: { -- StorageLive(_3); -- _3 = move ((_1 as Some).0: Empty); -- StorageLive(_4); unreachable; } bb3: { +- StorageLive(_3); +- _3 = move ((_1 as Some).0: Empty); +- StorageLive(_4); unreachable; } diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff index 2813d64672e..a2121fc684f 100644 --- a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff +++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff @@ -19,20 +19,20 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [0: bb4, 1: bb2, otherwise: bb3]; +- switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb2]; + _5 = Eq(_2, const 0_isize); + assume(move _5); + goto -> bb4; } bb2: { -- StorageLive(_3); -- _3 = move ((_1 as Some).0: Empty); -- StorageLive(_4); unreachable; } bb3: { +- StorageLive(_3); +- _3 = move ((_1 as Some).0: Empty); +- StorageLive(_4); unreachable; } diff --git a/tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs new file mode 100644 index 00000000000..3e3e602eb1b --- /dev/null +++ b/tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs @@ -0,0 +1,29 @@ +// This test ensures that non-glob reexports don't get their attributes merge with +// the reexported item whereas glob reexports do with the `doc_auto_cfg` feature. + +#![crate_name = "foo"] +#![feature(doc_auto_cfg)] + +// @has 'foo/index.html' +// There are two items. +// @count - '//*[@class="item-table"]//div[@class="item-name"]' 2 +// Only one of them should have an attribute. +// @count - '//*[@class="item-table"]//div[@class="item-name"]/*[@class="stab portability"]' 1 + +mod a { + #[cfg(not(feature = "a"))] + pub struct Test1; +} + +mod b { + #[cfg(not(feature = "a"))] + pub struct Test2; +} + +// @has 'foo/struct.Test1.html' +// @count - '//*[@id="main-content"]/*[@class="item-info"]' 1 +// @has - '//*[@id="main-content"]/*[@class="item-info"]' 'Available on non-crate feature a only.' +pub use a::*; +// @has 'foo/struct.Test2.html' +// @count - '//*[@id="main-content"]/*[@class="item-info"]' 0 +pub use b::Test2; diff --git a/tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs b/tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs new file mode 100644 index 00000000000..70f7a84a8dc --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs @@ -0,0 +1,17 @@ +// Here, `'a` and `'c` are late-bound and `'b`, `'d`, `T` and `N` are early-bound. + +pub fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy) +where + 'b:, + 'd:, +{} + +pub struct Ty; + +impl Ty { + pub fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy) + where + 'b:, + 'd:, + {} +} diff --git a/tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs b/tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs new file mode 100644 index 00000000000..09cc8a79072 --- /dev/null +++ b/tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs @@ -0,0 +1,17 @@ +// Check that we correctly render late-bound lifetime params in source order +// even if early-bound generic params are present. +// +// For context, at the time of writing early- and late-bound params are stored +// separately in rustc and therefore rustdoc needs to manually merge them. + +#![crate_name = "usr"] +// aux-crate:dep=early-late-bound-lifetime-params.rs +// edition:2021 + +// @has usr/fn.f.html +// @has - '//pre[@class="rust item-decl"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy)" +pub use dep::f; + +// @has usr/struct.Ty.html +// @has - '//*[@id="method.f"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy)" +pub use dep::Ty; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 67257c28b6e..2032b8a972a 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -2,7 +2,7 @@ error: unsupported type attribute for diagnostic derive enum --> $DIR/diagnostic-derive.rs:47:1 | LL | #[diag(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:50:5 @@ -24,27 +24,21 @@ error: `#[nonsense(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:63:1 | LL | #[nonsense(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:63:1 | -LL | / #[nonsense(no_crate_example, code = E0123)] -LL | | -LL | | -LL | | -LL | | struct InvalidStructAttr {} - | |___________________________^ +LL | #[nonsense(no_crate_example, code = E0123)] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:70:1 | -LL | / #[diag(code = E0123)] -LL | | -LL | | struct InvalidLitNestedAttr {} - | |______________________________^ +LL | #[diag(code = E0123)] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -57,11 +51,8 @@ LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:80:1 | -LL | / #[diag(nonsense("foo"), code = E0123, slug = "foo")] -LL | | -LL | | -LL | | struct InvalidNestedStructAttr1 {} - | |__________________________________^ +LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -76,11 +67,8 @@ LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:86:1 | -LL | / #[diag(nonsense = "...", code = E0123, slug = "foo")] -LL | | -LL | | -LL | | struct InvalidNestedStructAttr2 {} - | |__________________________________^ +LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -95,11 +83,8 @@ LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:92:1 | -LL | / #[diag(nonsense = 4, code = E0123, slug = "foo")] -LL | | -LL | | -LL | | struct InvalidNestedStructAttr3 {} - | |__________________________________^ +LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -115,7 +100,7 @@ error: `#[suggestion = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:105:5 | LL | #[suggestion = "bar"] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^ error: specified multiple times --> $DIR/diagnostic-derive.rs:112:8 @@ -163,17 +148,15 @@ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:128:1 | LL | struct KindNotProvided {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:131:1 | -LL | / #[diag(code = E0123)] -LL | | -LL | | struct SlugNotProvided {} - | |_________________________^ +LL | #[diag(code = E0123)] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -181,19 +164,19 @@ error: the `#[primary_span]` attribute can only be applied to fields of type `Sp --> $DIR/diagnostic-derive.rs:142:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ error: `#[nonsense]` is not a valid attribute --> $DIR/diagnostic-derive.rs:150:5 | LL | #[nonsense] - | ^^^^^^^^^^^ + | ^ error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:167:5 | LL | #[label(no_crate_label)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: `name` doesn't refer to a field on this type --> $DIR/diagnostic-derive.rs:175:46 @@ -223,13 +206,13 @@ error: the `#[label(...)]` attribute can only be applied to fields of type `Span --> $DIR/diagnostic-derive.rs:210:5 | LL | #[label(no_crate_label)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:229:5 | LL | #[suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: invalid nested attribute --> $DIR/diagnostic-derive.rs:237:18 @@ -243,7 +226,7 @@ error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:237:5 | LL | #[suggestion(nonsense = "bar")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: invalid nested attribute --> $DIR/diagnostic-derive.rs:246:18 @@ -257,15 +240,13 @@ error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:246:5 | LL | #[suggestion(msg = "bar")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: wrong field type for suggestion --> $DIR/diagnostic-derive.rs:269:5 | -LL | / #[suggestion(no_crate_suggestion, code = "This is suggested code")] -LL | | -LL | | suggestion: Applicability, - | |_____________________________^ +LL | #[suggestion(no_crate_suggestion, code = "This is suggested code")] + | ^ | = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` @@ -297,13 +278,13 @@ error: `#[label = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:300:5 | LL | #[label = "bar"] - | ^^^^^^^^^^^^^^^^ + | ^ error: specified multiple times --> $DIR/diagnostic-derive.rs:451:5 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | note: previously specified here --> $DIR/diagnostic-derive.rs:453:24 @@ -321,7 +302,7 @@ error: the `#[help(...)]` attribute can only be applied to fields of type `Span` --> $DIR/diagnostic-derive.rs:526:5 | LL | #[help(no_crate_help)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: a diagnostic slug must be the first argument to the attribute --> $DIR/diagnostic-derive.rs:535:32 @@ -345,7 +326,7 @@ error: `#[primary_span]` is not a valid attribute --> $DIR/diagnostic-derive.rs:563:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ | = help: the `primary_span` field attribute is not valid for lint diagnostics @@ -353,17 +334,13 @@ error: `#[error(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:583:1 | LL | #[error(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:583:1 | -LL | / #[error(no_crate_example, code = E0123)] -LL | | -LL | | -LL | | -LL | | struct ErrorAttribute {} - | |________________________^ +LL | #[error(no_crate_example, code = E0123)] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -371,17 +348,13 @@ error: `#[warn_(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:590:1 | LL | #[warn_(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:590:1 | -LL | / #[warn_(no_crate_example, code = E0123)] -LL | | -LL | | -LL | | -LL | | struct WarnAttribute {} - | |_______________________^ +LL | #[warn_(no_crate_example, code = E0123)] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -389,17 +362,13 @@ error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:597:1 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:597:1 | -LL | / #[lint(no_crate_example, code = E0123)] -LL | | -LL | | -LL | | -LL | | struct LintAttributeOnSessionDiag {} - | |____________________________________^ +LL | #[lint(no_crate_example, code = E0123)] + | ^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` @@ -407,26 +376,21 @@ error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:604:1 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:604:1 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:604:1 | -LL | / #[lint(no_crate_example, code = E0123)] -LL | | -LL | | -LL | | -LL | | -LL | | struct LintAttributeOnLintDiag {} - | |_________________________________^ +LL | #[lint(no_crate_example, code = E0123)] + | ^ | = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` @@ -462,13 +426,13 @@ error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:638:5 | LL | #[suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: `#[multipart_suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:645:1 | LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: consider creating a `Subdiagnostic` instead @@ -476,7 +440,7 @@ error: `#[multipart_suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:648:1 | LL | #[multipart_suggestion()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: consider creating a `Subdiagnostic` instead @@ -484,7 +448,7 @@ error: `#[multipart_suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:652:5 | LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: consider creating a `Subdiagnostic` instead @@ -492,7 +456,7 @@ error: `#[suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:660:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: `#[label]` and `#[suggestion]` can only be applied to fields @@ -500,7 +464,7 @@ error: `#[label]` is not a valid attribute --> $DIR/diagnostic-derive.rs:669:1 | LL | #[label] - | ^^^^^^^^ + | ^ | = help: `#[label]` and `#[suggestion]` can only be applied to fields @@ -508,31 +472,31 @@ error: `eager` is the only supported nested attribute for `subdiagnostic` --> $DIR/diagnostic-derive.rs:703:7 | LL | #[subdiagnostic(bad)] - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: `#[subdiagnostic = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:711:5 | LL | #[subdiagnostic = "bad"] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: `eager` is the only supported nested attribute for `subdiagnostic` --> $DIR/diagnostic-derive.rs:719:7 | LL | #[subdiagnostic(bad, bad)] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: `eager` is the only supported nested attribute for `subdiagnostic` --> $DIR/diagnostic-derive.rs:727:7 | LL | #[subdiagnostic("bad")] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:735:5 | LL | #[subdiagnostic(eager)] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: eager subdiagnostics are not supported on lints @@ -552,7 +516,7 @@ error: `#[suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:825:5 | LL | #[suggestion(no_crate_suggestion, code = "")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = note: `#[suggestion(...)]` applied to `Vec` field is ambiguous = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 80bee3bd6e6..fccf3757dbe 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -1,30 +1,26 @@ error: label without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:51:1 | -LL | / #[label(no_crate_example)] -LL | | -LL | | struct C { -LL | | var: String, -LL | | } - | |_^ +LL | #[label(no_crate_example)] + | ^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive.rs:58:1 | LL | #[label] - | ^^^^^^^^ + | ^ error: `#[foo]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:67:1 | LL | #[foo] - | ^^^^^^ + | ^ error: `#[label = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:77:1 | LL | #[label = "..."] - | ^^^^^^^^^^^^^^^^ + | ^ error: only `no_span` is a valid nested attribute --> $DIR/subdiagnostic-derive.rs:86:9 @@ -36,7 +32,7 @@ error: diagnostic slug must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive.rs:86:1 | LL | #[label(bug = "...")] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^ error: only `no_span` is a valid nested attribute --> $DIR/subdiagnostic-derive.rs:106:9 @@ -48,7 +44,7 @@ error: diagnostic slug must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive.rs:106:1 | LL | #[label(slug = 4)] - | ^^^^^^^^^^^^^^^^^^ + | ^ error: only `no_span` is a valid nested attribute --> $DIR/subdiagnostic-derive.rs:116:9 @@ -60,13 +56,13 @@ error: diagnostic slug must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive.rs:116:1 | LL | #[label(slug("..."))] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive.rs:136:1 | LL | #[label()] - | ^^^^^^^^^^ + | ^ error: only `no_span` is a valid nested attribute --> $DIR/subdiagnostic-derive.rs:145:27 @@ -84,31 +80,31 @@ error: unsupported type attribute for subdiagnostic enum --> $DIR/subdiagnostic-derive.rs:163:1 | LL | #[foo] - | ^^^^^^ + | ^ error: `#[bar]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:177:5 | LL | #[bar] - | ^^^^^^ + | ^ error: `#[bar = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:189:5 | LL | #[bar = "..."] - | ^^^^^^^^^^^^^^ + | ^ error: `#[bar = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:201:5 | LL | #[bar = 4] - | ^^^^^^^^^^ + | ^ error: `#[bar(...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:213:5 | LL | #[bar("...")] - | ^^^^^^^^^^^^^ + | ^ error: only `no_span` is a valid nested attribute --> $DIR/subdiagnostic-derive.rs:225:13 @@ -120,37 +116,31 @@ error: diagnostic slug must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive.rs:225:5 | LL | #[label(code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/subdiagnostic-derive.rs:254:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ error: label without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:251:1 | -LL | / #[label(no_crate_example)] -LL | | -LL | | struct W { -LL | | #[primary_span] -LL | | -LL | | span: String, -LL | | } - | |_^ +LL | #[label(no_crate_example)] + | ^ error: `#[applicability]` is only valid on suggestions --> $DIR/subdiagnostic-derive.rs:264:5 | LL | #[applicability] - | ^^^^^^^^^^^^^^^^ + | ^ error: `#[bar]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:274:5 | LL | #[bar] - | ^^^^^^ + | ^ | = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes @@ -158,13 +148,13 @@ error: `#[bar = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:285:5 | LL | #[bar = "..."] - | ^^^^^^^^^^^^^^ + | ^ error: `#[bar(...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:296:5 | LL | #[bar("...")] - | ^^^^^^^^^^^^^ + | ^ | = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes @@ -178,13 +168,13 @@ error: specified multiple times --> $DIR/subdiagnostic-derive.rs:341:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ | note: previously specified here --> $DIR/subdiagnostic-derive.rs:338:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ error: subdiagnostic kind not specified --> $DIR/subdiagnostic-derive.rs:347:8 @@ -208,25 +198,25 @@ error: specified multiple times --> $DIR/subdiagnostic-derive.rs:402:5 | LL | #[applicability] - | ^^^^^^^^^^^^^^^^ + | ^ | note: previously specified here --> $DIR/subdiagnostic-derive.rs:399:5 | LL | #[applicability] - | ^^^^^^^^^^^^^^^^ + | ^ error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` --> $DIR/subdiagnostic-derive.rs:412:5 | LL | #[applicability] - | ^^^^^^^^^^^^^^^^ + | ^ error: suggestion without `code = "..."` --> $DIR/subdiagnostic-derive.rs:425:1 | LL | #[suggestion(no_crate_example)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: invalid applicability --> $DIR/subdiagnostic-derive.rs:435:62 @@ -237,18 +227,14 @@ LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] error: suggestion without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:453:1 | -LL | / #[suggestion(no_crate_example, code = "...")] -LL | | -LL | | struct AR { -LL | | var: String, -LL | | } - | |_^ +LL | #[suggestion(no_crate_example, code = "...")] + | ^ error: unsupported type attribute for subdiagnostic enum --> $DIR/subdiagnostic-derive.rs:467:1 | LL | #[label] - | ^^^^^^^^ + | ^ error: `var` doesn't refer to a field on this type --> $DIR/subdiagnostic-derive.rs:487:39 @@ -266,7 +252,7 @@ error: `#[suggestion_part]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:529:5 | LL | #[suggestion_part] - | ^^^^^^^^^^^^^^^^^^ + | ^ | = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead @@ -274,21 +260,15 @@ error: `#[suggestion_part(...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:532:5 | LL | #[suggestion_part(code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: suggestion without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:526:1 | -LL | / #[suggestion(no_crate_example, code = "...")] -LL | | -LL | | struct BA { -LL | | #[suggestion_part] -... | -LL | | var: String, -LL | | } - | |_^ +LL | #[suggestion(no_crate_example, code = "...")] + | ^ error: invalid nested attribute --> $DIR/subdiagnostic-derive.rs:541:42 @@ -301,57 +281,46 @@ LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "mac error: multipart suggestion without any `#[suggestion_part(...)]` fields --> $DIR/subdiagnostic-derive.rs:541:1 | -LL | / #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] -LL | | -LL | | -LL | | struct BBa { -LL | | var: String, -LL | | } - | |_^ +LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] + | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` --> $DIR/subdiagnostic-derive.rs:551:5 | LL | #[suggestion_part] - | ^^^^^^^^^^^^^^^^^^ + | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` --> $DIR/subdiagnostic-derive.rs:559:5 | LL | #[suggestion_part()] - | ^^^^^^^^^^^^^^^^^^^^ + | ^ error: `#[primary_span]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:568:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ | = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: multipart suggestion without any `#[suggestion_part(...)]` fields --> $DIR/subdiagnostic-derive.rs:565:1 | -LL | / #[multipart_suggestion(no_crate_example)] -LL | | -LL | | struct BC { -LL | | #[primary_span] -LL | | -LL | | span: Span, -LL | | } - | |_^ +LL | #[multipart_suggestion(no_crate_example)] + | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` --> $DIR/subdiagnostic-derive.rs:576:5 | LL | #[suggestion_part] - | ^^^^^^^^^^^^^^^^^^ + | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` --> $DIR/subdiagnostic-derive.rs:579:5 | LL | #[suggestion_part()] - | ^^^^^^^^^^^^^^^^^^^^ + | ^ error: `code` is the only valid nested attribute --> $DIR/subdiagnostic-derive.rs:582:23 @@ -363,13 +332,13 @@ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of --> $DIR/subdiagnostic-derive.rs:587:5 | LL | #[suggestion_part(code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/subdiagnostic-derive.rs:590:5 | LL | #[suggestion_part()] - | ^^^^^^^^^^^^^^^^^^^^ + | ^ error: specified multiple times --> $DIR/subdiagnostic-derive.rs:598:37 @@ -387,7 +356,7 @@ error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_sugg --> $DIR/subdiagnostic-derive.rs:627:5 | LL | #[applicability] - | ^^^^^^^^^^^^^^^^ + | ^ error: expected exactly one string literal for `code = ...` --> $DIR/subdiagnostic-derive.rs:675:34 @@ -417,19 +386,19 @@ error: specified multiple times --> $DIR/subdiagnostic-derive.rs:763:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | note: previously specified here --> $DIR/subdiagnostic-derive.rs:763:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: `#[suggestion_hidden(...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:772:1 | LL | #[suggestion_hidden(no_crate_example, code = "")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: Use `#[suggestion(..., style = "hidden")]` instead @@ -437,7 +406,7 @@ error: `#[suggestion_hidden(...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:780:1 | LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = help: Use `#[suggestion(..., style = "hidden")]` instead @@ -471,7 +440,7 @@ error: `#[primary_span]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:825:5 | LL | #[primary_span] - | ^^^^^^^^^^^^^^^ + | ^ | = note: there must be exactly one primary span = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead @@ -479,14 +448,8 @@ LL | #[primary_span] error: suggestion without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:822:1 | -LL | / #[suggestion(no_crate_example, code = "")] -LL | | -LL | | struct PrimarySpanOnVec { -LL | | #[primary_span] -... | -LL | | sub: Vec<Span>, -LL | | } - | |_^ +LL | #[suggestion(no_crate_example, code = "")] + | ^ error[E0433]: failed to resolve: maybe a missing crate `core`? --> $DIR/subdiagnostic-derive.rs:96:9 diff --git a/tests/ui-fulldeps/stable-mir/check_foreign.rs b/tests/ui-fulldeps/stable-mir/check_foreign.rs new file mode 100644 index 00000000000..e6c59354d5e --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/check_foreign.rs @@ -0,0 +1,93 @@ +// run-pass +//! Test retrieval and kinds of foreign items. + +// ignore-stage1 +// ignore-cross-compile +// ignore-remote +// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 +// edition: 2021 + +#![feature(rustc_private)] +#![feature(assert_matches)] +#![feature(control_flow_enum)] + +extern crate rustc_middle; +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate rustc_span; +extern crate stable_mir; + +use rustc_smir::rustc_internal; +use stable_mir::{ + ty::{Abi, ForeignItemKind}, + *, +}; +use std::assert_matches::assert_matches; +use std::io::Write; +use std::ops::ControlFlow; + +const CRATE_NAME: &str = "input"; + +/// This function uses the Stable MIR APIs to get information about the test crate. +fn test_foreign() -> ControlFlow<()> { + let mods = + local_crate().foreign_modules().into_iter().map(|def| def.module()).collect::<Vec<_>>(); + assert_eq!(mods.len(), 2); + + let rust_mod = mods.iter().find(|m| matches!(m.abi, Abi::Rust)).unwrap(); + assert_eq!(rust_mod.items().len(), 1); + + let c_mod = mods.iter().find(|m| matches!(m.abi, Abi::C { .. })).unwrap(); + let c_items = c_mod.items(); + assert_eq!(c_items.len(), 3); + for item in c_items { + let kind = item.kind(); + match item.name().as_str() { + "foo" => assert_matches!(kind, ForeignItemKind::Fn(..)), + "bar" => assert_matches!(kind, ForeignItemKind::Static(..)), + "Baz" => assert_matches!(kind, ForeignItemKind::Type(..)), + name => unreachable!("Unexpected item {name}"), + }; + } + ControlFlow::Continue(()) +} + +/// This test will generate and analyze a dummy crate using the stable mir. +/// For that, it will first write the dummy crate into a file. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. +fn main() { + let path = "foreign_input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "-Cpanic=abort".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run!(args, || test_foreign()).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + #![feature(extern_types)] + #![allow(unused)] + extern "Rust" {{ + fn rust_foo(x: i32) -> i32; + }} + extern "C" {{ + fn foo(x: i32) -> i32; + static bar: i32; + type Baz; + }} + "# + )?; + Ok(()) +} diff --git a/tests/ui/abi/issues/issue-22565-rust-call.rs b/tests/ui/abi/issues/issue-22565-rust-call.rs index a572666c888..72f45cba0c0 100644 --- a/tests/ui/abi/issues/issue-22565-rust-call.rs +++ b/tests/ui/abi/issues/issue-22565-rust-call.rs @@ -25,7 +25,11 @@ impl Tr for Foo { fn main() { b(10); + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument Foo::bar(); + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument <Foo as Tr>::a(); + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument <Foo as Tr>::b(); + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument } diff --git a/tests/ui/abi/issues/issue-22565-rust-call.stderr b/tests/ui/abi/issues/issue-22565-rust-call.stderr index 9d205b444fa..0fd3285cd3a 100644 --- a/tests/ui/abi/issues/issue-22565-rust-call.stderr +++ b/tests/ui/abi/issues/issue-22565-rust-call.stderr @@ -28,6 +28,30 @@ error: functions with the "rust-call" ABI must take a single non-self tuple argu LL | extern "rust-call" fn b() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:27:7 + | +LL | b(10); + | ^^ the trait `Tuple` is not implemented for `i32` + +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:29:5 + | +LL | Foo::bar(); + | ^^^^^^^^^^ + +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:31:5 + | +LL | <Foo as Tr>::a(); + | ^^^^^^^^^^^^^^^^ + +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:33:5 + | +LL | <Foo as Tr>::b(); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/asm/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr index 6bc38811f1b..4a50ec8d0d5 100644 --- a/tests/ui/asm/inline-syntax.arm.stderr +++ b/tests/ui/asm/inline-syntax.arm.stderr @@ -13,7 +13,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:38:15 + --> $DIR/inline-syntax.rs:35:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^ @@ -25,7 +25,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:42:15 + --> $DIR/inline-syntax.rs:39:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^ @@ -37,7 +37,7 @@ LL | .intel_syntax aaa noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:46:15 + --> $DIR/inline-syntax.rs:43:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^ @@ -49,7 +49,7 @@ LL | .att_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:50:15 + --> $DIR/inline-syntax.rs:47:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^ @@ -61,7 +61,7 @@ LL | .att_syntax bbb noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:54:15 + --> $DIR/inline-syntax.rs:51:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^ @@ -73,7 +73,7 @@ LL | .intel_syntax noprefix; nop | ^ error: unknown directive - --> $DIR/inline-syntax.rs:61:13 + --> $DIR/inline-syntax.rs:58:13 | LL | .intel_syntax noprefix | ^ diff --git a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr b/tests/ui/asm/inline-syntax.arm_llvm_18.stderr index 4926293bb88..ada3f4891d3 100644 --- a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr +++ b/tests/ui/asm/inline-syntax.arm_llvm_18.stderr @@ -15,7 +15,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:38:15 + --> $DIR/inline-syntax.rs:35:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^ @@ -27,7 +27,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:42:15 + --> $DIR/inline-syntax.rs:39:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^ @@ -39,7 +39,7 @@ LL | .intel_syntax aaa noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:46:15 + --> $DIR/inline-syntax.rs:43:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^ @@ -51,7 +51,7 @@ LL | .att_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:50:15 + --> $DIR/inline-syntax.rs:47:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^ @@ -63,7 +63,7 @@ LL | .att_syntax bbb noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:54:15 + --> $DIR/inline-syntax.rs:51:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^ @@ -75,7 +75,7 @@ LL | .intel_syntax noprefix; nop | ^ error: unknown directive - --> $DIR/inline-syntax.rs:61:13 + --> $DIR/inline-syntax.rs:58:13 | LL | .intel_syntax noprefix | ^ diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs index 9398a87df62..a8c6c71b805 100644 --- a/tests/ui/asm/inline-syntax.rs +++ b/tests/ui/asm/inline-syntax.rs @@ -2,14 +2,11 @@ //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu //[x86_64] check-pass //[x86_64] needs-llvm-components: x86 -//[x86_64_allowed] compile-flags: --target x86_64-unknown-linux-gnu -//[x86_64_allowed] check-pass -//[x86_64_allowed] needs-llvm-components: x86 //[arm] compile-flags: --target armv7-unknown-linux-gnueabihf //[arm] build-fail //[arm] needs-llvm-components: arm //[arm] ignore-llvm-version: 18 - 99 -// Newer LLVM produces extra error notes. +//Newer LLVM produces extra error notes. //[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf //[arm_llvm_18] build-fail //[arm_llvm_18] needs-llvm-components: arm diff --git a/tests/ui/asm/inline-syntax.x86_64.stderr b/tests/ui/asm/inline-syntax.x86_64.stderr index b54b3560447..66dc37f3089 100644 --- a/tests/ui/asm/inline-syntax.x86_64.stderr +++ b/tests/ui/asm/inline-syntax.x86_64.stderr @@ -1,5 +1,5 @@ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:70:14 + --> $DIR/inline-syntax.rs:67:14 | LL | global_asm!(".intel_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop"); = note: `#[warn(bad_asm_style)]` on by default warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:38:15 + --> $DIR/inline-syntax.rs:35:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:42:15 + --> $DIR/inline-syntax.rs:39:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - --> $DIR/inline-syntax.rs:46:15 + --> $DIR/inline-syntax.rs:43:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - --> $DIR/inline-syntax.rs:50:15 + --> $DIR/inline-syntax.rs:47:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:54:15 + --> $DIR/inline-syntax.rs:51:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:61:13 + --> $DIR/inline-syntax.rs:58:13 | LL | .intel_syntax noprefix | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/x86_64/evex512-implicit-feature.rs b/tests/ui/asm/x86_64/evex512-implicit-feature.rs new file mode 100644 index 00000000000..a15060857ec --- /dev/null +++ b/tests/ui/asm/x86_64/evex512-implicit-feature.rs @@ -0,0 +1,15 @@ +// build-pass +// only-x86_64 +// compile-flags: --crate-type=lib -C target-cpu=skylake + +#![feature(avx512_target_feature)] +#![feature(stdarch_x86_avx512)] + +use std::arch::x86_64::*; + +#[target_feature(enable = "avx512f")] +#[no_mangle] +pub unsafe fn test(res: *mut f64, p: *const f64) { + let arg = _mm512_load_pd(p); + _mm512_store_pd(res, _mm512_fmaddsub_pd(arg, arg, arg)); +} diff --git a/tests/ui/associated-consts/associated-const-in-trait.rs b/tests/ui/associated-consts/associated-const-in-trait.rs index cf5d5d859b6..4e8143d5795 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.rs +++ b/tests/ui/associated-consts/associated-const-in-trait.rs @@ -7,6 +7,7 @@ trait Trait { impl dyn Trait { //~^ ERROR the trait `Trait` cannot be made into an object [E0038] const fn n() -> usize { Self::N } + //~^ ERROR the trait `Trait` cannot be made into an object [E0038] } fn main() {} diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr index 59acd4820ae..88360cd2dd5 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.stderr +++ b/tests/ui/associated-consts/associated-const-in-trait.stderr @@ -13,6 +13,21 @@ LL | const N: usize; | ^ ...because it contains this associated `const` = help: consider moving `N` to another trait -error: aborting due to 1 previous error +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/associated-const-in-trait.rs:9:29 + | +LL | const fn n() -> usize { Self::N } + | ^^^^ `Trait` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/associated-const-in-trait.rs:4:11 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | const N: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `N` to another trait + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs index 6c6dae864f3..fb2169ab43f 100644 --- a/tests/ui/associated-consts/issue-105330.rs +++ b/tests/ui/associated-consts/issue-105330.rs @@ -10,10 +10,15 @@ impl TraitWAssocConst for impl Demo { //~ ERROR E0404 fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658 foo::<Demo>()(); + //~^ ERROR is not satisfied + //~| ERROR type mismatch + //~| ERROR expected function, found `()` } fn main<A: TraitWAssocConst<A=32>>() { //~^ ERROR E0658 //~| ERROR E0131 foo::<Demo>(); + //~^ ERROR type mismatch + //~| ERROR is not satisfied } diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index b4c021d0f4f..50ce69b3381 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -26,7 +26,7 @@ LL | fn foo<A: TraitWAssocConst<A=32>>() { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete - --> $DIR/issue-105330.rs:15:29 + --> $DIR/issue-105330.rs:18:29 | LL | fn main<A: TraitWAssocConst<A=32>>() { | ^^^^ @@ -44,12 +44,76 @@ LL | impl TraitWAssocConst for impl Demo { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/issue-105330.rs:15:8 + --> $DIR/issue-105330.rs:18:8 | LL | fn main<A: TraitWAssocConst<A=32>>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters -error: aborting due to 6 previous errors +error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied + --> $DIR/issue-105330.rs:12:11 + | +LL | foo::<Demo>()(); + | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` + | + = help: the trait `TraitWAssocConst` is implemented for `{type error}` +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:11 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() { + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` + +error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32` + --> $DIR/issue-105330.rs:12:11 + | +LL | foo::<Demo>()(); + | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A` + | + = note: expected constant `32` + found constant `<Demo as TraitWAssocConst>::A` +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:28 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() { + | ^^^^ required by this bound in `foo` + +error[E0618]: expected function, found `()` + --> $DIR/issue-105330.rs:12:5 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() { + | ----------------------------------- `foo::<Demo>` defined here returns `()` +LL | foo::<Demo>()(); + | ^^^^^^^^^^^^^-- + | | + | call expression requires function + +error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied + --> $DIR/issue-105330.rs:21:11 + | +LL | foo::<Demo>(); + | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` + | + = help: the trait `TraitWAssocConst` is implemented for `{type error}` +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:11 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() { + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` + +error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32` + --> $DIR/issue-105330.rs:21:11 + | +LL | foo::<Demo>(); + | ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A` + | + = note: expected constant `32` + found constant `<Demo as TraitWAssocConst>::A` +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:28 + | +LL | fn foo<A: TraitWAssocConst<A=32>>() { + | ^^^^ required by this bound in `foo` + +error: aborting due to 11 previous errors -Some errors have detailed explanations: E0131, E0404, E0562, E0658. +Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658. For more information about an error, try `rustc --explain E0131`. diff --git a/tests/ui/associated-inherent-types/issue-109299.rs b/tests/ui/associated-inherent-types/issue-109299.rs index 84e4f9e7252..b6c010c34e4 100644 --- a/tests/ui/associated-inherent-types/issue-109299.rs +++ b/tests/ui/associated-inherent-types/issue-109299.rs @@ -8,5 +8,6 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d` } fn test(_: Lexer::Cursor) {} +//~^ ERROR: lifetime may not live long enough fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109299.stderr b/tests/ui/associated-inherent-types/issue-109299.stderr index 1e11c0e8c2a..f108a52b92c 100644 --- a/tests/ui/associated-inherent-types/issue-109299.stderr +++ b/tests/ui/associated-inherent-types/issue-109299.stderr @@ -6,6 +6,15 @@ LL | impl Lexer<'d> { | | | help: consider introducing lifetime `'d` here: `<'d>` -error: aborting due to 1 previous error +error: lifetime may not live long enough + --> $DIR/issue-109299.rs:10:1 + | +LL | fn test(_: Lexer::Cursor) {} + | ^^^^^^^^-^^^^^^^^^^^^^^^^ + | | | + | | has type `Lexer<'1>::Cursor` + | requires that `'1` must outlive `'static` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs index 0b5ba7d1fb5..46dd4590141 100644 --- a/tests/ui/associated-inherent-types/issue-109789.rs +++ b/tests/ui/associated-inherent-types/issue-109789.rs @@ -18,5 +18,7 @@ impl Other for u32 {} fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} //~^ ERROR mismatched types //~| ERROR mismatched types +//~| ERROR higher-ranked subtype error +//~| ERROR higher-ranked subtype error fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr index e844f6795e6..c6ea6c5541d 100644 --- a/tests/ui/associated-inherent-types/issue-109789.stderr +++ b/tests/ui/associated-inherent-types/issue-109789.stderr @@ -17,6 +17,20 @@ LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} found struct `Foo<for<'a> fn(&'a ())>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 2 previous errors +error: higher-ranked subtype error + --> $DIR/issue-109789.rs:18:1 + | +LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-109789.rs:18:1 + | +LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/regionck-2.rs b/tests/ui/associated-inherent-types/regionck-2.rs index 7a0b8b08300..573dd359bf2 100644 --- a/tests/ui/associated-inherent-types/regionck-2.rs +++ b/tests/ui/associated-inherent-types/regionck-2.rs @@ -10,5 +10,6 @@ impl Lexer<'static> { } fn test(_: Lexer::Cursor) {} //~ ERROR mismatched types +//~^ ERROR: lifetime may not live long enough fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-2.stderr b/tests/ui/associated-inherent-types/regionck-2.stderr index 4c68a591240..82f5c6a72c0 100644 --- a/tests/ui/associated-inherent-types/regionck-2.stderr +++ b/tests/ui/associated-inherent-types/regionck-2.stderr @@ -13,6 +13,15 @@ LL | fn test(_: Lexer::Cursor) {} | ^^^^^ = note: ...does not necessarily outlive the static lifetime -error: aborting due to 1 previous error +error: lifetime may not live long enough + --> $DIR/regionck-2.rs:12:1 + | +LL | fn test(_: Lexer::Cursor) {} + | ^^^^^^^^-^^^^^^^^^^^^^^^^ + | | | + | | has type `Lexer<'1>::Cursor` + | requires that `'1` must outlive `'static` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed index adfba994f32..e713db025e8 100644 --- a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed +++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed @@ -8,9 +8,9 @@ trait Get { } trait Other { - fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {} + fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get, Self: Get {} //~^ ERROR the trait bound `Self: Get` is not satisfied + //~| ERROR the trait bound `Self: Get` is not satisfied } -fn main() { -} +fn main() {} diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.rs b/tests/ui/associated-types/associated-types-for-unimpl-trait.rs index 50478171d86..c5d7ba3a755 100644 --- a/tests/ui/associated-types/associated-types-for-unimpl-trait.rs +++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.rs @@ -8,9 +8,9 @@ trait Get { } trait Other { - fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {} + fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {} //~^ ERROR the trait bound `Self: Get` is not satisfied + //~| ERROR the trait bound `Self: Get` is not satisfied } -fn main() { -} +fn main() {} diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr index 27014fa53d8..4cba3990049 100644 --- a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr +++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr @@ -1,14 +1,25 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-for-unimpl-trait.rs:11:40 + --> $DIR/associated-types-for-unimpl-trait.rs:11:41 | -LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {} - | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` +LL | fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {} + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | -LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {} - | +++++++++++++++ +LL | fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get {} + | +++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `Self: Get` is not satisfied + --> $DIR/associated-types-for-unimpl-trait.rs:11:81 + | +LL | fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {} + | ^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get {} + | +++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/associated-types-no-suitable-bound.rs b/tests/ui/associated-types/associated-types-no-suitable-bound.rs index d42460a4c07..7019c476237 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-bound.rs +++ b/tests/ui/associated-types/associated-types-no-suitable-bound.rs @@ -10,7 +10,7 @@ struct Struct { impl Struct { fn uhoh<T>(foo: <T as Get>::Value) {} //~^ ERROR the trait bound `T: Get` is not satisfied + //~| ERROR the trait bound `T: Get` is not satisfied } -fn main() { -} +fn main() {} diff --git a/tests/ui/associated-types/associated-types-no-suitable-bound.stderr b/tests/ui/associated-types/associated-types-no-suitable-bound.stderr index fe1be6be015..9713051d973 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-bound.stderr +++ b/tests/ui/associated-types/associated-types-no-suitable-bound.stderr @@ -9,6 +9,17 @@ help: consider restricting type parameter `T` LL | fn uhoh<T: Get>(foo: <T as Get>::Value) {} | +++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `T: Get` is not satisfied + --> $DIR/associated-types-no-suitable-bound.rs:11:40 + | +LL | fn uhoh<T>(foo: <T as Get>::Value) {} + | ^^ the trait `Get` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn uhoh<T: Get>(foo: <T as Get>::Value) {} + | +++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs index 17dfa1773dd..5dc1ac88c8a 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs +++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.rs @@ -16,6 +16,7 @@ trait Get { trait Other { fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {} //~^ ERROR the trait bound `Self: Get` is not satisfied + //~| ERROR the trait bound `Self: Get` is not satisfied } fn main() { } diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr index b586053a5bc..c5dcfc00925 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr +++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr @@ -9,6 +9,17 @@ help: consider further restricting `Self` LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {} | +++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `Self: Get` is not satisfied + --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:62 + | +LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {} + | ^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {} + | +++++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs b/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs index cc0101d63cf..144812fa4d1 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs +++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.rs @@ -16,12 +16,14 @@ trait Get { trait Other { fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {} //~^ ERROR the trait bound `Self: Get` is not satisfied + //~| ERROR the trait bound `Self: Get` is not satisfied } impl<T:Get> Other for T { fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {} //~^ ERROR the trait bound `(T, U): Get` is not satisfied //~| ERROR the trait bound `(T, U): Get` is not satisfied + //~| ERROR the trait bound `(T, U): Get` is not satisfied } fn main() { } diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr index 5443699eb01..46cebda078e 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(T, U): Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:22:5 + --> $DIR/associated-types-no-suitable-supertrait.rs:23:5 | LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` @@ -11,7 +11,7 @@ LL | trait Get { | ^^^^^^^^^ error[E0277]: the trait bound `(T, U): Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:22:40 + --> $DIR/associated-types-no-suitable-supertrait.rs:23:40 | LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` @@ -33,6 +33,29 @@ help: consider further restricting `Self` LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {} | +++++++++++++++ -error: aborting due to 3 previous errors +error[E0277]: the trait bound `Self: Get` is not satisfied + --> $DIR/associated-types-no-suitable-supertrait.rs:17:62 + | +LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {} + | ^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {} + | +++++++++++++++ + +error[E0277]: the trait bound `(T, U): Get` is not satisfied + --> $DIR/associated-types-no-suitable-supertrait.rs:23:64 + | +LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {} + | ^^ the trait `Get` is not implemented for `(T, U)` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-types-no-suitable-supertrait.rs:12:1 + | +LL | trait Get { + | ^^^^^^^^^ + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-1.rs b/tests/ui/associated-types/hr-associated-type-bound-1.rs index db414164e16..37c1a47fcd2 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-1.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-1.rs @@ -15,4 +15,5 @@ impl X<'_> for i32 { fn main() { 1i32.f("abc"); + //~^ ERROR the trait bound `str: Clone` } diff --git a/tests/ui/associated-types/hr-associated-type-bound-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-1.stderr index 01005b6b22d..8830048ed4e 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-1.stderr @@ -14,6 +14,22 @@ LL | where LL | for<'b> <Self as X<'b>>::U: Clone, | ^^^^^ required by this bound in `X` -error: aborting due to 1 previous error +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-1.rs:17:10 + | +LL | 1i32.f("abc"); + | ^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `X::f` + --> $DIR/hr-associated-type-bound-1.rs:3:33 + | +LL | for<'b> <Self as X<'b>>::U: Clone, + | ^^^^^ required by this bound in `X::f` +... +LL | fn f(&self, x: &Self::U) { + | - required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.rs b/tests/ui/associated-types/hr-associated-type-bound-object.rs index e19c918c3df..fec253f9289 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-object.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-object.rs @@ -7,6 +7,9 @@ where fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) { //~^ ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied <<T as X<'_>>::U>::clone(x); + //~^ ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied + //~| ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied + //~| ERROR the trait bound `<T as X<'_>>::U: Clone` is not satisfied } pub fn main() { diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr index 87a048d0a13..322d6e7b947 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr @@ -17,6 +17,55 @@ help: consider further restricting the associated type LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone { | ++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-object.rs:9:7 + | +LL | <<T as X<'_>>::U>::clone(x); + | ^ the trait `for<'b> Clone` is not implemented for `<T as X<'b>>::U` + | +note: required by a bound in `X::U` + --> $DIR/hr-associated-type-bound-object.rs:3:33 + | +LL | for<'b> <Self as X<'b>>::U: Clone, + | ^^^^^ required by this bound in `X::U` +LL | { +LL | type U: ?Sized; + | - required by a bound in this associated type +help: consider further restricting the associated type + | +LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone { + | ++++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `<T as X<'_>>::U: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-object.rs:9:6 + | +LL | <<T as X<'_>>::U>::clone(x); + | ^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<T as X<'_>>::U` + | +help: consider further restricting the associated type + | +LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where <T as X<'_>>::U: Clone { + | ++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-object.rs:9:5 + | +LL | <<T as X<'_>>::U>::clone(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Clone` is not implemented for `<T as X<'b>>::U` + | +note: required by a bound in `X` + --> $DIR/hr-associated-type-bound-object.rs:3:33 + | +LL | trait X<'a> + | - required by a bound in this trait +LL | where +LL | for<'b> <Self as X<'b>>::U: Clone, + | ^^^^^ required by this bound in `X` +help: consider further restricting the associated type + | +LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone { + | ++++++++++++++++++++++++++++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-1.rs b/tests/ui/associated-types/hr-associated-type-bound-param-1.rs index bbeeb145d1f..763d48252f7 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-1.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-1.rs @@ -17,4 +17,5 @@ impl<'a> Y<'a, u8> for u8 { fn main() { 1u8.g("abc"); + //~^ ERROR the trait bound `str: Clone` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr index 0031d205b84..ad6d3e17684 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr @@ -14,6 +14,22 @@ LL | trait Y<'a, T: ?Sized> LL | for<'b> <Self as Y<'b, T>>::V: Clone, | ^^^^^ required by this bound in `Y` -error: aborting due to 1 previous error +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-1.rs:19:9 + | +LL | 1u8.g("abc"); + | ^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `Y::g` + --> $DIR/hr-associated-type-bound-param-1.rs:4:36 + | +LL | for<'b> <Self as Y<'b, T>>::V: Clone, + | ^^^^^ required by this bound in `Y::g` +... +LL | fn g(&self, x: &Self::V) { + | - required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.rs b/tests/ui/associated-types/hr-associated-type-bound-param-2.rs index f74c5a8590d..b1a6fe87159 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-2.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.rs @@ -8,6 +8,8 @@ where type W: ?Sized; fn h(&self, x: &T::W) { <T::W>::clone(x); + //~^ the trait bound `str: Clone` is not satisfied + //~| the trait bound `str: Clone` is not satisfied } } @@ -18,4 +20,5 @@ impl<'a> Z<'a, u16> for u16 { fn main() { 1u16.h("abc"); + //~^ ERROR Clone` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr index bb484da6a77..6a5729e7784 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr @@ -15,7 +15,7 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone, | ^^^^^ required by this bound in `Z` error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/hr-associated-type-bound-param-2.rs:15:14 + --> $DIR/hr-associated-type-bound-param-2.rs:17:14 | LL | type W = str; | ^^^ the trait `Clone` is not implemented for `str`, which is required by `for<'b> <u16 as Z<'b, u16>>::W: Clone` @@ -47,6 +47,54 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone, | ^^^^^ required by this bound in `Z` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-2.rs:10:10 + | +LL | <T::W>::clone(x); + | ^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `Z::W` + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 + | +LL | for<'b> <T as Z<'b, u16>>::W: Clone, + | ^^^^^ required by this bound in `Z::W` +LL | { +LL | type W: ?Sized; + | - required by a bound in this associated type + +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-2.rs:10:9 + | +LL | <T::W>::clone(x); + | ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `Z` + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 + | +LL | trait Z<'a, T: ?Sized> + | - required by a bound in this trait +... +LL | for<'b> <T as Z<'b, u16>>::W: Clone, + | ^^^^^ required by this bound in `Z` + +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-2.rs:22:10 + | +LL | 1u16.h("abc"); + | ^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `Z::h` + --> $DIR/hr-associated-type-bound-param-2.rs:6:35 + | +LL | for<'b> <T as Z<'b, u16>>::W: Clone, + | ^^^^^ required by this bound in `Z::h` +... +LL | fn h(&self, x: &T::W) { + | - required by a bound in this associated function + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.rs b/tests/ui/associated-types/hr-associated-type-bound-param-3.rs index fda7d811185..8b4c84aa349 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-3.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.rs @@ -16,4 +16,5 @@ impl<S, T> X<'_, (T,)> for (S,) { pub fn main() { <(i32,) as X<(i32,)>>::f("abc"); + //~^ ERROR the trait bound `str: Clone` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr index f4d2f43a9b4..70e030f2d1c 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr @@ -14,6 +14,22 @@ LL | trait X<'a, T> LL | for<'b> <T as X<'b, T>>::U: Clone, | ^^^^^ required by this bound in `X` -error: aborting due to 1 previous error +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-3.rs:18:5 + | +LL | <(i32,) as X<(i32,)>>::f("abc"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `X::f` + --> $DIR/hr-associated-type-bound-param-3.rs:4:33 + | +LL | for<'b> <T as X<'b, T>>::U: Clone, + | ^^^^^ required by this bound in `X::f` +... +LL | fn f(x: &<T as X<'_, T>>::U) { + | - required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.rs b/tests/ui/associated-types/hr-associated-type-bound-param-4.rs index 20c8157ed97..b75bd896cc8 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-4.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.rs @@ -16,4 +16,5 @@ impl<S, T> X<'_, T> for (S,) { pub fn main() { <(i32,) as X<i32>>::f("abc"); + //~^ ERROR the trait bound `str: Clone` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr index 7f03d155391..cba12afd674 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr @@ -14,6 +14,22 @@ LL | trait X<'a, T> LL | for<'b> <(T,) as X<'b, T>>::U: Clone, | ^^^^^ required by this bound in `X` -error: aborting due to 1 previous error +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-4.rs:18:5 + | +LL | <(i32,) as X<i32>>::f("abc"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `X::f` + --> $DIR/hr-associated-type-bound-param-4.rs:4:36 + | +LL | for<'b> <(T,) as X<'b, T>>::U: Clone, + | ^^^^^ required by this bound in `X::f` +... +LL | fn f(x: &<(T,) as X<'_, T>>::U) { + | - required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.rs b/tests/ui/associated-types/hr-associated-type-bound-param-5.rs index d7f3151a502..672ade9aa5e 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-5.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.rs @@ -34,4 +34,5 @@ impl<S, T> X<'_, Box<T>> for S { pub fn main() { <i32 as X<Box<i32>>>::f("abc"); + //~^ ERROR the trait bound `str: Clone` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr index fbbc2f45772..ac96187749a 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr @@ -30,6 +30,22 @@ LL | trait X<'a, T: Cycle + for<'b> X<'b, T>> LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone, | ^^^^^ required by this bound in `X` -error: aborting due to 2 previous errors +error[E0277]: the trait bound `str: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-param-5.rs:36:5 + | +LL | <i32 as X<Box<i32>>>::f("abc"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | + = help: the trait `Clone` is implemented for `String` +note: required by a bound in `X::f` + --> $DIR/hr-associated-type-bound-param-5.rs:15:33 + | +LL | for<'b> <T as X<'b, T>>::U: Clone, + | ^^^^^ required by this bound in `X::f` +... +LL | fn f(x: &<T as X<'_, T>>::U) { + | - required by a bound in this associated function + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs index 482047b0959..f6639904ab3 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs +++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs @@ -16,4 +16,6 @@ impl<S, T> X<'_, T> for (S,) { pub fn main() { <(i32,) as X<i32>>::f("abc"); + //~^ ERROR the trait bound `for<'b> i32: X<'b, i32>` is not satisfied + //~| ERROR the trait bound `i32: X<'_, i32>` is not satisfied } diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr index da988f4cfc1..cba83120fdc 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr @@ -9,6 +9,22 @@ help: consider restricting type parameter `T` LL | impl<S, T: for<'b> X<'b, T>> X<'_, T> for (S,) { | ++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied + --> $DIR/hr-associated-type-bound-param-6.rs:18:5 + | +LL | <(i32,) as X<i32>>::f("abc"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> X<'b, i32>` is not implemented for `i32` + | + = help: the trait `X<'_, T>` is implemented for `(S,)` + +error[E0277]: the trait bound `i32: X<'_, i32>` is not satisfied + --> $DIR/hr-associated-type-bound-param-6.rs:18:27 + | +LL | <(i32,) as X<i32>>::f("abc"); + | ^^^^^ the trait `X<'_, i32>` is not implemented for `i32` + | + = help: the trait `X<'_, T>` is implemented for `(S,)` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.rs b/tests/ui/associated-types/hr-associated-type-projection-1.rs index 951dd9e97d2..3df3f68ab1e 100644 --- a/tests/ui/associated-types/hr-associated-type-projection-1.rs +++ b/tests/ui/associated-types/hr-associated-type-projection-1.rs @@ -17,4 +17,5 @@ impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T { pub fn main() { <&'static str>::bug(&""); + //~^ type mismatch resolving `<&str as Deref>::Target == &str` } diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr index 59b52521ef8..65221718ee6 100644 --- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr @@ -21,6 +21,21 @@ help: consider further restricting this bound LL | impl<T: Copy + std::ops::Deref<Target = T>> UnsafeCopy<'_, T> for T { | ++++++++++++ -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `<&str as Deref>::Target == &str` + --> $DIR/hr-associated-type-projection-1.rs:19:6 + | +LL | <&'static str>::bug(&""); + | ^^^^^^^^^^^^ expected `&str`, found `str` + | +note: required by a bound in `UnsafeCopy::bug` + --> $DIR/hr-associated-type-projection-1.rs:3:64 + | +LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>, + | ^^^^^^^^^^ required by this bound in `UnsafeCopy::bug` +... +LL | fn bug(item: &Self::Item) -> () { + | --- required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/issue-20005.rs b/tests/ui/associated-types/issue-20005.rs index 36350bff100..e6e83d92061 100644 --- a/tests/ui/associated-types/issue-20005.rs +++ b/tests/ui/associated-types/issue-20005.rs @@ -6,9 +6,9 @@ trait From<Src> { trait To { fn to<Dst>( - self + self //~ ERROR the size for values of type ) -> <Dst as From<Self>>::Result where Dst: From<Self> { //~ ERROR the size for values of type - From::from(self) + From::from(self) //~ ERROR the size for values of type } } diff --git a/tests/ui/associated-types/issue-20005.stderr b/tests/ui/associated-types/issue-20005.stderr index f2983383fa6..1600227c82d 100644 --- a/tests/ui/associated-types/issue-20005.stderr +++ b/tests/ui/associated-types/issue-20005.stderr @@ -18,6 +18,42 @@ help: consider relaxing the implicit `Sized` restriction LL | trait From<Src: ?Sized> { | ++++++++ -error: aborting due to 1 previous error +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/issue-20005.rs:9:9 + | +LL | self + | ^^^^ doesn't have a size known at compile-time + | + = help: unsized fn params are gated as an unstable feature +help: consider further restricting `Self` + | +LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized { + | +++++++++++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | &self + | + + +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/issue-20005.rs:11:9 + | +LL | From::from(self) + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | +note: required by an implicit `Sized` bound in `From` + --> $DIR/issue-20005.rs:1:12 + | +LL | trait From<Src> { + | ^^^ required by the implicit `Sized` requirement on this type parameter in `From` +help: consider further restricting `Self` + | +LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized { + | +++++++++++++ +help: consider relaxing the implicit `Sized` restriction + | +LL | trait From<Src: ?Sized> { + | ++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-38821.rs b/tests/ui/associated-types/issue-38821.rs index 34c35d7acf1..c9be1369f16 100644 --- a/tests/ui/associated-types/issue-38821.rs +++ b/tests/ui/associated-types/issue-38821.rs @@ -35,6 +35,8 @@ pub trait Column: Expression {} //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied pub enum ColumnInsertValue<Col, Expr> where //~^ ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index 50d622c89bb..acf6bb2810c 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -18,7 +18,7 @@ LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Co | +++++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:1 + --> $DIR/issue-38821.rs:40:1 | LL | pub enum ColumnInsertValue<Col, Expr> where | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable` @@ -36,7 +36,7 @@ LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Co | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:1 + --> $DIR/issue-38821.rs:40:1 | LL | / pub enum ColumnInsertValue<Col, Expr> where LL | | @@ -283,6 +283,38 @@ LL | impl<T: NotNull> IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 16 previous errors +error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied + --> $DIR/issue-38821.rs:23:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable` + | +note: required for `<Col as Expression>::SqlType` to implement `IntoNullable` + --> $DIR/issue-38821.rs:9:18 + | +LL | impl<T: NotNull> IntoNullable for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied + --> $DIR/issue-38821.rs:23:23 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable` + | +note: required for `<Col as Expression>::SqlType` to implement `IntoNullable` + --> $DIR/issue-38821.rs:9:18 + | +LL | impl<T: NotNull> IntoNullable for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-59324.rs b/tests/ui/associated-types/issue-59324.rs index 551f13ee178..7421e08c898 100644 --- a/tests/ui/associated-types/issue-59324.rs +++ b/tests/ui/associated-types/issue-59324.rs @@ -22,5 +22,7 @@ pub trait ThriftService<Bug: NotFoo>: fn with_factory<H>(factory: dyn ThriftService<()>) {} //~^ ERROR the trait bound `(): Foo` is not satisfied +//~| ERROR the trait bound `(): Foo` is not satisfied +//~| ERROR cannot be known at compilation time fn main() {} diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index 266e22d4726..f50d86580f8 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -66,6 +66,35 @@ help: consider further restricting this bound LL | pub trait ThriftService<Bug: NotFoo + Foo>: | +++++ -error: aborting due to 5 previous errors +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/issue-59324.rs:23:52 + | +LL | fn with_factory<H>(factory: dyn ThriftService<()>) {} + | ^^ the trait `Foo` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-59324.rs:3:1 + | +LL | pub trait Foo: NotFoo { + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time + --> $DIR/issue-59324.rs:23:20 + | +LL | fn with_factory<H>(factory: dyn ThriftService<()>) {} + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn ThriftService<(), AssocType = _> + 'static)` + = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn with_factory<H>(factory: impl ThriftService<()>) {} + | ~~~~ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn with_factory<H>(factory: &dyn ThriftService<()>) {} + | + + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/auto-traits/issue-83857-ub.rs b/tests/ui/auto-traits/issue-83857-ub.rs index 626e60c37f6..f9b47d2b0c6 100644 --- a/tests/ui/auto-traits/issue-83857-ub.rs +++ b/tests/ui/auto-traits/issue-83857-ub.rs @@ -21,7 +21,9 @@ impl WithAssoc for Foo<u32, ()> { fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) { //~^ ERROR `Foo<T, U>` cannot be sent between threads safely + //~| ERROR `Foo<T, U>` cannot be sent between threads safely f(foo(v)); + //~^ ERROR `Foo<T, U>` cannot be sent between threads safely } fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output { diff --git a/tests/ui/auto-traits/issue-83857-ub.stderr b/tests/ui/auto-traits/issue-83857-ub.stderr index 97f1a603208..6372bdfe762 100644 --- a/tests/ui/auto-traits/issue-83857-ub.stderr +++ b/tests/ui/auto-traits/issue-83857-ub.stderr @@ -17,6 +17,50 @@ help: consider introducing a `where` clause, but there might be an alternative b LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send { | +++++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: `Foo<T, U>` cannot be sent between threads safely + --> $DIR/issue-83857-ub.rs:22:80 + | +LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) { + | ________________________________________________________________________________^ +LL | | +LL | | +LL | | f(foo(v)); +LL | | +LL | | } + | |_^ `Foo<T, U>` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `Foo<T, U>`, which is required by `Foo<T, U>: WithAssoc` +note: required for `Foo<T, U>` to implement `WithAssoc` + --> $DIR/issue-83857-ub.rs:15:15 + | +LL | impl<T: Send> WithAssoc for T { + | ---- ^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send { + | +++++++++++++++++++++ + +error[E0277]: `Foo<T, U>` cannot be sent between threads safely + --> $DIR/issue-83857-ub.rs:25:11 + | +LL | f(foo(v)); + | --- ^ `Foo<T, U>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `Foo<T, U>` +note: required by a bound in `foo` + --> $DIR/issue-83857-ub.rs:29:11 + | +LL | fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output { + | ^^^^ required by this bound in `foo` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send { + | +++++++++++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.fixed b/tests/ui/borrowck/copy-suggestion-region-vid.fixed new file mode 100644 index 00000000000..ec16469757a --- /dev/null +++ b/tests/ui/borrowck/copy-suggestion-region-vid.fixed @@ -0,0 +1,18 @@ +// run-rustfix +pub struct DataStruct(); + +pub struct HelperStruct<'n> { + pub helpers: [Vec<&'n i64>; 2], + pub is_empty: bool, +} + +impl DataStruct { + pub fn f(&self) -> HelperStruct { + let helpers = [vec![], vec![]]; + + HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() } + //~^ ERROR borrow of moved value + } +} + +fn main() {} diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.rs b/tests/ui/borrowck/copy-suggestion-region-vid.rs index 3c5b887ce17..f95c6b03e01 100644 --- a/tests/ui/borrowck/copy-suggestion-region-vid.rs +++ b/tests/ui/borrowck/copy-suggestion-region-vid.rs @@ -1,4 +1,4 @@ -//@run-rustfix +// run-rustfix pub struct DataStruct(); pub struct HelperStruct<'n> { diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs index 6fba87b3197..05b51e969a0 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs +++ b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.rs @@ -14,4 +14,5 @@ fn main() { let (tx, rx) = channel(); 1193182.foo(tx); assert_eq!(rx.recv(), 1193182); + //~^ ERROR: mismatched types } diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr index d0102635315..22e72b6245c 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-self-type.stderr @@ -17,6 +17,20 @@ help: consider adding an explicit lifetime bound LL | impl <T: Sync + 'static> Foo for T { } | +++++++++ -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/builtin-superkinds-self-type.rs:16:27 + | +LL | assert_eq!(rx.recv(), 1193182); + | ^^^^^^^ expected `Result<{integer}, RecvError>`, found integer + | + = note: expected enum `Result<{integer}, RecvError>` + found type `{integer}` +help: try wrapping the expression in `Ok` + | +LL | assert_eq!(rx.recv(), Ok(1193182)); + | +++ + + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors have detailed explanations: E0308, E0310. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr index e2a2db7c3f0..c0f222b016d 100644 --- a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr +++ b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr @@ -9,8 +9,8 @@ LL | | LL | | }); | |______^ expected due to this | - = note: expected closure signature `fn(_, _) -> _` - found closure signature `fn(u32, i32) -> _` + = note: expected closure signature `fn(_, u32) -> _` + found closure signature `fn(_, i32) -> _` note: required by a bound in `with_closure` --> $DIR/expect-infer-var-appearing-twice.rs:2:14 | diff --git a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs index 039cf3e0464..84aaa5f85e4 100644 --- a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs +++ b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs @@ -5,6 +5,7 @@ struct X<F> where F: FnOnce() + 'static + Send { fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static { //~^ ERROR `F` cannot be sent between threads safely return X { field: blk }; + //~^ ERROR `F` cannot be sent between threads safely } fn main() { diff --git a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr index e98f05b470e..8157590bd9e 100644 --- a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr +++ b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr @@ -14,6 +14,22 @@ help: consider further restricting this bound LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static + std::marker::Send { | +++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: `F` cannot be sent between threads safely + --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:7:23 + | +LL | return X { field: blk }; + | ^^^ `F` cannot be sent between threads safely + | +note: required by a bound in `X` + --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:1:43 + | +LL | struct X<F> where F: FnOnce() + 'static + Send { + | ^^^^ required by this bound in `X` +help: consider further restricting this bound + | +LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static + std::marker::Send { + | +++++++++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-10682.rs b/tests/ui/closures/issue-10682.rs index 72e4559d31a..72e4559d31a 100644 --- a/tests/ui/issues/issue-10682.rs +++ b/tests/ui/closures/issue-10682.rs diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs new file mode 100644 index 00000000000..e45db18e407 --- /dev/null +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -0,0 +1,28 @@ +// build-fail +//~^ ERROR overflow evaluating the requirement + +#![recursion_limit = "32"] + +fn quicksort<It: Clone + Iterator<Item = T>, I: IntoIterator<IntoIter = It>, T: Ord>( + i: I, +) -> Vec<T> { + let mut i = i.into_iter(); + + match i.next() { + Some(x) => { + let less = i.clone().filter(|y| y < &x); + let greater = i.filter(|y| &x <= y); + + let mut v = quicksort(less); + let u = quicksort(greater); + v.push(x); + v.extend(u); + v + } + None => vec![], + } +} + +fn main() { + println!("{:?}", quicksort([5i32, 1, 6, 3, 6, 1, 9, 0, -1, 6, 8])); +} diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr new file mode 100644 index 00000000000..f7a3e2df3db --- /dev/null +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) + = note: required for `Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` + = note: 31 redundant requirements hidden + = note: required for `Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` + = note: required for `Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `IntoIterator` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs index cdec81271d0..8426748fd52 100644 --- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs +++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs @@ -23,6 +23,7 @@ impl MyTrait<MyType> for MyType { //~^ ERROR E0119 fn get(&self) -> usize { (*self).clone() } //~^ ERROR incompatible type + //~| ERROR mismatched types } fn main() { } diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr index 471dfe1cae7..0653009409c 100644 --- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr +++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr @@ -24,7 +24,15 @@ LL | fn get(&self) -> T; = note: expected signature `fn(&MyType) -> MyType` found signature `fn(&MyType) -> usize` -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:30 + | +LL | fn get(&self) -> usize { (*self).clone() } + | ----- ^^^^^^^^^^^^^^^ expected `usize`, found `MyType` + | | + | expected `usize` because of return type + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0053, E0119. +Some errors have detailed explanations: E0053, E0119, E0308. For more information about an error, try `rustc --explain E0053`. diff --git a/tests/ui/coherence/coherence-tuple-conflict.rs b/tests/ui/coherence/coherence-tuple-conflict.rs index 8cc82972668..8dd09598c30 100644 --- a/tests/ui/coherence/coherence-tuple-conflict.rs +++ b/tests/ui/coherence/coherence-tuple-conflict.rs @@ -15,6 +15,7 @@ impl<T> MyTrait for (T,T) { impl<A,B> MyTrait for (A,B) { //~^ ERROR E0119 fn get(&self) -> usize { self.dummy } + //~^ ERROR: no field `dummy` } fn main() { } diff --git a/tests/ui/coherence/coherence-tuple-conflict.stderr b/tests/ui/coherence/coherence-tuple-conflict.stderr index 4e02c0eb43c..95f9a1a8841 100644 --- a/tests/ui/coherence/coherence-tuple-conflict.stderr +++ b/tests/ui/coherence/coherence-tuple-conflict.stderr @@ -7,6 +7,13 @@ LL | impl<T> MyTrait for (T,T) { LL | impl<A,B> MyTrait for (A,B) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_, _)` -error: aborting due to 1 previous error +error[E0609]: no field `dummy` on type `&(A, B)` + --> $DIR/coherence-tuple-conflict.rs:17:35 + | +LL | fn get(&self) -> usize { self.dummy } + | ^^^^^ unknown field + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0119, E0609. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index f64e8b39798..65be4a9c884 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -20,6 +20,13 @@ LL | | for<'a> *const T: ToUnit<'a>, | = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details -error: aborting due to 1 previous error +error[E0284]: type annotations needed: cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize` + --> $DIR/associated-type.rs:44:59 + | +LL | foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize); + | ^^^^^^ cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0119, E0284. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs index 227b6684785..3df8fe10a83 100644 --- a/tests/ui/coherence/occurs-check/associated-type.rs +++ b/tests/ui/coherence/occurs-check/associated-type.rs @@ -42,4 +42,5 @@ fn foo<T: Overlap<U>, U>(x: T::Assoc) -> T::Assoc { fn main() { foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize); + //[next]~^ ERROR: cannot satisfy } diff --git a/tests/ui/const-generics/const-argument-if-length.full.stderr b/tests/ui/const-generics/const-argument-if-length.full.stderr index 315b0f0a064..db3d88392bd 100644 --- a/tests/ui/const-generics/const-argument-if-length.full.stderr +++ b/tests/ui/const-generics/const-argument-if-length.full.stderr @@ -1,5 +1,5 @@ error: unconstrained generic constant - --> $DIR/const-argument-if-length.rs:17:10 + --> $DIR/const-argument-if-length.rs:18:10 | LL | pad: [u8; is_zst::<T>()], | ^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | pad: [u8; is_zst::<T>()], = help: try adding a `where` bound using this expression: `where [(); is_zst::<T>()]:` error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/const-argument-if-length.rs:15:12 + --> $DIR/const-argument-if-length.rs:16:12 | LL | pub struct AtLeastByte<T: ?Sized> { | - this type parameter needs to be `Sized` @@ -30,6 +30,22 @@ help: the `Box` type always has a statically known size and allocates its conten LL | value: Box<T>, | ++++ + -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/const-argument-if-length.rs:7:28 + | +LL | pub const fn is_zst<T: ?Sized>() -> usize { + | - this type parameter needs to be `Sized` +LL | if std::mem::size_of::<T>() == 0 { + | ^ doesn't have a size known at compile-time + | +note: required by an implicit `Sized` bound in `std::mem::size_of` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - pub const fn is_zst<T: ?Sized>() -> usize { +LL + pub const fn is_zst<T>() -> usize { + | + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/const-argument-if-length.min.stderr b/tests/ui/const-generics/const-argument-if-length.min.stderr index b9d9bcc9270..fdc3f584476 100644 --- a/tests/ui/const-generics/const-argument-if-length.min.stderr +++ b/tests/ui/const-generics/const-argument-if-length.min.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/const-argument-if-length.rs:17:24 + --> $DIR/const-argument-if-length.rs:18:24 | LL | pad: [u8; is_zst::<T>()], | ^ cannot perform const operation using `T` @@ -8,7 +8,7 @@ LL | pad: [u8; is_zst::<T>()], = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/const-argument-if-length.rs:15:12 + --> $DIR/const-argument-if-length.rs:16:12 | LL | pub struct AtLeastByte<T: ?Sized> { | - this type parameter needs to be `Sized` @@ -31,6 +31,22 @@ help: the `Box` type always has a statically known size and allocates its conten LL | value: Box<T>, | ++++ + -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/const-argument-if-length.rs:7:28 + | +LL | pub const fn is_zst<T: ?Sized>() -> usize { + | - this type parameter needs to be `Sized` +LL | if std::mem::size_of::<T>() == 0 { + | ^ doesn't have a size known at compile-time + | +note: required by an implicit `Sized` bound in `std::mem::size_of` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - pub const fn is_zst<T: ?Sized>() -> usize { +LL + pub const fn is_zst<T>() -> usize { + | + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/const-argument-if-length.rs b/tests/ui/const-generics/const-argument-if-length.rs index db1eafca2c7..c5ff86fbfb7 100644 --- a/tests/ui/const-generics/const-argument-if-length.rs +++ b/tests/ui/const-generics/const-argument-if-length.rs @@ -5,6 +5,7 @@ pub const fn is_zst<T: ?Sized>() -> usize { if std::mem::size_of::<T>() == 0 { + //~^ ERROR the size for values of type `T` cannot be known at compilation time 1 } else { 0 diff --git a/tests/ui/const-generics/fn-const-param-infer.full.stderr b/tests/ui/const-generics/fn-const-param-infer.full.stderr index 48d4a45345a..753558636e1 100644 --- a/tests/ui/const-generics/fn-const-param-infer.full.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.full.stderr @@ -4,6 +4,27 @@ error[E0741]: using function pointers as const generic parameters is forbidden LL | struct Checked<const F: fn(usize) -> bool>; | ^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/fn-const-param-infer.rs:23:24 + | +LL | let _ = Checked::<{generic_arg::<u32>}>; + | ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item + | + = note: expected fn pointer `fn(usize) -> _` + found fn item `fn(u32) -> _ {generic_arg::<u32>}` + +error[E0282]: type annotations needed + --> $DIR/fn-const-param-infer.rs:25:23 + | +LL | let _ = Checked::<generic>; + | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic` + | +help: consider specifying the generic argument + | +LL | let _ = Checked::<generic::<T>>; + | +++++ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0741`. +Some errors have detailed explanations: E0282, E0308, E0741. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/const-generics/fn-const-param-infer.min.stderr b/tests/ui/const-generics/fn-const-param-infer.min.stderr index f6d41809d67..01e224f8d9c 100644 --- a/tests/ui/const-generics/fn-const-param-infer.min.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.min.stderr @@ -6,5 +6,27 @@ LL | struct Checked<const F: fn(usize) -> bool>; | = note: the only supported types are integers, `bool` and `char` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/fn-const-param-infer.rs:23:24 + | +LL | let _ = Checked::<{generic_arg::<u32>}>; + | ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item + | + = note: expected fn pointer `fn(usize) -> _` + found fn item `fn(u32) -> _ {generic_arg::<u32>}` + +error[E0282]: type annotations needed + --> $DIR/fn-const-param-infer.rs:25:23 + | +LL | let _ = Checked::<generic>; + | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic` + | +help: consider specifying the generic argument + | +LL | let _ = Checked::<generic::<T>>; + | +++++ + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/const-generics/fn-const-param-infer.rs b/tests/ui/const-generics/fn-const-param-infer.rs index 22f5f529c76..d80e18067e2 100644 --- a/tests/ui/const-generics/fn-const-param-infer.rs +++ b/tests/ui/const-generics/fn-const-param-infer.rs @@ -20,9 +20,9 @@ fn main() { let _ = Checked::<generic_arg>; let _ = Checked::<{generic_arg::<usize>}>; - let _ = Checked::<{generic_arg::<u32>}>; + let _ = Checked::<{generic_arg::<u32>}>; //~ ERROR: mismatched types - let _ = Checked::<generic>; + let _ = Checked::<generic>; //~ ERROR: type annotations needed let _ = Checked::<{generic::<u16>}>; let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>; let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs index 9c5de03170b..77cce66e4ec 100644 --- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs +++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs @@ -16,6 +16,7 @@ impl<const N: usize> Example<N> { Self { a: [0.; N], b: [0.; complex_maths(N)], + //~^ ERROR: unconstrained generic constant } } } diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr index 100cf3f8b62..4a87649f43d 100644 --- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr +++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr @@ -6,5 +6,13 @@ LL | b: [f32; complex_maths(N)], | = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:` -error: aborting due to 1 previous error +error: unconstrained generic constant + --> $DIR/no_where_clause.rs:18:15 + | +LL | b: [0.; complex_maths(N)], + | ^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:` + +error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs index 24d333aba0f..1620e257667 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs @@ -15,7 +15,7 @@ impl Foo for () { } fn use_dyn(v: &dyn Foo) { //~ERROR the trait `Foo` cannot be made into an object - v.test(); + v.test(); //~ERROR the trait `Foo` cannot be made into an object } fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr index 6f0a6b04333..31f271cc7ba 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr @@ -16,6 +16,24 @@ LL | fn test(&self) -> [u8; bar::<Self>()]; = help: consider moving `test` to another trait = help: only type `()` implements the trait, consider using it directly instead -error: aborting due to 1 previous error +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-err-ret.rs:18:5 + | +LL | v.test(); + | ^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-err-ret.rs:8:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn test(&self) -> [u8; bar::<Self>()]; + | ^^^^ ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type + | | + | ...because method `test` references the `Self` type in its `where` clause + = help: consider moving `test` to another trait + = help: only type `()` implements the trait, consider using it directly instead + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index eb71ebb62eb..77a7da17c13 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -34,6 +34,47 @@ LL + #[derive(ConstParamTy)] LL | struct Foo(u8); | -error: aborting due to 3 previous errors +error: unconstrained generic constant + --> $DIR/unify-op-with-fn-call.rs:30:12 + | +LL | bar2::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:` + +error[E0015]: cannot call non-const operator in constants + --> $DIR/unify-op-with-fn-call.rs:20:39 + | +LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) { + | ^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/unify-op-with-fn-call.rs:10:1 + | +LL | impl const std::ops::Add for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable + +error[E0015]: cannot call non-const fn `<Foo as Add>::add` in constants + --> $DIR/unify-op-with-fn-call.rs:21:13 + | +LL | bar::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable + +error[E0015]: cannot call non-const fn `<usize as Add>::add` in constants + --> $DIR/unify-op-with-fn-call.rs:30:14 + | +LL | bar2::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable + +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0741`. +Some errors have detailed explanations: E0015, E0741. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index eb8b9732f58..984381d1669 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -15,6 +15,16 @@ LL | fn foo<const N: usize, const A: [u8; N]>() {} = note: the only supported types are integers, `bool` and `char` = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types -error: aborting due to 2 previous errors +error[E0747]: type provided when a constant was expected + --> $DIR/issue-62878.rs:10:11 + | +LL | foo::<_, { [1] }>(); + | ^ + | + = help: const arguments cannot yet be inferred with `_` + = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0770`. +Some errors have detailed explanations: E0747, E0770. +For more information about an error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/issues/issue-62878.rs b/tests/ui/const-generics/issues/issue-62878.rs index 4c08a484ef4..d226551ef8a 100644 --- a/tests/ui/const-generics/issues/issue-62878.rs +++ b/tests/ui/const-generics/issues/issue-62878.rs @@ -8,4 +8,5 @@ fn foo<const N: usize, const A: [u8; N]>() {} fn main() { foo::<_, { [1] }>(); + //[min]~^ ERROR: type provided when a constant was expected } diff --git a/tests/ui/const-generics/issues/issue-72352.full.stderr b/tests/ui/const-generics/issues/issue-72352.full.stderr index cc46e7951f0..16a14d7f480 100644 --- a/tests/ui/const-generics/issues/issue-72352.full.stderr +++ b/tests/ui/const-generics/issues/issue-72352.full.stderr @@ -1,7 +1,7 @@ error[E0741]: using function pointers as const generic parameters is forbidden - --> $DIR/issue-72352.rs:7:42 + --> $DIR/issue-72352.rs:8:42 | -LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { +LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const c_char) -> usize { | ^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-72352.min.stderr b/tests/ui/const-generics/issues/issue-72352.min.stderr index cd009c973ae..ede0faec7c6 100644 --- a/tests/ui/const-generics/issues/issue-72352.min.stderr +++ b/tests/ui/const-generics/issues/issue-72352.min.stderr @@ -1,7 +1,7 @@ error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-72352.rs:7:42 + --> $DIR/issue-72352.rs:8:42 | -LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { +LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const c_char) -> usize { | ^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` diff --git a/tests/ui/const-generics/issues/issue-72352.rs b/tests/ui/const-generics/issues/issue-72352.rs index 2fa1d7a5337..0cab6e8ebfa 100644 --- a/tests/ui/const-generics/issues/issue-72352.rs +++ b/tests/ui/const-generics/issues/issue-72352.rs @@ -1,10 +1,11 @@ // revisions: full min + #![cfg_attr(full, feature(adt_const_params))] #![cfg_attr(full, allow(incomplete_features))] -use std::ffi::{CStr, CString}; +use std::ffi::{c_char, CStr, CString}; -unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { +unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const c_char) -> usize { //~^ ERROR: using function pointers as const generic parameters is forbidden F(CStr::from_ptr(ptr)) } @@ -16,7 +17,5 @@ fn safely_do_the_thing(s: &CStr) -> usize { fn main() { let baguette = CString::new("baguette").unwrap(); let ptr = baguette.as_ptr(); - println!("{}", unsafe { - unsafely_do_the_thing::<safely_do_the_thing>(ptr) - }); + println!("{}", unsafe { unsafely_do_the_thing::<safely_do_the_thing>(ptr) }); } diff --git a/tests/ui/const-generics/raw-ptr-const-param.full.stderr b/tests/ui/const-generics/raw-ptr-const-param.full.stderr index aef95bdaa88..7ba9ac15bf3 100644 --- a/tests/ui/const-generics/raw-ptr-const-param.full.stderr +++ b/tests/ui/const-generics/raw-ptr-const-param.full.stderr @@ -4,6 +4,18 @@ error[E0741]: using raw pointers as const generic parameters is forbidden LL | struct Const<const P: *const u32>; | ^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/raw-ptr-const-param.rs:9:40 + | +LL | let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>; + | ------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{0xf as *const u32}`, found `{0xa as *const u32}` + | | + | expected due to this + | + = note: expected struct `Const<{0xf as *const u32}>` + found struct `Const<{0xa as *const u32}>` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0741`. +Some errors have detailed explanations: E0308, E0741. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/raw-ptr-const-param.min.stderr b/tests/ui/const-generics/raw-ptr-const-param.min.stderr index 4de98191d5b..18bbcc33c4d 100644 --- a/tests/ui/const-generics/raw-ptr-const-param.min.stderr +++ b/tests/ui/const-generics/raw-ptr-const-param.min.stderr @@ -6,5 +6,17 @@ LL | struct Const<const P: *const u32>; | = note: the only supported types are integers, `bool` and `char` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/raw-ptr-const-param.rs:9:40 + | +LL | let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>; + | ------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{0xf as *const u32}`, found `{0xa as *const u32}` + | | + | expected due to this + | + = note: expected struct `Const<{0xf as *const u32}>` + found struct `Const<{0xa as *const u32}>` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/raw-ptr-const-param.rs b/tests/ui/const-generics/raw-ptr-const-param.rs index 27ef9e7d96c..9cc46c769e7 100644 --- a/tests/ui/const-generics/raw-ptr-const-param.rs +++ b/tests/ui/const-generics/raw-ptr-const-param.rs @@ -7,5 +7,6 @@ struct Const<const P: *const u32>; //~ ERROR: using raw pointers as const generi fn main() { let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>; + //~^ ERROR: mismatched types let _: Const<{ 10 as *const _ }> = Const::<{ 10 as *const _ }>; } diff --git a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr index 3c086f59b27..26f5af6c831 100644 --- a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr +++ b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr @@ -16,5 +16,39 @@ LL | struct ConstBytes<const T: &'static [u8]>; = note: the only supported types are integers, `bool` and `char` = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/slice-const-param-mismatch.rs:14:35 + | +LL | let _: ConstString<"Hello"> = ConstString::<"World">; + | -------------------- ^^^^^^^^^^^^^^^^^^^^^^ expected `"Hello"`, found `"World"` + | | + | expected due to this + | + = note: expected struct `ConstString<"Hello">` + found struct `ConstString<"World">` + +error[E0308]: mismatched types + --> $DIR/slice-const-param-mismatch.rs:16:33 + | +LL | let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; + | ------------------- ^^^^^^^^^^^^^^^^^^^^^ expected `"ℇ㇈↦"`, found `"ℇ㇈↥"` + | | + | expected due to this + | + = note: expected struct `ConstString<"ℇ㇈↦">` + found struct `ConstString<"ℇ㇈↥">` + +error[E0308]: mismatched types + --> $DIR/slice-const-param-mismatch.rs:18:33 + | +LL | let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">; + | ------------------ ^^^^^^^^^^^^^^^^^^^^ expected `b"AAA"`, found `b"BBB"` + | | + | expected due to this + | + = note: expected struct `ConstBytes<b"AAA">` + found struct `ConstBytes<b"BBB">` + +error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/slice-const-param-mismatch.rs b/tests/ui/const-generics/slice-const-param-mismatch.rs index 7127323e5ba..24c05d7bea5 100644 --- a/tests/ui/const-generics/slice-const-param-mismatch.rs +++ b/tests/ui/const-generics/slice-const-param-mismatch.rs @@ -11,9 +11,9 @@ struct ConstBytes<const T: &'static [u8]>; pub fn main() { let _: ConstString<"Hello"> = ConstString::<"Hello">; - let _: ConstString<"Hello"> = ConstString::<"World">; //[full]~ ERROR mismatched types + let _: ConstString<"Hello"> = ConstString::<"World">; //~ ERROR mismatched types let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↦">; - let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; //[full]~ ERROR mismatched types + let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; //~ ERROR mismatched types let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>; - let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">; //[full]~ ERROR mismatched types + let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">; //~ ERROR mismatched types } diff --git a/tests/ui/consts/const-unsized.rs b/tests/ui/consts/const-unsized.rs index e0b06a27109..18682aa6eb6 100644 --- a/tests/ui/consts/const-unsized.rs +++ b/tests/ui/consts/const-unsized.rs @@ -18,4 +18,6 @@ static STATIC_BAR: str = *"bar"; fn main() { println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); + //~^ ERROR: cannot move a value of type `str` + //~| ERROR: cannot move a value of type `dyn Debug + Sync` } diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr index f70c9b2e077..0b69cad9651 100644 --- a/tests/ui/consts/const-unsized.stderr +++ b/tests/ui/consts/const-unsized.stderr @@ -66,6 +66,19 @@ LL | static STATIC_BAR: str = *"bar"; = help: the trait `Sized` is not implemented for `str` = note: constant expressions must have a statically known size -error: aborting due to 8 previous errors +error[E0161]: cannot move a value of type `str` + --> $DIR/const-unsized.rs:20:48 + | +LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); + | ^^^^^^^^^ the size of `str` cannot be statically determined + +error[E0161]: cannot move a value of type `dyn Debug + Sync` + --> $DIR/const-unsized.rs:20:38 + | +LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); + | ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined + +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0161, E0277. +For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/issues/issue-44255.rs b/tests/ui/consts/issue-44255.rs index 22450320432..22450320432 100644 --- a/tests/ui/issues/issue-44255.rs +++ b/tests/ui/consts/issue-44255.rs diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr index d5c5f76b90a..7cb85d5279d 100644 --- a/tests/ui/consts/issue-89088.stderr +++ b/tests/ui/consts/issue-89088.stderr @@ -9,9 +9,4 @@ LL | FOO => todo!(), = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362> = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-89088.rs:5:10 - | -LL | #![allow(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr index 5b4a0418b1e..7679c50c74b 100644 --- a/tests/ui/consts/recursive-zst-static.default.stderr +++ b/tests/ui/consts/recursive-zst-static.default.stderr @@ -1,21 +1,35 @@ -error[E0391]: cycle detected when const-evaluating + checking `FOO` +error[E0080]: could not evaluate static initializer --> $DIR/recursive-zst-static.rs:10:18 | LL | static FOO: () = FOO; - | ^^^ + | ^^^ encountered static that tried to initialize itself with itself + +error[E0391]: cycle detected when evaluating initializer of static `A` + --> $DIR/recursive-zst-static.rs:13:16 + | +LL | static A: () = B; + | ^ | - = note: ...which immediately requires const-evaluating + checking `FOO` again +note: ...which requires evaluating initializer of static `B`... + --> $DIR/recursive-zst-static.rs:14:16 + | +LL | static B: () = A; + | ^ + = note: ...which again requires evaluating initializer of static `A`, completing the cycle note: cycle used when linting top-level module --> $DIR/recursive-zst-static.rs:10:1 | LL | / static FOO: () = FOO; LL | | -LL | | fn main() { +LL | | +LL | | static A: () = B; +... | LL | | FOO LL | | } | |_^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0080, E0391. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/recursive-zst-static.rs b/tests/ui/consts/recursive-zst-static.rs index 4e61634b349..9311490020d 100644 --- a/tests/ui/consts/recursive-zst-static.rs +++ b/tests/ui/consts/recursive-zst-static.rs @@ -7,7 +7,11 @@ // can depend on this fact and will thus do unsound things when it is violated. // See https://github.com/rust-lang/rust/issues/71078 for more details. -static FOO: () = FOO; //~ cycle detected when const-evaluating + checking `FOO` +static FOO: () = FOO; +//~^ ERROR could not evaluate static initializer + +static A: () = B; //~ cycle detected when evaluating initializer of static `A` +static B: () = A; fn main() { FOO diff --git a/tests/ui/consts/recursive-zst-static.unleash.stderr b/tests/ui/consts/recursive-zst-static.unleash.stderr index 5b4a0418b1e..7679c50c74b 100644 --- a/tests/ui/consts/recursive-zst-static.unleash.stderr +++ b/tests/ui/consts/recursive-zst-static.unleash.stderr @@ -1,21 +1,35 @@ -error[E0391]: cycle detected when const-evaluating + checking `FOO` +error[E0080]: could not evaluate static initializer --> $DIR/recursive-zst-static.rs:10:18 | LL | static FOO: () = FOO; - | ^^^ + | ^^^ encountered static that tried to initialize itself with itself + +error[E0391]: cycle detected when evaluating initializer of static `A` + --> $DIR/recursive-zst-static.rs:13:16 + | +LL | static A: () = B; + | ^ | - = note: ...which immediately requires const-evaluating + checking `FOO` again +note: ...which requires evaluating initializer of static `B`... + --> $DIR/recursive-zst-static.rs:14:16 + | +LL | static B: () = A; + | ^ + = note: ...which again requires evaluating initializer of static `A`, completing the cycle note: cycle used when linting top-level module --> $DIR/recursive-zst-static.rs:10:1 | LL | / static FOO: () = FOO; LL | | -LL | | fn main() { +LL | | +LL | | static A: () = B; +... | LL | | FOO LL | | } | |_^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0080, E0391. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/write-to-static-mut-in-static.rs b/tests/ui/consts/write-to-static-mut-in-static.rs index 43c63fed8ce..a2985d05a79 100644 --- a/tests/ui/consts/write-to-static-mut-in-static.rs +++ b/tests/ui/consts/write-to-static-mut-in-static.rs @@ -3,8 +3,8 @@ pub static mut B: () = unsafe { A = 1; }; //~^ ERROR could not evaluate static initializer pub static mut C: u32 = unsafe { C = 1; 0 }; -//~^ ERROR cycle detected pub static D: u32 = D; +//~^ ERROR could not evaluate static initializer fn main() {} diff --git a/tests/ui/consts/write-to-static-mut-in-static.stderr b/tests/ui/consts/write-to-static-mut-in-static.stderr index caee433a681..9616f8eeeb7 100644 --- a/tests/ui/consts/write-to-static-mut-in-static.stderr +++ b/tests/ui/consts/write-to-static-mut-in-static.stderr @@ -4,27 +4,12 @@ error[E0080]: could not evaluate static initializer LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ modifying a static's initial value from another static's initializer -error[E0391]: cycle detected when const-evaluating + checking `C` - --> $DIR/write-to-static-mut-in-static.rs:5:34 - | -LL | pub static mut C: u32 = unsafe { C = 1; 0 }; - | ^^^^^ - | - = note: ...which immediately requires const-evaluating + checking `C` again -note: cycle used when linting top-level module - --> $DIR/write-to-static-mut-in-static.rs:1:1 +error[E0080]: could not evaluate static initializer + --> $DIR/write-to-static-mut-in-static.rs:7:21 | -LL | / pub static mut A: u32 = 0; -LL | | pub static mut B: () = unsafe { A = 1; }; -LL | | -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +LL | pub static D: u32 = D; + | ^ encountered static that tried to initialize itself with itself error: aborting due to 2 previous errors -Some errors have detailed explanations: E0080, E0391. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/cross/cross-fn-cache-hole.rs b/tests/ui/cross/cross-fn-cache-hole.rs index c38a5001ac8..4aa08ea2e17 100644 --- a/tests/ui/cross/cross-fn-cache-hole.rs +++ b/tests/ui/cross/cross-fn-cache-hole.rs @@ -28,4 +28,5 @@ fn require<A,B>() fn main() { require::<i32, u32>(); + //~^ ERROR `i32: Bar<u32>` is not satisfied } diff --git a/tests/ui/cross/cross-fn-cache-hole.stderr b/tests/ui/cross/cross-fn-cache-hole.stderr index ae944387f57..dec2f2553c2 100644 --- a/tests/ui/cross/cross-fn-cache-hole.stderr +++ b/tests/ui/cross/cross-fn-cache-hole.stderr @@ -12,6 +12,25 @@ LL | trait Bar<X> { } = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable -error: aborting due to 1 previous error +error[E0277]: the trait bound `i32: Bar<u32>` is not satisfied + --> $DIR/cross-fn-cache-hole.rs:30:15 + | +LL | require::<i32, u32>(); + | ^^^ the trait `Bar<u32>` is not implemented for `i32` + | +help: this trait has no implementations, consider adding one + --> $DIR/cross-fn-cache-hole.rs:11:1 + | +LL | trait Bar<X> { } + | ^^^^^^^^^^^^ +note: required by a bound in `require` + --> $DIR/cross-fn-cache-hole.rs:25:14 + | +LL | fn require<A,B>() + | ------- required by a bound in this function +LL | where A: Bar<B> + | ^^^^^^ required by this bound in `require` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr index 3c474d19d1d..4a119f673c8 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr @@ -182,7 +182,7 @@ LL | type H = Fn(u8) -> (u8)::Output; = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | type H = <dyn Fn(u8) -> (u8)>::Output; | ++++ + diff --git a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr index 65d44604dc9..711bfa188ec 100644 --- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr +++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #[deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) { | +++ @@ -24,7 +24,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) { | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) { | +++ @@ -37,7 +37,7 @@ LL | let _x: &SomeTrait = todo!(); | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let _x: &dyn SomeTrait = todo!(); | +++ diff --git a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr index 0b194cb8364..41298cc73c8 100644 --- a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr +++ b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | <dyn fmt::Debug>::fmt(self, f) | +++ diff --git a/tests/ui/error-codes/E0038.rs b/tests/ui/error-codes/E0038.rs index 9757e2ab10c..a467767c3fa 100644 --- a/tests/ui/error-codes/E0038.rs +++ b/tests/ui/error-codes/E0038.rs @@ -5,6 +5,8 @@ trait Trait { fn call_foo(x: Box<dyn Trait>) { //~^ ERROR E0038 let y = x.foo(); + //~^ ERROR E0038 + //~| ERROR E0277 } fn main() { diff --git a/tests/ui/error-codes/E0038.stderr b/tests/ui/error-codes/E0038.stderr index 99130396e02..6e8eaab8ddf 100644 --- a/tests/ui/error-codes/E0038.stderr +++ b/tests/ui/error-codes/E0038.stderr @@ -13,6 +13,32 @@ LL | fn foo(&self) -> Self; | ^^^^ ...because method `foo` references the `Self` type in its return type = help: consider moving `foo` to another trait -error: aborting due to 1 previous error +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/E0038.rs:7:13 + | +LL | let y = x.foo(); + | ^^^^^^^ `Trait` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/E0038.rs:2:22 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | fn foo(&self) -> Self; + | ^^^^ ...because method `foo` references the `Self` type in its return type + = help: consider moving `foo` to another trait + +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/E0038.rs:7:9 + | +LL | let y = x.foo(); + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/error-codes/E0059.rs b/tests/ui/error-codes/E0059.rs index f775089bfb9..a04cc0cb2b9 100644 --- a/tests/ui/error-codes/E0059.rs +++ b/tests/ui/error-codes/E0059.rs @@ -1,6 +1,8 @@ #![feature(unboxed_closures)] fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } //~ ERROR E0059 +//~^ ERROR `i32` is not a tuple +//~| ERROR cannot use call notation fn main() { } diff --git a/tests/ui/error-codes/E0059.stderr b/tests/ui/error-codes/E0059.stderr index a7591d2b04b..d26fadcdbfa 100644 --- a/tests/ui/error-codes/E0059.stderr +++ b/tests/ui/error-codes/E0059.stderr @@ -7,6 +7,19 @@ LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL -error: aborting due to 1 previous error +error[E0277]: `i32` is not a tuple + --> $DIR/E0059.rs:3:41 + | +LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } + | ^^^^ the trait `Tuple` is not implemented for `i32` + +error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit + --> $DIR/E0059.rs:3:41 + | +LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) } + | ^^^^ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0059`. +Some errors have detailed explanations: E0059, E0277. +For more information about an error, try `rustc --explain E0059`. diff --git a/tests/ui/error-codes/E0229.rs b/tests/ui/error-codes/E0229.rs index b7cdb1737b0..558baae37f7 100644 --- a/tests/ui/error-codes/E0229.rs +++ b/tests/ui/error-codes/E0229.rs @@ -15,6 +15,7 @@ fn baz<I>(x: &<I as Foo<A=Bar>>::A) {} //~| ERROR associated type bindings are not allowed here [E0229] //~| ERROR associated type bindings are not allowed here [E0229] //~| ERROR the trait bound `I: Foo` is not satisfied +//~| ERROR the trait bound `I: Foo` is not satisfied fn main() { } diff --git a/tests/ui/error-codes/E0229.stderr b/tests/ui/error-codes/E0229.stderr index a7a2904bb89..bd8e1955ac6 100644 --- a/tests/ui/error-codes/E0229.stderr +++ b/tests/ui/error-codes/E0229.stderr @@ -31,7 +31,18 @@ help: consider restricting type parameter `I` LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {} | +++++ -error: aborting due to 4 previous errors +error[E0277]: the trait bound `I: Foo` is not satisfied + --> $DIR/E0229.rs:13:37 + | +LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {} + | ^^ the trait `Foo` is not implemented for `I` + | +help: consider restricting type parameter `I` + | +LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {} + | +++++ + +error: aborting due to 5 previous errors Some errors have detailed explanations: E0229, E0277. For more information about an error, try `rustc --explain E0229`. diff --git a/tests/ui/issues/issue-18576.rs b/tests/ui/extern/issue-18576.rs index 389cf108b05..389cf108b05 100644 --- a/tests/ui/issues/issue-18576.rs +++ b/tests/ui/extern/issue-18576.rs diff --git a/tests/ui/issues/issue-18819.rs b/tests/ui/extern/issue-18819.rs index e634c55f824..e634c55f824 100644 --- a/tests/ui/issues/issue-18819.rs +++ b/tests/ui/extern/issue-18819.rs diff --git a/tests/ui/issues/issue-18819.stderr b/tests/ui/extern/issue-18819.stderr index b2cf0bad1df..b2cf0bad1df 100644 --- a/tests/ui/issues/issue-18819.stderr +++ b/tests/ui/extern/issue-18819.stderr diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.rs b/tests/ui/extern/issue-36122-accessing-externed-dst.rs index 5f886ff5737..9fb7780e3d7 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.rs +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.rs @@ -3,4 +3,5 @@ fn main() { static symbol: [usize]; //~ ERROR: the size for values of type } println!("{}", symbol[0]); + //~^ ERROR: extern static is unsafe } diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr index 25348b64002..64178e6f843 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr @@ -6,6 +6,15 @@ LL | static symbol: [usize]; | = help: the trait `Sized` is not implemented for `[usize]` -error: aborting due to 1 previous error +error[E0133]: use of extern static is unsafe and requires unsafe function or block + --> $DIR/issue-36122-accessing-externed-dst.rs:5:20 + | +LL | println!("{}", symbol[0]); + | ^^^^^^ use of extern static + | + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0133, E0277. +For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/issues/issue-23781.rs b/tests/ui/fmt/issue-23781.rs index 220ebdb1872..220ebdb1872 100644 --- a/tests/ui/issues/issue-23781.rs +++ b/tests/ui/fmt/issue-23781.rs diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs index 2a9a6a8cc6c..a7489f6fbaf 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.rs @@ -18,6 +18,6 @@ where fn main() { let x = String::from("Hello World!"); let y = f(&x, ()); - drop(x); + drop(x); //~ ERROR cannot move out of `x` println!("{}", y); } diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr index 4662eb32abb..bf6d77b6269 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr @@ -16,6 +16,19 @@ help: consider adding an explicit lifetime bound LL | impl<'a, T: 'a> Trait<'a> for T { | ++++ -error: aborting due to 1 previous error +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/implied-bounds-unnorm-associated-type-5.rs:21:10 + | +LL | let x = String::from("Hello World!"); + | - binding `x` declared here +LL | let y = f(&x, ()); + | -- borrow of `x` occurs here +LL | drop(x); + | ^ move out of `x` occurs here +LL | println!("{}", y); + | - borrow later used here + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0309`. +Some errors have detailed explanations: E0309, E0505. +For more information about an error, try `rustc --explain E0309`. diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr index e05c83ebc76..4205c5c5ef7 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr @@ -16,6 +16,43 @@ LL | type A<'a> where Self: 'a; Fooer<T> Fooy -error: aborting due to 1 previous error +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/gat-in-trait-path.rs:32:5 + | +LL | f(Box::new(foo)); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/gat-in-trait-path.rs:10:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type A<'a> where Self: 'a; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead: + Fooer<T> + Fooy + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/gat-in-trait-path.rs:32:5 + | +LL | f(Box::new(foo)); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/gat-in-trait-path.rs:10:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type A<'a> where Self: 'a; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead: + Fooer<T> + Fooy + = note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A = &'a ()> + 'static)>` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.rs b/tests/ui/generic-associated-types/gat-in-trait-path.rs index c55f5a726bd..c1ce7d69f10 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path.rs +++ b/tests/ui/generic-associated-types/gat-in-trait-path.rs @@ -30,4 +30,6 @@ fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {} fn main() { let foo = Fooer(5); f(Box::new(foo)); + //[base]~^ the trait `Foo` cannot be made into an object + //[base]~| the trait `Foo` cannot be made into an object } diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs index 285493132b6..671d17f36f1 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs @@ -9,6 +9,7 @@ impl<T> X for T { //~ ERROR: not all trait items implemented //~^ ERROR missing generics for associated type //~^^ ERROR missing generics for associated type //~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters + //~| ERROR may not live long enough t } } diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr index 74ce93a613c..8589d008a6b 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -51,7 +51,16 @@ LL | type Y<'a>; LL | impl<T> X for T { | ^^^^^^^^^^^^^^^ missing `Y` in implementation -error: aborting due to 4 previous errors +error: lifetime may not live long enough + --> $DIR/gat-trait-path-missing-lifetime.rs:8:3 + | +LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> { + | ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | lifetime `'a` defined here + | requires that `'a` must outlive `'static` + +error: aborting due to 5 previous errors Some errors have detailed explanations: E0046, E0049, E0107. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/generic-associated-types/trait-objects.base.stderr b/tests/ui/generic-associated-types/trait-objects.base.stderr index e3cfd46524e..2b5060289ab 100644 --- a/tests/ui/generic-associated-types/trait-objects.base.stderr +++ b/tests/ui/generic-associated-types/trait-objects.base.stderr @@ -13,6 +13,36 @@ LL | type Item<'a> where Self: 'a; | ^^^^ ...because it contains the generic associated type `Item` = help: consider moving `Item` to another trait -error: aborting due to 1 previous error +error[E0038]: the trait `StreamingIterator` cannot be made into an object + --> $DIR/trait-objects.rs:15:7 + | +LL | x.size_hint().0 + | ^^^^^^^^^ `StreamingIterator` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/trait-objects.rs:7:10 + | +LL | trait StreamingIterator { + | ----------------- this trait cannot be made into an object... +LL | type Item<'a> where Self: 'a; + | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait + +error[E0038]: the trait `StreamingIterator` cannot be made into an object + --> $DIR/trait-objects.rs:15:5 + | +LL | x.size_hint().0 + | ^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/trait-objects.rs:7:10 + | +LL | trait StreamingIterator { + | ----------------- this trait cannot be made into an object... +LL | type Item<'a> where Self: 'a; + | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/trait-objects.rs b/tests/ui/generic-associated-types/trait-objects.rs index 17fed11bac3..674bee919bf 100644 --- a/tests/ui/generic-associated-types/trait-objects.rs +++ b/tests/ui/generic-associated-types/trait-objects.rs @@ -14,6 +14,8 @@ fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize //[base]~^ the trait `StreamingIterator` cannot be made into an object x.size_hint().0 //[extended]~^ borrowed data escapes + //[base]~^^ the trait `StreamingIterator` cannot be made into an object + //[base]~| the trait `StreamingIterator` cannot be made into an object } fn main() {} diff --git a/tests/ui/issues/issue-29746.rs b/tests/ui/hygiene/issue-29746.rs index 3470a7e09ad..3470a7e09ad 100644 --- a/tests/ui/issues/issue-29746.rs +++ b/tests/ui/hygiene/issue-29746.rs diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr index 84aaedf1838..3cb3af89bfc 100644 --- a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr +++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr @@ -7,7 +7,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> { = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn ice() -> impl AsRef<dyn Fn(&())> { | +++ diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs index ab3086c78b3..068f7d3eea6 100644 --- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs +++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs @@ -19,6 +19,7 @@ impl NotObjectSafe for B { } fn car() -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be made into an object +//~^ ERROR return type cannot have an unboxed trait object if true { return A; } @@ -27,9 +28,9 @@ fn car() -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be ma fn cat() -> Box<dyn NotObjectSafe> { //~ ERROR the trait `NotObjectSafe` cannot be made into an if true { - return Box::new(A); + return Box::new(A); //~ ERROR cannot be made into an object } - Box::new(B) + Box::new(B) //~ ERROR cannot be made into an object } fn main() {} diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 37c96d9bc4e..fc9c30abf13 100644 --- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -24,7 +24,7 @@ LL | fn foo() -> Self where Self: Sized; | +++++++++++++++++ error[E0038]: the trait `NotObjectSafe` cannot be made into an object - --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:17 + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:29:17 | LL | fn cat() -> Box<dyn NotObjectSafe> { | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object @@ -48,6 +48,79 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o LL | fn foo() -> Self where Self: Sized; | +++++++++++++++++ -error: aborting due to 2 previous errors +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 + | +LL | fn car() -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | +help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + | +LL | fn car() -> impl NotObjectSafe { + | ~~~~ +help: box the return type, and wrap all of the returned values in `Box::new` + | +LL ~ fn car() -> Box<dyn NotObjectSafe> { +LL | +LL | if true { +LL ~ return Box::new(A); +LL | } +LL ~ Box::new(B) + | + +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:31:16 + | +LL | return Box::new(A); + | ^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8 + | +LL | trait NotObjectSafe { + | ------------- this trait cannot be made into an object... +LL | fn foo() -> Self; + | ^^^ ...because associated function `foo` has no `self` parameter + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead: + A + B + = note: required for the cast from `Box<A>` to `Box<(dyn NotObjectSafe + 'static)>` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) -> Self; + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() -> Self where Self: Sized; + | +++++++++++++++++ + +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:33:5 + | +LL | Box::new(B) + | ^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8 + | +LL | trait NotObjectSafe { + | ------------- this trait cannot be made into an object... +LL | fn foo() -> Self; + | ^^^ ...because associated function `foo` has no `self` parameter + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead: + A + B + = note: required for the cast from `Box<B>` to `Box<(dyn NotObjectSafe + 'static)>` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) -> Self; + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() -> Self where Self: Sized; + | +++++++++++++++++ + +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0746. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr new file mode 100644 index 00000000000..fee3b86034a --- /dev/null +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -0,0 +1,23 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-coroutine-boxed.rs:10:23 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` +... +LL | let mut r = gen.as_mut().resume(()); + | ------ type must be known at this point + | +help: consider specifying the generic argument + | +LL | let mut gen = Box::<T>::pin(foo()); + | +++++ + +error[E0282]: type annotations needed + --> $DIR/recursive-coroutine-boxed.rs:10:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ cannot infer type for opaque type `impl Coroutine<Yield = (), Return = ()>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index b9291f07e21..3f677986c13 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -1,5 +1,5 @@ -// check-pass // revisions: current next +//[current] check-pass //[next] compile-flags: -Znext-solver #![feature(coroutines, coroutine_trait)] @@ -8,6 +8,8 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine<Yield = (), Return = ()> { || { let mut gen = Box::pin(foo()); + //[next]~^ ERROR type annotations needed + //[next]~| ERROR type annotations needed let mut r = gen.as_mut().resume(()); while let CoroutineState::Yielded(v) = r { yield v; diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr index e49d1d18b0c..69328e20583 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr @@ -1,8 +1,8 @@ -error[E0284]: type annotations needed: cannot satisfy `A <: B` +error[E0284]: type annotations needed: cannot satisfy `A == B` --> $DIR/two_tait_defining_each_other2.rs:11:5 | LL | x // B's hidden type is A (opaquely) - | ^ cannot satisfy `A <: B` + | ^ cannot satisfy `A == B` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index 8a79af19776..b2f768f4dcd 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -10,7 +10,7 @@ trait Foo {} fn muh(x: A) -> B { x // B's hidden type is A (opaquely) //[current]~^ ERROR opaque type's hidden type cannot be another opaque type - //[next]~^^ ERROR type annotations needed: cannot satisfy `A <: B` + //[next]~^^ ERROR type annotations needed: cannot satisfy `A == B` } struct Bar; diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs index 27c8f30ec32..eba4ecd3a28 100644 --- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs +++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs @@ -29,16 +29,19 @@ impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T { //~^ ERROR lifetime mismatch sadness.cast() + //~^ ERROR may not live long enough } fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) { //~^ ERROR lifetime mismatch let _: &'out T = sadness.cast(); + //~^ ERROR may not live long enough } fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) { //~^ ERROR lifetime mismatch let _: &'out T = sadness.cast(); + //~^ ERROR may not live long enough } fn bad<'short, T>(value: &'short T) -> &'static T { diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr index 0c00bbc380e..c9dc820fd60 100644 --- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr +++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr @@ -8,7 +8,7 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out | ...but data from `x` is returned here error[E0623]: lifetime mismatch - --> $DIR/hrlt-implied-trait-bounds-guard.rs:34:30 + --> $DIR/hrlt-implied-trait-bounds-guard.rs:35:30 | LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) { | ^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) { | ...but data with one lifetime flows into the other here error[E0623]: lifetime mismatch - --> $DIR/hrlt-implied-trait-bounds-guard.rs:39:30 + --> $DIR/hrlt-implied-trait-bounds-guard.rs:41:30 | LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) { | ^^^^^^^^^^^^^^^^^-------^^-------^^ @@ -25,6 +25,45 @@ LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: | | these two types are declared with different lifetimes... | ...but data from `a` flows into `a` here -error: aborting due to 3 previous errors +error: lifetime may not live long enough + --> $DIR/hrlt-implied-trait-bounds-guard.rs:31:5 + | +LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T { + | ---- ---- lifetime `'out` defined here + | | + | lifetime `'in_` defined here +LL | +LL | sadness.cast() + | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'out` but it is returning data with lifetime `'in_` + | + = help: consider adding the following bound: `'in_: 'out` + +error: lifetime may not live long enough + --> $DIR/hrlt-implied-trait-bounds-guard.rs:37:12 + | +LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) { + | ---- ---- lifetime `'out` defined here + | | + | lifetime `'in_` defined here +LL | +LL | let _: &'out T = sadness.cast(); + | ^^^^^^^ type annotation requires that `'in_` must outlive `'out` + | + = help: consider adding the following bound: `'in_: 'out` + +error: lifetime may not live long enough + --> $DIR/hrlt-implied-trait-bounds-guard.rs:43:12 + | +LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) { + | ---- ---- lifetime `'out` defined here + | | + | lifetime `'in_` defined here +LL | +LL | let _: &'out T = sadness.cast(); + | ^^^^^^^ type annotation requires that `'in_` must outlive `'out` + | + = help: consider adding the following bound: `'in_: 'out` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0623`. diff --git a/tests/ui/inference/issue-107090.rs b/tests/ui/inference/issue-107090.rs index 799c3641833..d1c86fb03d7 100644 --- a/tests/ui/inference/issue-107090.rs +++ b/tests/ui/inference/issue-107090.rs @@ -19,7 +19,7 @@ impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { //~^ ERROR use of undeclared lifetime name - sadness.cast() + sadness.cast() //~ ERROR: mismatched types } fn main() {} diff --git a/tests/ui/inference/issue-107090.stderr b/tests/ui/inference/issue-107090.stderr index e509e262fb1..55825f7765b 100644 --- a/tests/ui/inference/issue-107090.stderr +++ b/tests/ui/inference/issue-107090.stderr @@ -66,6 +66,19 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, | | | help: consider introducing lifetime `'short` here: `'short,` -error: aborting due to 6 previous errors +error[E0308]: mismatched types + --> $DIR/issue-107090.rs:22:5 + | +LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { + | - expected this type parameter ------- expected `&'out T` because of return type +LL | +LL | sadness.cast() + | ^^^^^^^^^^^^^^ expected `&T`, found `&Foo<'_, '_, T>` + | + = note: expected reference `&'out T` + found reference `&Foo<'_, '_, T>` + +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0261`. +Some errors have detailed explanations: E0261, E0308. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/issues/issue-12028.rs b/tests/ui/inference/issue-12028.rs index 7503766ff20..7503766ff20 100644 --- a/tests/ui/issues/issue-12028.rs +++ b/tests/ui/inference/issue-12028.rs diff --git a/tests/ui/issues/issue-12028.stderr b/tests/ui/inference/issue-12028.stderr index 3d7fb13d447..3d7fb13d447 100644 --- a/tests/ui/issues/issue-12028.stderr +++ b/tests/ui/inference/issue-12028.stderr diff --git a/tests/ui/issues/issue-18611.rs b/tests/ui/issues/issue-18611.rs index 91a765f34ef..57da57d8353 100644 --- a/tests/ui/issues/issue-18611.rs +++ b/tests/ui/issues/issue-18611.rs @@ -1,5 +1,6 @@ fn add_state(op: <isize as HasState>::State) { //~^ ERROR `isize: HasState` is not satisfied +//~| ERROR `isize: HasState` is not satisfied } trait HasState { diff --git a/tests/ui/issues/issue-18611.stderr b/tests/ui/issues/issue-18611.stderr index ab2374586e4..76848201f73 100644 --- a/tests/ui/issues/issue-18611.stderr +++ b/tests/ui/issues/issue-18611.stderr @@ -5,11 +5,27 @@ LL | fn add_state(op: <isize as HasState>::State) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` | help: this trait has no implementations, consider adding one - --> $DIR/issue-18611.rs:5:1 + --> $DIR/issue-18611.rs:6:1 | LL | trait HasState { | ^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `isize: HasState` is not satisfied + --> $DIR/issue-18611.rs:1:46 + | +LL | fn add_state(op: <isize as HasState>::State) { + | ______________________________________________^ +LL | | +LL | | +LL | | } + | |_^ the trait `HasState` is not implemented for `isize` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-18611.rs:6:1 + | +LL | trait HasState { + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-18959.rs b/tests/ui/issues/issue-18959.rs index 4b6f04e251b..f4cab630f2e 100644 --- a/tests/ui/issues/issue-18959.rs +++ b/tests/ui/issues/issue-18959.rs @@ -11,10 +11,14 @@ impl Foo for Thing { fn foo(b: &dyn Bar) { //~^ ERROR E0038 b.foo(&0) + //~^ ERROR E0038 } fn main() { let mut thing = Thing; let test: &dyn Bar = &mut thing; + //~^ ERROR E0038 + //~| ERROR E0038 foo(test); + //~^ ERROR E0038 } diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/issues/issue-18959.stderr index 76082dadd37..83d46f0331c 100644 --- a/tests/ui/issues/issue-18959.stderr +++ b/tests/ui/issues/issue-18959.stderr @@ -13,6 +13,67 @@ LL | pub trait Bar: Foo { } | --- this trait cannot be made into an object... = help: consider moving `foo` to another trait -error: aborting due to 1 previous error +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-18959.rs:13:5 + | +LL | b.foo(&0) + | ^^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-18959.rs:1:20 + | +LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } + | ^^^ ...because method `foo` has generic type parameters +LL | pub trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-18959.rs:19:15 + | +LL | let test: &dyn Bar = &mut thing; + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-18959.rs:1:20 + | +LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } + | ^^^ ...because method `foo` has generic type parameters +LL | pub trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-18959.rs:19:26 + | +LL | let test: &dyn Bar = &mut thing; + | ^^^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-18959.rs:1:20 + | +LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } + | ^^^ ...because method `foo` has generic type parameters +LL | pub trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + = note: required for the cast from `&mut Thing` to `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-18959.rs:22:9 + | +LL | foo(test); + | ^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-18959.rs:1:20 + | +LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); } + | ^^^ ...because method `foo` has generic type parameters +LL | pub trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/issues/issue-20831-debruijn.rs b/tests/ui/issues/issue-20831-debruijn.rs index 20d980763ea..f3286af0ae5 100644 --- a/tests/ui/issues/issue-20831-debruijn.rs +++ b/tests/ui/issues/issue-20831-debruijn.rs @@ -28,6 +28,8 @@ impl<'a> Publisher<'a> for MyStruct<'a> { fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) { // Not obvious, but there is an implicit lifetime here -------^ //~^^ ERROR cannot infer + //~| ERROR may not live long enough + //~| ERROR may not live long enough // // The fact that `Publisher` is using an implicit lifetime is // what was causing the debruijn accounting to be off, so diff --git a/tests/ui/issues/issue-20831-debruijn.stderr b/tests/ui/issues/issue-20831-debruijn.stderr index bd3ff5d59c6..7d1e19b7e47 100644 --- a/tests/ui/issues/issue-20831-debruijn.stderr +++ b/tests/ui/issues/issue-20831-debruijn.stderr @@ -22,6 +22,30 @@ LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher = note: expected `<MyStruct<'a> as Publisher<'_>>` found `<MyStruct<'_> as Publisher<'_>>` -error: aborting due to 1 previous error +error: lifetime may not live long enough + --> $DIR/issue-20831-debruijn.rs:28:5 + | +LL | impl<'a> Publisher<'a> for MyStruct<'a> { + | -- lifetime `'a` defined here +LL | type Output = u64; +LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | has type `Box<dyn Subscriber<Input = <MyStruct<'_> as Publisher<'1>>::Output>>` + | requires that `'a` must outlive `'1` + +error: lifetime may not live long enough + --> $DIR/issue-20831-debruijn.rs:28:5 + | +LL | impl<'a> Publisher<'a> for MyStruct<'a> { + | -- lifetime `'a` defined here +LL | type Output = u64; +LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | has type `Box<dyn Subscriber<Input = <MyStruct<'_> as Publisher<'1>>::Output>>` + | requires that `'1` must outlive `'a` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/issues/issue-21974.rs b/tests/ui/issues/issue-21974.rs index f7c659be148..24e92ce7b91 100644 --- a/tests/ui/issues/issue-21974.rs +++ b/tests/ui/issues/issue-21974.rs @@ -11,7 +11,7 @@ fn foo<'a,'b,T>(x: &'a T, y: &'b T) where &'a T : Foo, //~ ERROR type annotations needed &'b T : Foo { - x.foo(); + x.foo(); //~ ERROR type annotations needed y.foo(); } diff --git a/tests/ui/issues/issue-21974.stderr b/tests/ui/issues/issue-21974.stderr index 3934846ea02..cc9164e5621 100644 --- a/tests/ui/issues/issue-21974.stderr +++ b/tests/ui/issues/issue-21974.stderr @@ -12,6 +12,20 @@ LL | where &'a T : Foo, LL | &'b T : Foo | ^^^ -error: aborting due to 1 previous error +error[E0283]: type annotations needed: cannot satisfy `&T: Foo` + --> $DIR/issue-21974.rs:14:7 + | +LL | x.foo(); + | ^^^ + | +note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found + --> $DIR/issue-21974.rs:11:19 + | +LL | where &'a T : Foo, + | ^^^ +LL | &'b T : Foo + | ^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/issues/issue-22874.rs b/tests/ui/issues/issue-22874.rs index 37c6c814352..c4500aacb61 100644 --- a/tests/ui/issues/issue-22874.rs +++ b/tests/ui/issues/issue-22874.rs @@ -5,6 +5,7 @@ struct Table { fn f(table: &Table) -> &[String] { &table.rows[0] + //~^ ERROR the size for values of type } fn main() {} diff --git a/tests/ui/issues/issue-22874.stderr b/tests/ui/issues/issue-22874.stderr index 717ce72b9c1..29ddf9756ff 100644 --- a/tests/ui/issues/issue-22874.stderr +++ b/tests/ui/issues/issue-22874.stderr @@ -7,6 +7,15 @@ LL | rows: [[String]], = help: the trait `Sized` is not implemented for `[String]` = note: slice and array elements must have `Sized` type -error: aborting due to 1 previous error +error[E0277]: the size for values of type `[String]` cannot be known at compilation time + --> $DIR/issue-22874.rs:7:6 + | +LL | &table.rows[0] + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[String]`, which is required by `[_]: Index<_>` + = note: required for `[[String]]` to implement `Index<_>` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-27340.rs b/tests/ui/issues/issue-27340.rs index aff37d95a3f..53ca2bc973f 100644 --- a/tests/ui/issues/issue-27340.rs +++ b/tests/ui/issues/issue-27340.rs @@ -2,5 +2,6 @@ struct Foo; #[derive(Copy, Clone)] //~^ ERROR the trait `Copy` cannot be implemented for this type struct Bar(Foo); +//~^ ERROR `Foo: Clone` is not satisfied fn main() {} diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/issues/issue-27340.stderr index 3353b83f4e5..61ae660f4cf 100644 --- a/tests/ui/issues/issue-27340.stderr +++ b/tests/ui/issues/issue-27340.stderr @@ -9,6 +9,25 @@ LL | struct Bar(Foo); | = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error[E0277]: the trait bound `Foo: Clone` is not satisfied + --> $DIR/issue-27340.rs:4:12 + | +LL | #[derive(Copy, Clone)] + | ----- in this derive macro expansion +LL | +LL | struct Bar(Foo); + | ^^^ the trait `Clone` is not implemented for `Foo` + | +note: required by a bound in `AssertParamIsClone` + --> $SRC_DIR/core/src/clone.rs:LL:COL + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Foo` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct Foo; + | + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0204`. +Some errors have detailed explanations: E0204, E0277. +For more information about an error, try `rustc --explain E0204`. diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr index 71d642109ac..8b427b692a7 100644 --- a/tests/ui/issues/issue-28344.stderr +++ b/tests/ui/issues/issue-28344.stderr @@ -7,7 +7,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8); | ++++ + @@ -35,7 +35,7 @@ LL | let g = BitXor::bitor; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let g = <dyn BitXor>::bitor; | ++++ + diff --git a/tests/ui/issues/issue-35570.rs b/tests/ui/issues/issue-35570.rs index 42bdb423f8f..a2b0222d4f3 100644 --- a/tests/ui/issues/issue-35570.rs +++ b/tests/ui/issues/issue-35570.rs @@ -7,6 +7,7 @@ trait Trait2<'a> { fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) { //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied + //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied let _e: (usize, usize) = unsafe{mem::transmute(param)}; } diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/issues/issue-35570.stderr index f23b55689e3..0aa6b5e402e 100644 --- a/tests/ui/issues/issue-35570.stderr +++ b/tests/ui/issues/issue-35570.stderr @@ -10,6 +10,23 @@ help: this trait has no implementations, consider adding one LL | trait Trait2<'a> { | ^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied + --> $DIR/issue-35570.rs:8:66 + | +LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) { + | __________________________________________________________________^ +LL | | +LL | | +LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)}; +LL | | } + | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-35570.rs:4:1 + | +LL | trait Trait2<'a> { + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-54410.rs b/tests/ui/issues/issue-54410.rs index e3e8ca985b9..51eea3ad9ac 100644 --- a/tests/ui/issues/issue-54410.rs +++ b/tests/ui/issues/issue-54410.rs @@ -5,4 +5,5 @@ extern "C" { fn main() { println!("{:p}", unsafe { &symbol }); + //~^ WARN: shared reference of mutable static is discouraged } diff --git a/tests/ui/issues/issue-54410.stderr b/tests/ui/issues/issue-54410.stderr index 97e5990750e..941c1be3eab 100644 --- a/tests/ui/issues/issue-54410.stderr +++ b/tests/ui/issues/issue-54410.stderr @@ -6,6 +6,21 @@ LL | pub static mut symbol: [i8]; | = help: the trait `Sized` is not implemented for `[i8]` -error: aborting due to 1 previous error +warning: shared reference of mutable static is discouraged + --> $DIR/issue-54410.rs:7:31 + | +LL | println!("{:p}", unsafe { &symbol }); + | ^^^^^^^ shared reference of mutable static + | + = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447> + = note: reference of mutable static is a hard error from 2024 edition + = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior + = note: `#[warn(static_mut_ref)]` on by default +help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer + | +LL | println!("{:p}", unsafe { addr_of!(symbol) }); + | ~~~~~~~~~~~~~~~~ + +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-58734.stderr b/tests/ui/issues/issue-58734.stderr index 5ae1ec7cac8..71581e96844 100644 --- a/tests/ui/issues/issue-58734.stderr +++ b/tests/ui/issues/issue-58734.stderr @@ -7,7 +7,7 @@ LL | Trait::nonexistent(()); = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | <dyn Trait>::nonexistent(()); | ++++ + diff --git a/tests/ui/issues/issue-7364.rs b/tests/ui/issues/issue-7364.rs index 79642bd411b..0608f902fde 100644 --- a/tests/ui/issues/issue-7364.rs +++ b/tests/ui/issues/issue-7364.rs @@ -3,5 +3,6 @@ use std::cell::RefCell; // Regression test for issue 7364 static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0)); //~^ ERROR `RefCell<isize>` cannot be shared between threads safely [E0277] +//~| ERROR cannot call non-const fn fn main() { } diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index 15cb2d875c1..3bf59a6d711 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -11,6 +11,16 @@ note: required because it appears within the type `Box<RefCell<isize>>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL = note: shared static variables must have a type that implements `Sync` -error: aborting due to 1 previous error +error[E0015]: cannot call non-const fn `Box::<RefCell<isize>>::new` in statics + --> $DIR/issue-7364.rs:4:37 + | +LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/issues/issue-86756.stderr index bfa7459ab4a..d0906a6fa74 100644 --- a/tests/ui/issues/issue-86756.stderr +++ b/tests/ui/issues/issue-86756.stderr @@ -21,7 +21,7 @@ LL | eq::<dyn, Foo> = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | eq::<dyn, dyn Foo> | +++ diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs index 1a2ff8c4705..d2b6e1d8eba 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs @@ -16,8 +16,7 @@ struct Other { fn main() { unsafe { - // FIXME(oli-obk): make this report a transmute error again. std::mem::transmute::<Option<()>, Option<&Other>>(None); - //^ ERROR cannot transmute between types of different sizes, or dependently-sized types + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types } } diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr index d17564a1eca..dd5119318ff 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr @@ -4,6 +4,16 @@ error[E0412]: cannot find type `Missing` in this scope LL | Missing: Trait, | ^^^^^^^ not found in this scope -error: aborting due to 1 previous error +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/cannot-transmute-unnormalizable-type.rs:19:9 + | +LL | std::mem::transmute::<Option<()>, Option<&Other>>(None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<()>` (8 bits) + = note: target type: `Option<&Other>` (unable to determine layout for `Other` because `<() as Trait>::RefTarget` cannot be normalized) + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0412, E0512. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/issues/issue-19707.rs b/tests/ui/lifetimes/issue-19707.rs index 6bc7132af3c..6bc7132af3c 100644 --- a/tests/ui/issues/issue-19707.rs +++ b/tests/ui/lifetimes/issue-19707.rs diff --git a/tests/ui/issues/issue-19707.stderr b/tests/ui/lifetimes/issue-19707.stderr index 3e1bb32c19b..3e1bb32c19b 100644 --- a/tests/ui/issues/issue-19707.stderr +++ b/tests/ui/lifetimes/issue-19707.stderr diff --git a/tests/ui/lifetimes/issue-95023.rs b/tests/ui/lifetimes/issue-95023.rs index e35f1a36e2a..ee39a8c49c0 100644 --- a/tests/ui/lifetimes/issue-95023.rs +++ b/tests/ui/lifetimes/issue-95023.rs @@ -9,5 +9,6 @@ impl Fn(&isize) for Error { //~^ ERROR associated function in `impl` without body //~^^ ERROR method `foo` is not a member of trait `Fn` [E0407] //~^^^ ERROR associated type `B` not found for `Self` [E0220] + //~| ERROR associated type `B` not found for `Self` [E0220] } fn main() {} diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr index b9c95d3e49a..0c67d7328f2 100644 --- a/tests/ui/lifetimes/issue-95023.stderr +++ b/tests/ui/lifetimes/issue-95023.stderr @@ -56,7 +56,15 @@ LL | impl Fn(&isize) for Error { | = help: implement the missing item: `fn call(&self, _: (&isize,)) -> <Self as FnOnce<(&isize,)>>::Output { todo!() }` -error: aborting due to 7 previous errors +error[E0220]: associated type `B` not found for `Self` + --> $DIR/issue-95023.rs:8:44 + | +LL | fn foo<const N: usize>(&self) -> Self::B<{ N }>; + | ^ help: `Self` has the following associated type: `Output` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0046, E0183, E0220, E0229, E0277, E0407. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr index c5d72707f80..da1d9f248a0 100644 --- a/tests/ui/lint/bare-trait-objects-path.stderr +++ b/tests/ui/lint/bare-trait-objects-path.stderr @@ -7,7 +7,7 @@ LL | let _: Dyn::Ty; = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let _: <dyn Dyn>::Ty; | ++++ + @@ -26,7 +26,7 @@ LL | Dyn::func(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | <dyn Dyn>::func(); | ++++ + @@ -39,7 +39,7 @@ LL | ::Dyn::func(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | <dyn (::Dyn)>::func(); | ++++++ ++ @@ -52,7 +52,7 @@ LL | Dyn::CONST; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | <dyn Dyn>::CONST; | ++++ + diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr index e9b7b248e61..388dc6160cb 100644 --- a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr +++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr @@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {} = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: requested on the command line with `--force-warn bare-trait-objects` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} | +++ diff --git a/tests/ui/lint/force-warn/cap-lints-allow.stderr b/tests/ui/lint/force-warn/cap-lints-allow.stderr index e569b2f9f1a..a037fb671af 100644 --- a/tests/ui/lint/force-warn/cap-lints-allow.stderr +++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr @@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {} = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: requested on the command line with `--force-warn bare-trait-objects` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} | +++ diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr index c971e4d0d4d..a74cda2239f 100644 --- a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr +++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr @@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {} = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} | +++ diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr index 97b8694984d..c9472a3b9b9 100644 --- a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr +++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr @@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {} = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} | +++ diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr index cd030cc1fcd..558d5cbb531 100644 --- a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr +++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr @@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {} = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} | +++ diff --git a/tests/ui/lint/future-incompat-json-test.stderr b/tests/ui/lint/future-incompat-json-test.stderr index 18fc3f17f00..f33a5cab6ba 100644 --- a/tests/ui/lint/future-incompat-json-test.stderr +++ b/tests/ui/lint/future-incompat-json-test.stderr @@ -1,10 +1,7 @@ -{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x` +{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x` --> $DIR/future-incompat-json-test.rs:9:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` - | - = note: `-A unused-variables` implied by `-A unused` - = help: to override `-A unused` add `#[allow(unused_variables)]` "}}]} diff --git a/tests/ui/lint/future-incompat-test.stderr b/tests/ui/lint/future-incompat-test.stderr index 2951f904fb5..f24e1c7aba4 100644 --- a/tests/ui/lint/future-incompat-test.stderr +++ b/tests/ui/lint/future-incompat-test.stderr @@ -4,7 +4,4 @@ warning: unused variable: `x` | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` - | - = note: `-A unused-variables` implied by `-A unused` - = help: to override `-A unused` add `#[allow(unused_variables)]` diff --git a/tests/ui/lint/issue-121070-let-range.rs b/tests/ui/lint/issue-121070-let-range.rs new file mode 100644 index 00000000000..84598dcd258 --- /dev/null +++ b/tests/ui/lint/issue-121070-let-range.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(let_chains)] +#![allow(irrefutable_let_patterns)] +fn main() { + let _a = 0..1; + + if let x = (0..1) { + eprintln!("x: {:?}", x); + } + if let x = (0..1) && + let _y = (0..2) + { + eprintln!("x: {:?}", x); + } +} diff --git a/tests/ui/issues/issue-19102.rs b/tests/ui/lint/issue-19102.rs index 1f32d10b644..1f32d10b644 100644 --- a/tests/ui/issues/issue-19102.rs +++ b/tests/ui/lint/issue-19102.rs diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 63541943d65..e5d84e464fd 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -239,6 +239,11 @@ unsafe fn bigger_layout() { //~^ ERROR casting references to a bigger memory layout } + { + let x: Box<dyn Send> = Box::new(0i32); + let _z = unsafe { &*(&*x as *const dyn Send as *const i32) }; + } + unsafe fn from_ref(this: &i32) -> &i64 { &*(this as *const i32 as *const i64) } diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr index c6012006164..ea72ef84b9d 100644 --- a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr +++ b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr @@ -60,11 +60,6 @@ LL | foo!(first) = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> = note: macro invocations at the end of a block are treated as expressions = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo` -note: the lint level is defined here - --> $DIR/semicolon-in-expressions-from-macros.rs:24:13 - | -LL | #[allow(semicolon_in_expressions_from_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -79,11 +74,6 @@ LL | let _ = foo!(second); | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> -note: the lint level is defined here - --> $DIR/semicolon-in-expressions-from-macros.rs:29:13 - | -LL | #[allow(semicolon_in_expressions_from_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -98,11 +88,6 @@ LL | let _ = foo!(third); | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> -note: the lint level is defined here - --> $DIR/semicolon-in-expressions-from-macros.rs:32:13 - | -LL | #[allow(semicolon_in_expressions_from_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -117,11 +102,6 @@ LL | let _ = foo!(fourth); | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> -note: the lint level is defined here - --> $DIR/semicolon-in-expressions-from-macros.rs:37:13 - | -LL | #[allow(semicolon_in_expressions_from_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: diff --git a/tests/ui/lowering/issue-121108.rs b/tests/ui/lowering/issue-121108.rs new file mode 100644 index 00000000000..6b2dd24e4a8 --- /dev/null +++ b/tests/ui/lowering/issue-121108.rs @@ -0,0 +1,9 @@ +#![derive(Clone, Copy)] //~ ERROR `derive` attribute cannot be used at crate level + +use std::ptr::addr_of; + +const UNINHABITED_VARIANT: () = unsafe { + let v = *addr_of!(data).cast(); //~ ERROR cannot determine resolution for the macro `addr_of` +}; + +fn main() {} diff --git a/tests/ui/lowering/issue-121108.stderr b/tests/ui/lowering/issue-121108.stderr new file mode 100644 index 00000000000..c2c5746d6f1 --- /dev/null +++ b/tests/ui/lowering/issue-121108.stderr @@ -0,0 +1,25 @@ +error: `derive` attribute cannot be used at crate level + --> $DIR/issue-121108.rs:1:1 + | +LL | #![derive(Clone, Copy)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | use std::ptr::addr_of; + | ------- the inner attribute doesn't annotate this `use` import + | +help: perhaps you meant to use an outer attribute + | +LL - #![derive(Clone, Copy)] +LL + #[derive(Clone, Copy)] + | + +error: cannot determine resolution for the macro `addr_of` + --> $DIR/issue-121108.rs:6:14 + | +LL | let v = *addr_of!(data).cast(); + | ^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to 2 previous errors + diff --git a/tests/ui/mir/issue-121103.rs b/tests/ui/mir/issue-121103.rs new file mode 100644 index 00000000000..e06361a6964 --- /dev/null +++ b/tests/ui/mir/issue-121103.rs @@ -0,0 +1,3 @@ +fn main(_: <lib2::GenericType<42> as lib2::TypeFn>::Output) {} +//~^ ERROR failed to resolve: use of undeclared crate or module `lib2` +//~| ERROR failed to resolve: use of undeclared crate or module `lib2` diff --git a/tests/ui/mir/issue-121103.stderr b/tests/ui/mir/issue-121103.stderr new file mode 100644 index 00000000000..913eee9e0c5 --- /dev/null +++ b/tests/ui/mir/issue-121103.stderr @@ -0,0 +1,15 @@ +error[E0433]: failed to resolve: use of undeclared crate or module `lib2` + --> $DIR/issue-121103.rs:1:38 + | +LL | fn main(_: <lib2::GenericType<42> as lib2::TypeFn>::Output) {} + | ^^^^ use of undeclared crate or module `lib2` + +error[E0433]: failed to resolve: use of undeclared crate or module `lib2` + --> $DIR/issue-121103.rs:1:13 + | +LL | fn main(_: <lib2::GenericType<42> as lib2::TypeFn>::Output) {} + | ^^^^ use of undeclared crate or module `lib2` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/nll/check-normalized-sig-for-wf.rs b/tests/ui/nll/check-normalized-sig-for-wf.rs new file mode 100644 index 00000000000..cb0f34ce02f --- /dev/null +++ b/tests/ui/nll/check-normalized-sig-for-wf.rs @@ -0,0 +1,27 @@ +// <https://github.com/rust-lang/rust/issues/114936> +fn whoops( + s: String, + f: impl for<'s> FnOnce(&'s str) -> (&'static str, [&'static &'s (); 0]), +) -> &'static str +{ + f(&s).0 + //~^ ERROR `s` does not live long enough +} + +// <https://github.com/rust-lang/rust/issues/118876> +fn extend<T>(input: &T) -> &'static T { + struct Bounded<'a, 'b: 'static, T>(&'a T, [&'b (); 0]); + let n: Box<dyn FnOnce(&T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, [])); + n(input).0 + //~^ ERROR borrowed data escapes outside of function +} + +// <https://github.com/rust-lang/rust/issues/118876> +fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T { + struct Bounded<'a, 'b: 'static, T>(&'a mut T, [&'b (); 0]); + let mut n: Box<dyn FnMut(&mut T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, [])); + n(input).0 + //~^ ERROR borrowed data escapes outside of function +} + +fn main() {} diff --git a/tests/ui/nll/check-normalized-sig-for-wf.stderr b/tests/ui/nll/check-normalized-sig-for-wf.stderr new file mode 100644 index 00000000000..5c96b0c6561 --- /dev/null +++ b/tests/ui/nll/check-normalized-sig-for-wf.stderr @@ -0,0 +1,47 @@ +error[E0597]: `s` does not live long enough + --> $DIR/check-normalized-sig-for-wf.rs:7:7 + | +LL | s: String, + | - binding `s` declared here +... +LL | f(&s).0 + | --^^- + | | | + | | borrowed value does not live long enough + | argument requires that `s` is borrowed for `'static` +LL | +LL | } + | - `s` dropped here while still borrowed + +error[E0521]: borrowed data escapes outside of function + --> $DIR/check-normalized-sig-for-wf.rs:15:5 + | +LL | fn extend<T>(input: &T) -> &'static T { + | ----- - let's call the lifetime of this reference `'1` + | | + | `input` is a reference that is only valid in the function body +... +LL | n(input).0 + | ^^^^^^^^ + | | + | `input` escapes the function body here + | argument requires that `'1` must outlive `'static` + +error[E0521]: borrowed data escapes outside of function + --> $DIR/check-normalized-sig-for-wf.rs:23:5 + | +LL | fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T { + | -- ----- `input` is a reference that is only valid in the function body + | | + | lifetime `'a` defined here +... +LL | n(input).0 + | ^^^^^^^^ + | | + | `input` escapes the function body here + | argument requires that `'a` must outlive `'static` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0521, E0597. +For more information about an error, try `rustc --explain E0521`. diff --git a/tests/ui/nll/normalization-bounds-error.rs b/tests/ui/nll/normalization-bounds-error.rs index b6cfcd98732..e7744b53f75 100644 --- a/tests/ui/nll/normalization-bounds-error.rs +++ b/tests/ui/nll/normalization-bounds-error.rs @@ -10,6 +10,7 @@ impl<'a, 'd: 'a> Visitor<'d> for &'a () { } fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} -//~^ ERROR +//~^ ERROR lifetime may not live long enough +//~| ERROR cannot infer fn main() {} diff --git a/tests/ui/nll/normalization-bounds-error.stderr b/tests/ui/nll/normalization-bounds-error.stderr index c6f3f2fd018..d4254881863 100644 --- a/tests/ui/nll/normalization-bounds-error.stderr +++ b/tests/ui/nll/normalization-bounds-error.stderr @@ -22,6 +22,18 @@ LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} = note: expected `Visitor<'d>` found `Visitor<'_>` -error: aborting due to 1 previous error +error: lifetime may not live long enough + --> $DIR/normalization-bounds-error.rs:12:1 + | +LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} + | ^^^^^^^^^^^^^--^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | | + | | | lifetime `'a` defined here + | | lifetime `'d` defined here + | requires that `'d` must outlive `'a` + | + = help: consider adding the following bound: `'d: 'a` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr index 7aec3a73fe9..0bc396390d7 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr @@ -7,6 +7,35 @@ LL | fn id<F>(f: Copy) -> usize { = note: the trait cannot be made into an object because it requires `Self: Sized` = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> -error: aborting due to 1 previous error +error[E0618]: expected function, found `(dyn Copy + 'static)` + --> $DIR/avoid-ice-on-warning-2.rs:11:5 + | +LL | fn id<F>(f: Copy) -> usize { + | - `f` has type `(dyn Copy + 'static)` +... +LL | f() + | ^-- + | | + | call expression requires function + +error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time + --> $DIR/avoid-ice-on-warning-2.rs:4:10 + | +LL | fn id<F>(f: Copy) -> usize { + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` + = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn id<F>(f: impl Copy) -> usize { + | ++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn id<F>(f: &dyn Copy) -> usize { + | ++++ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0277, E0618. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr index 41c09b7df62..f1f33a6c6d6 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr @@ -7,7 +7,7 @@ LL | fn id<F>(f: Copy) -> usize { = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn id<F>(f: dyn Copy) -> usize { | +++ @@ -21,7 +21,7 @@ LL | fn id<F>(f: Copy) -> usize { = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn id<F>(f: dyn Copy) -> usize { | +++ @@ -35,6 +35,35 @@ LL | fn id<F>(f: Copy) -> usize { = note: the trait cannot be made into an object because it requires `Self: Sized` = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> -error: aborting due to 1 previous error; 2 warnings emitted +error[E0618]: expected function, found `(dyn Copy + 'static)` + --> $DIR/avoid-ice-on-warning-2.rs:11:5 + | +LL | fn id<F>(f: Copy) -> usize { + | - `f` has type `(dyn Copy + 'static)` +... +LL | f() + | ^-- + | | + | call expression requires function + +error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time + --> $DIR/avoid-ice-on-warning-2.rs:4:10 + | +LL | fn id<F>(f: Copy) -> usize { + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` + = help: unsized fn params are gated as an unstable feature +help: you can use `impl Trait` as the argument type + | +LL | fn id<F>(f: impl Copy) -> usize { + | ++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn id<F>(f: &dyn Copy) -> usize { + | ++++ + +error: aborting due to 3 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0277, E0618. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.rs b/tests/ui/object-safety/avoid-ice-on-warning-2.rs index 9a6a4378fa3..eabfd31dda6 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.rs +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.rs @@ -3,10 +3,12 @@ //[new] edition:2021 fn id<F>(f: Copy) -> usize { //~^ ERROR the trait `Copy` cannot be made into an object +//~| ERROR: the size for values of type `(dyn Copy + 'static)` //[old]~| WARN trait objects without an explicit `dyn` are deprecated //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //[old]~| WARN trait objects without an explicit `dyn` are deprecated //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! f() + //~^ ERROR: expected function, found `(dyn Copy + 'static)` } fn main() {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr index a36e2519c80..f499e2d946f 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr @@ -7,7 +7,7 @@ LL | trait B { fn f(a: A) -> A; } = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | trait B { fn f(a: dyn A) -> A; } | +++ @@ -20,7 +20,7 @@ LL | trait B { fn f(a: A) -> A; } | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | trait B { fn f(a: A) -> dyn A; } | +++ @@ -33,7 +33,7 @@ LL | trait A { fn g(b: B) -> B; } | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | trait A { fn g(b: dyn B) -> B; } | +++ @@ -46,7 +46,7 @@ LL | trait A { fn g(b: B) -> B; } | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | trait A { fn g(b: B) -> dyn B; } | +++ @@ -60,7 +60,7 @@ LL | trait B { fn f(a: A) -> A; } = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | trait B { fn f(a: dyn A) -> A; } | +++ @@ -96,7 +96,7 @@ LL | trait A { fn g(b: B) -> B; } = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | trait A { fn g(b: dyn B) -> B; } | +++ diff --git a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr index 7c7af968280..3939c06eabe 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr @@ -19,7 +19,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {} = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {} | +++ diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr index 274d5a639a4..f795e910d21 100644 --- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr +++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn ord_prefer_dot(s: String) -> dyn Ord { | +++ diff --git a/tests/ui/object-safety/issue-102762.rs b/tests/ui/object-safety/issue-102762.rs index 4f4c3634528..ed0bee5d37e 100644 --- a/tests/ui/object-safety/issue-102762.rs +++ b/tests/ui/object-safety/issue-102762.rs @@ -22,5 +22,7 @@ fn fetcher() -> Box<dyn Fetcher> { pub fn foo() { let fetcher = fetcher(); + //~^ ERROR the trait `Fetcher` cannot be made into an object let _ = fetcher.get(); + //~^ ERROR the trait `Fetcher` cannot be made into an object } diff --git a/tests/ui/object-safety/issue-102762.stderr b/tests/ui/object-safety/issue-102762.stderr index 2215ec677c5..e746628aa37 100644 --- a/tests/ui/object-safety/issue-102762.stderr +++ b/tests/ui/object-safety/issue-102762.stderr @@ -15,6 +15,40 @@ LL | pub trait Fetcher: Send + Sync { LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> | ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on -error: aborting due to 1 previous error +error[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/issue-102762.rs:24:19 + | +LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + | ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self` +... +LL | let fetcher = fetcher(); + | ^^^^^^^^^ `Fetcher` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-102762.rs:10:22 + | +LL | pub trait Fetcher: Send + Sync { + | ------- this trait cannot be made into an object... +LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + | ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on + +error[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/issue-102762.rs:26:13 + | +LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + | ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self` +... +LL | let _ = fetcher.get(); + | ^^^^^^^^^^^^^ `Fetcher` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-102762.rs:10:22 + | +LL | pub trait Fetcher: Send + Sync { + | ------- this trait cannot be made into an object... +LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>> + | ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-associated-consts.curr.stderr b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr index 462d3d95f13..bd558d36f73 100644 --- a/tests/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -13,6 +13,22 @@ LL | const X: usize; | ^ ...because it contains this associated `const` = help: consider moving `X` to another trait -error: aborting due to 1 previous error +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-associated-consts.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-associated-consts.rs b/tests/ui/object-safety/object-safety-associated-consts.rs index e1a772e5ab2..622f3a0f92e 100644 --- a/tests/ui/object-safety/object-safety-associated-consts.rs +++ b/tests/ui/object-safety/object-safety-associated-consts.rs @@ -12,7 +12,7 @@ trait Bar { fn make_bar<T:Bar>(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t - //[object_safe_for_dispatch]~^ ERROR E0038 + //~^ ERROR E0038 } fn main() { diff --git a/tests/ui/object-safety/object-safety-generics.curr.stderr b/tests/ui/object-safety/object-safety-generics.curr.stderr index 45810375263..85adeace3c7 100644 --- a/tests/ui/object-safety/object-safety-generics.curr.stderr +++ b/tests/ui/object-safety/object-safety-generics.curr.stderr @@ -14,7 +14,7 @@ LL | fn bar<T>(&self, t: T); = help: consider moving `bar` to another trait error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:24:40 + --> $DIR/object-safety-generics.rs:25:40 | LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` cannot be made into an object @@ -28,6 +28,53 @@ LL | fn bar<T>(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait -error: aborting due to 2 previous errors +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:20:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:27:10 + | +LL | t as &dyn Bar + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:27:5 + | +LL | t as &dyn Bar + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar<T>(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index b200b64a1f0..498ad0d8a5e 100644 --- a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -15,7 +15,7 @@ LL | fn bar<T>(&self, t: T); = note: required for the cast from `&T` to `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:26:5 + --> $DIR/object-safety-generics.rs:27:5 | LL | t as &dyn Bar | ^ `Bar` cannot be made into an object diff --git a/tests/ui/object-safety/object-safety-generics.rs b/tests/ui/object-safety/object-safety-generics.rs index 63dcd169925..4528b4ea6e0 100644 --- a/tests/ui/object-safety/object-safety-generics.rs +++ b/tests/ui/object-safety/object-safety-generics.rs @@ -19,12 +19,15 @@ fn make_bar<T:Bar>(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t //[object_safe_for_dispatch]~^ ERROR E0038 + //[curr]~^^ ERROR E0038 } fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t as &dyn Bar //[object_safe_for_dispatch]~^ ERROR E0038 + //[curr]~^^ ERROR E0038 + //[curr]~| ERROR E0038 } fn make_quux<T:Quux>(t: &T) -> &dyn Quux { diff --git a/tests/ui/object-safety/object-safety-issue-22040.rs b/tests/ui/object-safety/object-safety-issue-22040.rs index 1fc5c5442c2..c9ec44cc0b8 100644 --- a/tests/ui/object-safety/object-safety-issue-22040.rs +++ b/tests/ui/object-safety/object-safety-issue-22040.rs @@ -36,7 +36,9 @@ impl <'x> Expr for SExpr<'x> { fn main() { let a: Box<dyn Expr> = Box::new(SExpr::new()); + //~^ ERROR: `Expr` cannot be made into an object let b: Box<dyn Expr> = Box::new(SExpr::new()); + //~^ ERROR: `Expr` cannot be made into an object // assert_eq!(a , b); } diff --git a/tests/ui/object-safety/object-safety-issue-22040.stderr b/tests/ui/object-safety/object-safety-issue-22040.stderr index c9c1437a261..767c232c6ce 100644 --- a/tests/ui/object-safety/object-safety-issue-22040.stderr +++ b/tests/ui/object-safety/object-safety-issue-22040.stderr @@ -13,6 +13,36 @@ LL | trait Expr: Debug + PartialEq { | this trait cannot be made into an object... = help: only type `SExpr<'x>` implements the trait, consider using it directly instead -error: aborting due to 1 previous error +error[E0038]: the trait `Expr` cannot be made into an object + --> $DIR/object-safety-issue-22040.rs:38:16 + | +LL | let a: Box<dyn Expr> = Box::new(SExpr::new()); + | ^^^^^^^^ `Expr` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-issue-22040.rs:5:21 + | +LL | trait Expr: Debug + PartialEq { + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + = help: only type `SExpr<'x>` implements the trait, consider using it directly instead + +error[E0038]: the trait `Expr` cannot be made into an object + --> $DIR/object-safety-issue-22040.rs:40:16 + | +LL | let b: Box<dyn Expr> = Box::new(SExpr::new()); + | ^^^^^^^^ `Expr` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-issue-22040.rs:5:21 + | +LL | trait Expr: Debug + PartialEq { + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + = help: only type `SExpr<'x>` implements the trait, consider using it directly instead + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr index de430a89bf8..28c9c9d64a0 100644 --- a/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -28,6 +28,38 @@ LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type = help: consider moving `baz` to another trait -error: aborting due to 2 previous errors +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:24:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:30:5 + | +LL | t + | ^ `Baz` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + = note: required for the cast from `&T` to `&dyn Baz` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-mentions-Self.rs b/tests/ui/object-safety/object-safety-mentions-Self.rs index 412d16ff3c7..91582aa6a04 100644 --- a/tests/ui/object-safety/object-safety-mentions-Self.rs +++ b/tests/ui/object-safety/object-safety-mentions-Self.rs @@ -22,13 +22,13 @@ trait Quux { fn make_bar<T:Bar>(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t - //[object_safe_for_dispatch]~^ ERROR E0038 + //~^ ERROR E0038 } fn make_baz<T:Baz>(t: &T) -> &dyn Baz { //[curr]~^ ERROR E0038 t - //[object_safe_for_dispatch]~^ ERROR E0038 + //~^ ERROR E0038 } fn make_quux<T:Quux>(t: &T) -> &dyn Quux { diff --git a/tests/ui/object-safety/object-safety-no-static.curr.stderr b/tests/ui/object-safety/object-safety-no-static.curr.stderr index c9e076c6577..8e5b0cbf9dd 100644 --- a/tests/ui/object-safety/object-safety-no-static.curr.stderr +++ b/tests/ui/object-safety/object-safety-no-static.curr.stderr @@ -21,6 +21,53 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o LL | fn foo() where Self: Sized {} | +++++++++++++++++ -error: aborting due to 1 previous error +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:22:12 + | +LL | let b: Box<dyn Foo> = Box::new(Bar); + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:22:27 + | +LL | let b: Box<dyn Foo> = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead + = note: required for the cast from `Box<Bar>` to `Box<dyn Foo>` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-no-static.rs b/tests/ui/object-safety/object-safety-no-static.rs index 03b62217483..abfaa11c9e4 100644 --- a/tests/ui/object-safety/object-safety-no-static.rs +++ b/tests/ui/object-safety/object-safety-no-static.rs @@ -20,5 +20,6 @@ impl Foo for Bar {} fn main() { let b: Box<dyn Foo> = Box::new(Bar); - //[object_safe_for_dispatch]~^ ERROR E0038 + //~^ ERROR E0038 + //[curr]~| ERROR E0038 } diff --git a/tests/ui/object-safety/object-safety-sized-2.curr.stderr b/tests/ui/object-safety/object-safety-sized-2.curr.stderr index 7b91c4d665c..03b078c2a44 100644 --- a/tests/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/tests/ui/object-safety/object-safety-sized-2.curr.stderr @@ -12,6 +12,21 @@ LL | trait Bar LL | where Self : Sized | ^^^^^ ...because it requires `Self: Sized` -error: aborting due to 1 previous error +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized-2.rs:16:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-sized-2.rs b/tests/ui/object-safety/object-safety-sized-2.rs index 1e79b8cd917..607b7c68f7f 100644 --- a/tests/ui/object-safety/object-safety-sized-2.rs +++ b/tests/ui/object-safety/object-safety-sized-2.rs @@ -14,7 +14,7 @@ trait Bar fn make_bar<T:Bar>(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t - //[object_safe_for_dispatch]~^ ERROR E0038 + //~^ ERROR E0038 } fn main() { diff --git a/tests/ui/object-safety/object-safety-sized.curr.stderr b/tests/ui/object-safety/object-safety-sized.curr.stderr index 66b5239745b..0513780a81f 100644 --- a/tests/ui/object-safety/object-safety-sized.curr.stderr +++ b/tests/ui/object-safety/object-safety-sized.curr.stderr @@ -1,17 +1,32 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized.rs:12:31 + --> $DIR/object-safety-sized.rs:12:32 | -LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { - | ^^^^^^^ `Bar` cannot be made into an object +LL | fn make_bar<T: Bar>(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety-sized.rs:8:13 + --> $DIR/object-safety-sized.rs:8:12 | -LL | trait Bar : Sized { - | --- ^^^^^ ...because it requires `Self: Sized` +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -error: aborting due to 1 previous error +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety-sized.rs:8:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 1d0ffcffd04..d988293c0e9 100644 --- a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -5,10 +5,10 @@ LL | t | ^ `Bar` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety-sized.rs:8:13 + --> $DIR/object-safety-sized.rs:8:12 | -LL | trait Bar : Sized { - | --- ^^^^^ ...because it requires `Self: Sized` +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... = note: required for the cast from `&T` to `&dyn Bar` diff --git a/tests/ui/object-safety/object-safety-sized.rs b/tests/ui/object-safety/object-safety-sized.rs index b424b892d3b..ab7aa57611d 100644 --- a/tests/ui/object-safety/object-safety-sized.rs +++ b/tests/ui/object-safety/object-safety-sized.rs @@ -5,15 +5,14 @@ #![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] -trait Bar : Sized { +trait Bar: Sized { fn bar<T>(&self, t: T); } -fn make_bar<T:Bar>(t: &T) -> &dyn Bar { +fn make_bar<T: Bar>(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t - //[object_safe_for_dispatch]~^ ERROR E0038 + //~^ ERROR E0038 } -fn main() { -} +fn main() {} diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.rs b/tests/ui/overloaded/overloaded-calls-nontuple.rs index 32a3b93e0a1..aaae39d8506 100644 --- a/tests/ui/overloaded/overloaded-calls-nontuple.rs +++ b/tests/ui/overloaded/overloaded-calls-nontuple.rs @@ -20,11 +20,12 @@ impl FnOnce<isize> for S { type Output = isize; extern "rust-call" fn call_once(mut self, z: isize) -> isize { //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument - self.call_mut(z) + self.call_mut(z) //~ ERROR `isize` is not a tuple } } fn main() { let mut s = S { x: 1, y: 2 }; - drop(s(3)) + drop(s(3)) //~ ERROR `isize` is not a tuple + //~^ ERROR cannot use call notation } diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.stderr b/tests/ui/overloaded/overloaded-calls-nontuple.stderr index 2e160078259..45a84fc4d7b 100644 --- a/tests/ui/overloaded/overloaded-calls-nontuple.stderr +++ b/tests/ui/overloaded/overloaded-calls-nontuple.stderr @@ -28,7 +28,30 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` -error: aborting due to 4 previous errors +error[E0277]: `isize` is not a tuple + --> $DIR/overloaded-calls-nontuple.rs:23:23 + | +LL | self.call_mut(z) + | -------- ^ the trait `Tuple` is not implemented for `isize` + | | + | required by a bound introduced by this call + | +note: required by a bound in `call_mut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit + --> $DIR/overloaded-calls-nontuple.rs:29:10 + | +LL | drop(s(3)) + | ^^^^ + +error[E0277]: `isize` is not a tuple + --> $DIR/overloaded-calls-nontuple.rs:29:10 + | +LL | drop(s(3)) + | ^^^^ the trait `Tuple` is not implemented for `isize` + +error: aborting due to 7 previous errors Some errors have detailed explanations: E0059, E0277. For more information about an error, try `rustc --explain E0059`. diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr index 5e07a3fe6c7..3134746b930 100644 --- a/tests/ui/parser/trait-object-trait-parens.stderr +++ b/tests/ui/parser/trait-object-trait-parens.stderr @@ -25,7 +25,7 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>; | +++ @@ -49,7 +49,7 @@ LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>; | +++ @@ -73,7 +73,7 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>; | +++ diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs index f1238ec240f..4da9ad84bab 100644 --- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs +++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs @@ -5,9 +5,6 @@ fn f2<'a>(x: u8, y: Vec<&'a ...>) {} //~^ ERROR C-variadic type `...` may not be nested inside another type fn main() { - // While this is an error, wf-checks happen before typeck, and if any wf-checks - // encountered errors, we do not continue to typeck, even if the items are - // unrelated. - // FIXME(oli-obk): make this report a type mismatch again. let _recovery_witness: () = 0; + //~^ ERROR: mismatched types } diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr index 7ca6a6d1bbf..8b9d676a45d 100644 --- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr +++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr @@ -10,6 +10,15 @@ error[E0743]: C-variadic type `...` may not be nested inside another type LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {} | ^^^ -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0743`. +Some errors have detailed explanations: E0308, E0743. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index 59b454d3981..2a1cd3a7aa4 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -20,10 +20,4 @@ LL | if let CONSTANT = &&MyType { = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362> = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/const-partial_eq-fallback-ice.rs:1:10 - | -LL | #![allow(warnings)] - | ^^^^^^^^ - = note: `#[allow(indirect_structural_match)]` implied by `#[allow(warnings)]` diff --git a/tests/ui/proc-macro/bad-projection.rs b/tests/ui/proc-macro/bad-projection.rs index c7cffdc9b47..c3ac624b600 100644 --- a/tests/ui/proc-macro/bad-projection.rs +++ b/tests/ui/proc-macro/bad-projection.rs @@ -14,4 +14,5 @@ trait Project { pub fn uwu() -> <() as Project>::Assoc {} //~^ ERROR the trait bound `(): Project` is not satisfied //~| ERROR the trait bound `(): Project` is not satisfied +//~| ERROR the trait bound `(): Project` is not satisfied //~| ERROR function is expected to take 1 argument, but it takes 0 arguments diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr index aea5d6d7c84..8e0d8461849 100644 --- a/tests/ui/proc-macro/bad-projection.stderr +++ b/tests/ui/proc-macro/bad-projection.stderr @@ -35,7 +35,19 @@ help: this trait has no implementations, consider adding one LL | trait Project { | ^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error[E0277]: the trait bound `(): Project` is not satisfied + --> $DIR/bad-projection.rs:14:40 + | +LL | pub fn uwu() -> <() as Project>::Assoc {} + | ^^ the trait `Project` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/bad-projection.rs:9:1 + | +LL | trait Project { + | ^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0593. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/proc-macro/generate-mod.stderr b/tests/ui/proc-macro/generate-mod.stderr index db629b5b5e2..cbe6b14ca9a 100644 --- a/tests/ui/proc-macro/generate-mod.stderr +++ b/tests/ui/proc-macro/generate-mod.stderr @@ -139,11 +139,6 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> -note: the lint level is defined here - --> $DIR/generate-mod.rs:30:10 - | -LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -155,10 +150,5 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> -note: the lint level is defined here - --> $DIR/generate-mod.rs:30:10 - | -LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index a0d619c4566..1e387326b2e 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -14,7 +14,9 @@ struct PriorityQueueEntry<T> { //~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>` //~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied //~| ERROR can't compare `T` with `T` +//~| ERROR `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator +//~| ERROR no field `height` on type `&PriorityQueue<T>` struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); - +//~^ ERROR can't compare `BinaryHeap<PriorityQueueEntry<T>>` with `_` fn main() {} diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index 3b2a5e70188..6fa639877d3 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -34,6 +34,38 @@ note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL = note: this error originates in the derive macro `AddImpl` which comes from the expansion of the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error[E0277]: can't compare `BinaryHeap<PriorityQueueEntry<T>>` with `_` + --> $DIR/issue-104884-trait-impl-sugg-err.rs:20:25 + | +LL | #[derive(PartialOrd, AddImpl)] + | ---------- in this derive macro expansion +... +LL | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `BinaryHeap<PriorityQueueEntry<T>> < _` and `BinaryHeap<PriorityQueueEntry<T>> > _` + | + = help: the trait `PartialOrd<_>` is not implemented for `BinaryHeap<PriorityQueueEntry<T>>` + = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0599]: `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator + --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 + | +LL | #[derive(PartialOrd, AddImpl)] + | ^^^^^^^ `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `BinaryHeap<PriorityQueueEntry<T>>: Iterator` + which is required by `&mut BinaryHeap<PriorityQueueEntry<T>>: Iterator` + = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0609]: no field `height` on type `&PriorityQueue<T>` + --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 + | +LL | #[derive(PartialOrd, AddImpl)] + | ^^^^^^^ unknown field + | + = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0599, E0609. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/recursion/recursive-static-definition.rs b/tests/ui/recursion/recursive-static-definition.rs index f59ef7316d8..5317c47076e 100644 --- a/tests/ui/recursion/recursive-static-definition.rs +++ b/tests/ui/recursion/recursive-static-definition.rs @@ -1,4 +1,12 @@ pub static FOO: u32 = FOO; -//~^ ERROR cycle detected when const-evaluating + checking `FOO` +//~^ ERROR could not evaluate static initializer + +#[derive(Copy, Clone)] +pub union Foo { + x: u32, +} + +pub static BAR: Foo = BAR; +//~^ ERROR could not evaluate static initializer fn main() {} diff --git a/tests/ui/recursion/recursive-static-definition.stderr b/tests/ui/recursion/recursive-static-definition.stderr index 4fc3ee68ebc..86a22c990e9 100644 --- a/tests/ui/recursion/recursive-static-definition.stderr +++ b/tests/ui/recursion/recursive-static-definition.stderr @@ -1,20 +1,15 @@ -error[E0391]: cycle detected when const-evaluating + checking `FOO` +error[E0080]: could not evaluate static initializer --> $DIR/recursive-static-definition.rs:1:23 | LL | pub static FOO: u32 = FOO; - | ^^^ - | - = note: ...which immediately requires const-evaluating + checking `FOO` again -note: cycle used when linting top-level module - --> $DIR/recursive-static-definition.rs:1:1 + | ^^^ encountered static that tried to initialize itself with itself + +error[E0080]: could not evaluate static initializer + --> $DIR/recursive-static-definition.rs:9:23 | -LL | / pub static FOO: u32 = FOO; -LL | | -LL | | -LL | | fn main() {} - | |____________^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +LL | pub static BAR: Foo = BAR; + | ^^^ encountered static that tried to initialize itself with itself -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/regions/regions-free-region-ordering-callee-4.rs b/tests/ui/regions/regions-free-region-ordering-callee-4.rs index de58dd0b10f..af9f3124cc7 100644 --- a/tests/ui/regions/regions-free-region-ordering-callee-4.rs +++ b/tests/ui/regions/regions-free-region-ordering-callee-4.rs @@ -6,6 +6,7 @@ fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &' //~^ ERROR reference has a longer lifetime than the data it references // Do not infer ordering from closure argument types. let z: Option<&'a &'b usize> = None; + //~^ ERROR may not live long enough } fn main() {} diff --git a/tests/ui/regions/regions-free-region-ordering-callee-4.stderr b/tests/ui/regions/regions-free-region-ordering-callee-4.stderr index 1c8f1c1e472..e6218079952 100644 --- a/tests/ui/regions/regions-free-region-ordering-callee-4.stderr +++ b/tests/ui/regions/regions-free-region-ordering-callee-4.stderr @@ -15,6 +15,19 @@ note: but the referenced data is only valid for the lifetime `'b` as defined her LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { | ^^ -error: aborting due to 1 previous error +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-callee-4.rs:8:12 + | +LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let z: Option<&'a &'b usize> = None; + | ^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0491`. diff --git a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs index 429548f119b..4d77a551f64 100644 --- a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs +++ b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs @@ -21,6 +21,7 @@ trait Trait2<'a, 'b> { fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >) //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied { + //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied } fn main() { } diff --git a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index 1555e5981c5..b17d1e0ab11 100644 --- a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -9,6 +9,19 @@ help: consider restricting type parameter `T` LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >) | ++++++++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:23:1 + | +LL | / { +LL | | +LL | | } + | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >) + | ++++++++++++++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/resolve/issue-120559.rs b/tests/ui/resolve/issue-120559.rs new file mode 100644 index 00000000000..e874e840de7 --- /dev/null +++ b/tests/ui/resolve/issue-120559.rs @@ -0,0 +1,5 @@ +use std::io::Read; + +fn f<T: Read, U, Read>() {} //~ ERROR expected trait, found type parameter `Read` + +fn main() {} diff --git a/tests/ui/resolve/issue-120559.stderr b/tests/ui/resolve/issue-120559.stderr new file mode 100644 index 00000000000..9150fb38ad5 --- /dev/null +++ b/tests/ui/resolve/issue-120559.stderr @@ -0,0 +1,14 @@ +error[E0404]: expected trait, found type parameter `Read` + --> $DIR/issue-120559.rs:3:9 + | +LL | use std::io::Read; + | ---- you might have meant to refer to this trait +LL | +LL | fn f<T: Read, U, Read>() {} + | ^^^^ ---- found this type parameter + | | + | not a trait + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/resolve/issue-3907-2.rs b/tests/ui/resolve/issue-3907-2.rs index 46f145e63e1..0ebaea08e18 100644 --- a/tests/ui/resolve/issue-3907-2.rs +++ b/tests/ui/resolve/issue-3907-2.rs @@ -10,5 +10,6 @@ struct S { fn bar(_x: Foo) {} //~^ ERROR E0038 +//~| ERROR E0277 fn main() {} diff --git a/tests/ui/resolve/issue-3907-2.stderr b/tests/ui/resolve/issue-3907-2.stderr index 2693daa3c7a..364edb788c6 100644 --- a/tests/ui/resolve/issue-3907-2.stderr +++ b/tests/ui/resolve/issue-3907-2.stderr @@ -10,6 +10,20 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all LL | fn bar(); | ^^^ the trait cannot be made into an object because associated function `bar` has no `self` parameter -error: aborting due to 1 previous error +error[E0277]: the size for values of type `(dyn issue_3907::Foo + 'static)` cannot be known at compilation time + --> $DIR/issue-3907-2.rs:11:8 + | +LL | fn bar(_x: Foo) {} + | ^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn issue_3907::Foo + 'static)` + = help: unsized fn params are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn bar(_x: &Foo) {} + | + + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr index 5210a694201..e5b9493b3ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr @@ -7,6 +7,16 @@ LL | impl<T: Default> A for T { LL | impl<T: Default + ~const Sup> const A for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/specializing-constness-2.rs:27:5 + | +LL | <T as A>::a(); + | ^^^^^^^^^^^^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0119, E0308. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index 4cc69666b88..bd0519f66c0 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -9,6 +9,7 @@ LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) +ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not? error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs index 883d718c49b..27a7df17d66 100644 --- a/tests/ui/simd/array-trait.rs +++ b/tests/ui/simd/array-trait.rs @@ -23,6 +23,7 @@ impl Simd for i32x4 { pub struct T<S: Simd>([S::Lane; S::SIZE]); //~^ ERROR unconstrained generic constant //~| ERROR SIMD vector element type should be a primitive scalar +//~| ERROR unconstrained generic constant extern "platform-intrinsic" { fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T; @@ -37,6 +38,7 @@ pub fn main() { } for i in 0_i32..4 { assert_eq!(i, simd_extract(t, i as u32)); + //~^ ERROR: use of moved value: `t` } } } diff --git a/tests/ui/simd/array-trait.stderr b/tests/ui/simd/array-trait.stderr index cf6026912aa..bbaead569df 100644 --- a/tests/ui/simd/array-trait.stderr +++ b/tests/ui/simd/array-trait.stderr @@ -12,6 +12,29 @@ error[E0077]: SIMD vector element type should be a primitive scalar (integer/flo LL | pub struct T<S: Simd>([S::Lane; S::SIZE]); | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: unconstrained generic constant + --> $DIR/array-trait.rs:23:23 + | +LL | #[derive(Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct T<S: Simd>([S::Lane; S::SIZE]); + | ^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); S::SIZE]:` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0382]: use of moved value: `t` + --> $DIR/array-trait.rs:40:40 + | +LL | let mut t = T::<i32x4>([0; 4]); + | ----- move occurs because `t` has type `T<i32x4>`, which does not implement the `Copy` trait +... +LL | for i in 0_i32..4 { + | ----------------- inside of this loop +LL | assert_eq!(i, simd_extract(t, i as u32)); + | ^ value moved here, in previous iteration of loop + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0077`. +Some errors have detailed explanations: E0077, E0382. +For more information about an error, try `rustc --explain E0077`. diff --git a/tests/ui/span/issue-35987.stderr b/tests/ui/span/issue-35987.stderr index 4c4b100da3d..d3014f276fd 100644 --- a/tests/ui/span/issue-35987.stderr +++ b/tests/ui/span/issue-35987.stderr @@ -8,11 +8,6 @@ LL | impl<T: Clone, Add> Add for Foo<T> { | --- ^^^ not a trait | | | found this type parameter - | -help: consider importing this trait instead - | -LL + use std::ops::Add; - | error: aborting due to 1 previous error diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs index 6834d573629..344dd7bb288 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs +++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs @@ -20,5 +20,5 @@ default impl<T> Foo for T { fn main() { println!("{}", MyStruct.foo_one()); - //~^ ERROR the method + //~^ ERROR no method named `foo_one` found for struct `MyStruct` in the current scope } diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index e9b0845ccf7..74f81bb023e 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -8,27 +8,15 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait bounds were not satisfied +error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope --> $DIR/specialization-trait-not-implemented.rs:22:29 | LL | struct MyStruct; - | --------------- method `foo_one` not found for this struct because it doesn't satisfy `MyStruct: Foo` + | --------------- method `foo_one` not found for this struct ... LL | println!("{}", MyStruct.foo_one()); - | ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds + | ^^^^^^^ method not found in `MyStruct` | -note: trait bound `MyStruct: Foo` was not satisfied - --> $DIR/specialization-trait-not-implemented.rs:14:1 - | -LL | default impl<T> Foo for T { - | ^^^^^^^^^^^^^^^^---^^^^^- - | | - | unsatisfied trait bound introduced here -note: the trait `Foo` must be implemented - --> $DIR/specialization-trait-not-implemented.rs:7:1 - | -LL | trait Foo { - | ^^^^^^^^^ = help: items from traits can only be used if the trait is implemented and in scope note: `Foo` defines an item `foo_one`, perhaps you need to implement it --> $DIR/specialization-trait-not-implemented.rs:7:1 diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs index 8558a1efb82..4049c4ea14c 100644 --- a/tests/ui/specialization/defaultimpl/validation.rs +++ b/tests/ui/specialization/defaultimpl/validation.rs @@ -7,6 +7,7 @@ struct Z; default impl S {} //~ ERROR inherent impls cannot be `default` default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default +//~^ ERROR `S` cannot be sent between threads safely default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default //~^ ERROR negative impls cannot be default impls diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr index eb6dc9355a3..5f62e8dce17 100644 --- a/tests/ui/specialization/defaultimpl/validation.stderr +++ b/tests/ui/specialization/defaultimpl/validation.stderr @@ -26,8 +26,19 @@ LL | default unsafe impl Send for S {} | | | default because of this +error[E0277]: `S` cannot be sent between threads safely + --> $DIR/validation.rs:9:1 + | +LL | default unsafe impl Send for S {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `S` + = help: the trait `Send` is implemented for `S` + = help: see issue #48214 + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable + error: impls of auto traits cannot be default - --> $DIR/validation.rs:10:15 + --> $DIR/validation.rs:11:15 | LL | default impl !Send for Z {} | ------- ^^^^ auto trait @@ -35,17 +46,18 @@ LL | default impl !Send for Z {} | default because of this error[E0750]: negative impls cannot be default impls - --> $DIR/validation.rs:10:1 + --> $DIR/validation.rs:11:1 | LL | default impl !Send for Z {} | ^^^^^^^ ^ error[E0750]: negative impls cannot be default impls - --> $DIR/validation.rs:14:1 + --> $DIR/validation.rs:15:1 | LL | default impl !Tr for S {} | ^^^^^^^ ^ -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0750`. +Some errors have detailed explanations: E0277, E0750. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/specialization/issue-45814.current.stderr b/tests/ui/specialization/issue-45814.current.stderr index da0dff78e26..b89d3073a8f 100644 --- a/tests/ui/specialization/issue-45814.current.stderr +++ b/tests/ui/specialization/issue-45814.current.stderr @@ -1,14 +1,12 @@ -error[E0275]: overflow evaluating the requirement `T: Trait<_>` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`) -note: required for `T` to implement `Trait<_>` - --> $DIR/issue-45814.rs:9:20 +error[E0119]: conflicting implementations of trait `Trait<_>` + --> $DIR/issue-45814.rs:10:1 | LL | default impl<T, U> Trait<T> for U {} - | ^^^^^^^^ ^ - = note: 128 redundant requirements hidden - = note: required for `T` to implement `Trait<_>` + | --------------------------------- first implementation here +LL | +LL | impl<T> Trait<<T as Iterator>::Item> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/issue-45814.negative.stderr b/tests/ui/specialization/issue-45814.negative.stderr index da0dff78e26..b89d3073a8f 100644 --- a/tests/ui/specialization/issue-45814.negative.stderr +++ b/tests/ui/specialization/issue-45814.negative.stderr @@ -1,14 +1,12 @@ -error[E0275]: overflow evaluating the requirement `T: Trait<_>` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`) -note: required for `T` to implement `Trait<_>` - --> $DIR/issue-45814.rs:9:20 +error[E0119]: conflicting implementations of trait `Trait<_>` + --> $DIR/issue-45814.rs:10:1 | LL | default impl<T, U> Trait<T> for U {} - | ^^^^^^^^ ^ - = note: 128 redundant requirements hidden - = note: required for `T` to implement `Trait<_>` + | --------------------------------- first implementation here +LL | +LL | impl<T> Trait<<T as Iterator>::Item> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/issue-45814.rs b/tests/ui/specialization/issue-45814.rs index fce236390c2..832d734d945 100644 --- a/tests/ui/specialization/issue-45814.rs +++ b/tests/ui/specialization/issue-45814.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow evaluating the requirement `T: Trait<_>` // revisions: current negative #![feature(specialization)] #![cfg_attr(negative, feature(with_negative_coherence))] @@ -9,5 +8,6 @@ pub trait Trait<T> {} default impl<T, U> Trait<T> for U {} impl<T> Trait<<T as Iterator>::Item> for T {} +//~^ ERROR conflicting implementations of trait `Trait<_>` fn main() {} diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs index a0ee7714417..f89a463bc58 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs @@ -6,6 +6,7 @@ struct S<const L: usize>; impl<const N: i32> Copy for S<N> {} +//~^ ERROR: mismatched types impl<const M: usize> Copy for S<M> {} //~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>` diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr index 2953bc95917..1dac58e1f69 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr @@ -1,11 +1,19 @@ error[E0119]: conflicting implementations of trait `Copy` for type `S<_>` - --> $DIR/bad-const-wf-doesnt-specialize.rs:9:1 + --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1 | LL | impl<const N: i32> Copy for S<N> {} | -------------------------------- first implementation here +LL | LL | impl<const M: usize> Copy for S<M> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31 + | +LL | impl<const N: i32> Copy for S<N> {} + | ^ expected `usize`, found `i32` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0119, E0308. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/min_specialization/issue-79224.rs b/tests/ui/specialization/min_specialization/issue-79224.rs index a118cb28b38..6ddd3d79ccf 100644 --- a/tests/ui/specialization/min_specialization/issue-79224.rs +++ b/tests/ui/specialization/min_specialization/issue-79224.rs @@ -20,6 +20,7 @@ impl<B: ?Sized> Display for Cow<'_, B> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277] + //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277] write!(f, "foo") } } diff --git a/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr index da19ed44ce6..db88be88a81 100644 --- a/tests/ui/specialization/min_specialization/issue-79224.stderr +++ b/tests/ui/specialization/min_specialization/issue-79224.stderr @@ -34,6 +34,24 @@ help: consider further restricting this bound LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> { | +++++++++++++++++++ -error: aborting due to 3 previous errors +error[E0277]: the trait bound `B: Clone` is not satisfied + --> $DIR/issue-79224.rs:20:62 + | +LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + | ______________________________________________________________^ +LL | | +LL | | +LL | | +LL | | write!(f, "foo") +LL | | } + | |_____^ the trait `Clone` is not implemented for `B`, which is required by `B: ToOwned` + | + = note: required for `B` to implement `ToOwned` +help: consider further restricting this bound + | +LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> { + | +++++++++++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/statics/recursive_interior_mut.rs b/tests/ui/statics/recursive_interior_mut.rs new file mode 100644 index 00000000000..7e3083909d5 --- /dev/null +++ b/tests/ui/statics/recursive_interior_mut.rs @@ -0,0 +1,20 @@ +// check-pass + +use std::cell::Cell; +use std::ptr::NonNull; + +struct ChunkFooter { + prev: Cell<NonNull<ChunkFooter>>, +} + +struct EmptyChunkFooter(ChunkFooter); + +unsafe impl Sync for EmptyChunkFooter {} + +static EMPTY_CHUNK: EmptyChunkFooter = EmptyChunkFooter(ChunkFooter { + prev: Cell::new(unsafe { + NonNull::new_unchecked(&EMPTY_CHUNK as *const EmptyChunkFooter as *mut ChunkFooter) + }), +}); + +fn main() {} diff --git a/tests/ui/suggestions/fn-trait-notation.fixed b/tests/ui/suggestions/fn-trait-notation.fixed index 6cb97df4a85..fcf00a17002 100644 --- a/tests/ui/suggestions/fn-trait-notation.fixed +++ b/tests/ui/suggestions/fn-trait-notation.fixed @@ -7,12 +7,14 @@ where H: Fn(i32) -> i32, //~ ERROR E0658 { f(3); + //~^ ERROR: cannot use call notation + //~| ERROR: `i32` is not a tuple g(3, 4); h(3) } fn main() { - e0658( + e0658( //~ ERROR: mismatched types |a| a, |a, b| (b, a), |a| a, diff --git a/tests/ui/suggestions/fn-trait-notation.rs b/tests/ui/suggestions/fn-trait-notation.rs index 91251614930..715bcf71d47 100644 --- a/tests/ui/suggestions/fn-trait-notation.rs +++ b/tests/ui/suggestions/fn-trait-notation.rs @@ -7,12 +7,14 @@ where H: Fn<(i32,), Output = i32>, //~ ERROR E0658 { f(3); + //~^ ERROR: cannot use call notation + //~| ERROR: `i32` is not a tuple g(3, 4); h(3) } fn main() { - e0658( + e0658( //~ ERROR: mismatched types |a| a, |a, b| (b, a), |a| a, diff --git a/tests/ui/suggestions/fn-trait-notation.stderr b/tests/ui/suggestions/fn-trait-notation.stderr index b221af18bfc..9b47c8c02a7 100644 --- a/tests/ui/suggestions/fn-trait-notation.stderr +++ b/tests/ui/suggestions/fn-trait-notation.stderr @@ -37,7 +37,40 @@ LL | F: Fn<i32, Output = i32>, note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL -error: aborting due to 4 previous errors +error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit + --> $DIR/fn-trait-notation.rs:9:5 + | +LL | f(3); + | ^^^^ + +error[E0277]: `i32` is not a tuple + --> $DIR/fn-trait-notation.rs:9:5 + | +LL | f(3); + | ^^^^ the trait `Tuple` is not implemented for `i32` + +error[E0308]: mismatched types + --> $DIR/fn-trait-notation.rs:17:5 + | +LL | / e0658( +LL | | |a| a, +LL | | |a, b| (b, a), +LL | | |a| a, +LL | | ); + | |_____^ types differ + | + = note: expected trait `Fn<i32>` + found trait `Fn(_)` +note: required by a bound in `e0658` + --> $DIR/fn-trait-notation.rs:4:8 + | +LL | fn e0658<F, G, H>(f: F, g: G, h: H) -> i32 + | ----- required by a bound in this function +LL | where +LL | F: Fn<i32, Output = i32>, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `e0658` + +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0059, E0658. +Some errors have detailed explanations: E0059, E0277, E0308, E0658. For more information about an error, try `rustc --explain E0059`. diff --git a/tests/ui/suggestions/issue-116434-2015.rs b/tests/ui/suggestions/issue-116434-2015.rs new file mode 100644 index 00000000000..614fc27b771 --- /dev/null +++ b/tests/ui/suggestions/issue-116434-2015.rs @@ -0,0 +1,23 @@ +trait Foo { + type Clone; + fn foo() -> Clone; + //~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| ERROR the trait `Clone` cannot be made into an object [E0038] +} + +trait DbHandle: Sized {} + +trait DbInterface { + type DbHandle; + fn handle() -> DbHandle; + //~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| ERROR the trait `DbHandle` cannot be made into an object [E0038] +} + +fn main() {} diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr new file mode 100644 index 00000000000..2d87029b6eb --- /dev/null +++ b/tests/ui/suggestions/issue-116434-2015.stderr @@ -0,0 +1,81 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-116434-2015.rs:3:17 + | +LL | fn foo() -> Clone; + | ^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is an object-safe trait, use `dyn` + | +LL | fn foo() -> dyn Clone; + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-116434-2015.rs:15:20 + | +LL | fn handle() -> DbHandle; + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: if this is an object-safe trait, use `dyn` + | +LL | fn handle() -> dyn DbHandle; + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-116434-2015.rs:3:17 + | +LL | fn foo() -> Clone; + | ^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is an object-safe trait, use `dyn` + | +LL | fn foo() -> dyn Clone; + | +++ + +error[E0038]: the trait `Clone` cannot be made into an object + --> $DIR/issue-116434-2015.rs:3:17 + | +LL | fn foo() -> Clone; + | ^^^^^ `Clone` cannot be made into an object + | + = note: the trait cannot be made into an object because it requires `Self: Sized` + = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-116434-2015.rs:15:20 + | +LL | fn handle() -> DbHandle; + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is an object-safe trait, use `dyn` + | +LL | fn handle() -> dyn DbHandle; + | +++ + +error[E0038]: the trait `DbHandle` cannot be made into an object + --> $DIR/issue-116434-2015.rs:15:20 + | +LL | fn handle() -> DbHandle; + | ^^^^^^^^ `DbHandle` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-116434-2015.rs:11:17 + | +LL | trait DbHandle: Sized {} + | -------- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + +error: aborting due to 2 previous errors; 4 warnings emitted + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/suggestions/issue-116434-2021.rs b/tests/ui/suggestions/issue-116434-2021.rs new file mode 100644 index 00000000000..74c30e0cc1f --- /dev/null +++ b/tests/ui/suggestions/issue-116434-2021.rs @@ -0,0 +1,17 @@ +// edition:2021 + +trait Foo { + type Clone; + fn foo() -> Clone; + //~^ ERROR the trait `Clone` cannot be made into an object [E0038] +} + +trait DbHandle: Sized {} + +trait DbInterface { + type DbHandle; + fn handle() -> DbHandle; + //~^ ERROR the trait `DbHandle` cannot be made into an object [E0038] +} + +fn main() {} diff --git a/tests/ui/suggestions/issue-116434-2021.stderr b/tests/ui/suggestions/issue-116434-2021.stderr new file mode 100644 index 00000000000..43ad82d484a --- /dev/null +++ b/tests/ui/suggestions/issue-116434-2021.stderr @@ -0,0 +1,26 @@ +error[E0038]: the trait `Clone` cannot be made into an object + --> $DIR/issue-116434-2021.rs:5:17 + | +LL | fn foo() -> Clone; + | ^^^^^ `Clone` cannot be made into an object + | + = note: the trait cannot be made into an object because it requires `Self: Sized` + = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + +error[E0038]: the trait `DbHandle` cannot be made into an object + --> $DIR/issue-116434-2021.rs:13:20 + | +LL | fn handle() -> DbHandle; + | ^^^^^^^^ `DbHandle` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-116434-2021.rs:9:17 + | +LL | trait DbHandle: Sized {} + | -------- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/suggestions/issue-61963.stderr b/tests/ui/suggestions/issue-61963.stderr index 754d02b1c02..084b0cbeef2 100644 --- a/tests/ui/suggestions/issue-61963.stderr +++ b/tests/ui/suggestions/issue-61963.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | bar: Box<dyn Bar>, | +++ @@ -24,7 +24,7 @@ LL | pub struct Foo { | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | dyn pub struct Foo { | +++ diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed index ac0b14fba83..269ebd2b75a 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.fixed @@ -2,15 +2,17 @@ use std::fmt::Debug; #[derive(Debug, Copy, Clone)] -pub struct Vector2<T: Debug + Copy + Clone>{ +pub struct Vector2<T: Debug + Copy + Clone> { pub x: T, - pub y: T + pub y: T, } #[derive(Debug, Copy, Clone)] -pub struct AABB<K: Debug + std::marker::Copy>{ +pub struct AABB<K: Debug + std::marker::Copy + std::marker::Copy + std::marker::Copy + std::marker::Copy> { pub loc: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied - pub size: Vector2<K> + //~^ ERROR the trait bound `K: Copy` is not satisfied + //~| ERROR the trait bound `K: Copy` is not satisfied + pub size: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied } fn main() {} diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs index 31f8cd6fcf7..e9455f918bc 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.rs @@ -2,15 +2,17 @@ use std::fmt::Debug; #[derive(Debug, Copy, Clone)] -pub struct Vector2<T: Debug + Copy + Clone>{ +pub struct Vector2<T: Debug + Copy + Clone> { pub x: T, - pub y: T + pub y: T, } #[derive(Debug, Copy, Clone)] -pub struct AABB<K: Debug>{ +pub struct AABB<K: Debug> { pub loc: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied - pub size: Vector2<K> + //~^ ERROR the trait bound `K: Copy` is not satisfied + //~| ERROR the trait bound `K: Copy` is not satisfied + pub size: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied } fn main() {} diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index f9db1e1ec00..a2a78ddc705 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -7,13 +7,80 @@ LL | pub loc: Vector2<K>, note: required by a bound in `Vector2` --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:31 | -LL | pub struct Vector2<T: Debug + Copy + Clone>{ +LL | pub struct Vector2<T: Debug + Copy + Clone> { | ^^^^ required by this bound in `Vector2` help: consider further restricting this bound | -LL | pub struct AABB<K: Debug + std::marker::Copy>{ +LL | pub struct AABB<K: Debug + std::marker::Copy> { | +++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `K: Copy` is not satisfied + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:12:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct AABB<K: Debug> { +LL | pub loc: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Debug` + | +note: required for `Vector2<K>` to implement `Debug` + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +LL | pub struct Vector2<T: Debug + Copy + Clone> { + | ---- unsatisfied trait bound introduced in this `derive` macro + = note: required for the cast from `&Vector2<K>` to `&dyn Debug` + = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting this bound + | +LL | pub struct AABB<K: Debug + std::marker::Copy> { + | +++++++++++++++++++ + +error[E0277]: the trait bound `K: Copy` is not satisfied + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:12:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct AABB<K: Debug> { +LL | pub loc: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone` + | +note: required for `Vector2<K>` to implement `Clone` + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +LL | pub struct Vector2<T: Debug + Copy + Clone> { + | ---- unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting this bound + | +LL | pub struct AABB<K: Debug + std::marker::Copy> { + | +++++++++++++++++++ + +error[E0277]: the trait bound `K: Copy` is not satisfied + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:15:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub size: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone` + | +note: required for `Vector2<K>` to implement `Clone` + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +LL | pub struct Vector2<T: Debug + Copy + Clone> { + | ---- unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting this bound + | +LL | pub struct AABB<K: Debug + std::marker::Copy> { + | +++++++++++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed index 53476ee8c59..8a91e2d5f0d 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed @@ -8,9 +8,10 @@ pub struct Vector2<T: Debug + Copy + Clone>{ } #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB<K: Copy + Debug + std::fmt::Debug>{ +pub struct AABB<K: Copy + Debug + std::fmt::Debug + std::fmt::Debug + std::fmt::Debug>{ pub loc: Vector2<K>, //~ ERROR `K` doesn't implement `Debug` - pub size: Vector2<K> + //~^ ERROR `K` doesn't implement `Debug` + pub size: Vector2<K> //~ ERROR `K` doesn't implement `Debug` } fn main() {} diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs index 08c4f344e4e..c10f9d46010 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs @@ -10,7 +10,8 @@ pub struct Vector2<T: Debug + Copy + Clone>{ #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type pub struct AABB<K: Copy>{ pub loc: Vector2<K>, //~ ERROR `K` doesn't implement `Debug` - pub size: Vector2<K> + //~^ ERROR `K` doesn't implement `Debug` + pub size: Vector2<K> //~ ERROR `K` doesn't implement `Debug` } fn main() {} diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr index bfb96b4076b..2ade0e974e4 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr @@ -34,7 +34,37 @@ help: consider further restricting this bound LL | pub struct AABB<K: Copy + std::fmt::Debug>{ | +++++++++++++++++ -error: aborting due to 2 previous errors +error[E0277]: `K` doesn't implement `Debug` + --> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct AABB<K: Copy>{ +LL | pub loc: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting this bound + | +LL | pub struct AABB<K: Copy + std::fmt::Debug>{ + | +++++++++++++++++ + +error[E0277]: `K` doesn't implement `Debug` + --> $DIR/missing-bound-in-derive-copy-impl-3.rs:14:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub size: Vector2<K> + | ^^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting this bound + | +LL | pub struct AABB<K: Copy + std::fmt::Debug>{ + | +++++++++++++++++ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0204, E0277. For more information about an error, try `rustc --explain E0204`. diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs index 2f1ebc1f133..0ffc1b8f7a2 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs @@ -1,17 +1,22 @@ use std::fmt::Debug; #[derive(Debug, Copy, Clone)] -pub struct Vector2<T: Debug + Copy + Clone>{ +pub struct Vector2<T: Debug + Copy + Clone> { pub x: T, - pub y: T + pub y: T, } #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB<K>{ +pub struct AABB<K> { pub loc: Vector2<K>, //~^ ERROR doesn't implement `Debug` //~| ERROR `K: Copy` is not satisfied - pub size: Vector2<K> + //~| ERROR doesn't implement `Debug` + //~| ERROR `K: Copy` is not satisfied + //~| ERROR `K: Copy` is not satisfied + pub size: Vector2<K>, + //~^ ERROR doesn't implement `Debug` + //~| ERROR `K: Copy` is not satisfied } fn main() {} diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index f3213e1a4c8..2ae0871b815 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -3,7 +3,7 @@ error[E0204]: the trait `Copy` cannot be implemented for this type | LL | #[derive(Debug, Copy, Clone)] | ^^^^ -LL | pub struct AABB<K>{ +LL | pub struct AABB<K> { LL | pub loc: Vector2<K>, | ------------------- this field does not implement `Copy` | @@ -15,7 +15,7 @@ LL | pub loc: Vector2<K>, = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `K` | -LL | pub struct AABB<K: Debug>{ +LL | pub struct AABB<K: Debug> { | +++++++ error[E0277]: `K` doesn't implement `Debug` @@ -27,11 +27,11 @@ LL | pub loc: Vector2<K>, note: required by a bound in `Vector2` --> $DIR/missing-bound-in-derive-copy-impl.rs:4:23 | -LL | pub struct Vector2<T: Debug + Copy + Clone>{ +LL | pub struct Vector2<T: Debug + Copy + Clone> { | ^^^^^ required by this bound in `Vector2` help: consider restricting type parameter `K` | -LL | pub struct AABB<K: std::fmt::Debug>{ +LL | pub struct AABB<K: std::fmt::Debug> { | +++++++++++++++++ error[E0277]: the trait bound `K: Copy` is not satisfied @@ -43,14 +43,111 @@ LL | pub loc: Vector2<K>, note: required by a bound in `Vector2` --> $DIR/missing-bound-in-derive-copy-impl.rs:4:31 | -LL | pub struct Vector2<T: Debug + Copy + Clone>{ +LL | pub struct Vector2<T: Debug + Copy + Clone> { | ^^^^ required by this bound in `Vector2` help: consider restricting type parameter `K` | -LL | pub struct AABB<K: std::marker::Copy>{ +LL | pub struct AABB<K: std::marker::Copy> { | +++++++++++++++++++ -error: aborting due to 3 previous errors +error[E0277]: the trait bound `K: Copy` is not satisfied + --> $DIR/missing-bound-in-derive-copy-impl.rs:11:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct AABB<K> { +LL | pub loc: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Debug` + | +note: required for `Vector2<K>` to implement `Debug` + --> $DIR/missing-bound-in-derive-copy-impl.rs:3:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +LL | pub struct Vector2<T: Debug + Copy + Clone> { + | ---- unsatisfied trait bound introduced in this `derive` macro + = note: required for the cast from `&Vector2<K>` to `&dyn Debug` + = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider restricting type parameter `K` + | +LL | pub struct AABB<K: std::marker::Copy> { + | +++++++++++++++++++ + +error[E0277]: `K` doesn't implement `Debug` + --> $DIR/missing-bound-in-derive-copy-impl.rs:11:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct AABB<K> { +LL | pub loc: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider restricting type parameter `K` + | +LL | pub struct AABB<K: std::fmt::Debug> { + | +++++++++++++++++ + +error[E0277]: the trait bound `K: Copy` is not satisfied + --> $DIR/missing-bound-in-derive-copy-impl.rs:11:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +LL | pub struct AABB<K> { +LL | pub loc: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone` + | +note: required for `Vector2<K>` to implement `Clone` + --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +LL | pub struct Vector2<T: Debug + Copy + Clone> { + | ---- unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider restricting type parameter `K` + | +LL | pub struct AABB<K: std::marker::Copy> { + | +++++++++++++++++++ + +error[E0277]: `K` doesn't implement `Debug` + --> $DIR/missing-bound-in-derive-copy-impl.rs:17:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub size: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider restricting type parameter `K` + | +LL | pub struct AABB<K: std::fmt::Debug> { + | +++++++++++++++++ + +error[E0277]: the trait bound `K: Copy` is not satisfied + --> $DIR/missing-bound-in-derive-copy-impl.rs:17:5 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub size: Vector2<K>, + | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2<K>: Clone` + | +note: required for `Vector2<K>` to implement `Clone` + --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +LL | pub struct Vector2<T: Debug + Copy + Clone> { + | ---- unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider restricting type parameter `K` + | +LL | pub struct AABB<K: std::marker::Copy> { + | +++++++++++++++++++ + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0204, E0277. For more information about an error, try `rustc --explain E0204`. diff --git a/tests/ui/suggestions/object-unsafe-trait-references-self.rs b/tests/ui/suggestions/object-unsafe-trait-references-self.rs index 07bf053e996..4b3d5faba46 100644 --- a/tests/ui/suggestions/object-unsafe-trait-references-self.rs +++ b/tests/ui/suggestions/object-unsafe-trait-references-self.rs @@ -1,6 +1,9 @@ trait Trait { fn baz(&self, _: Self) {} + //~^ ERROR the size for values of type `Self` cannot be known fn bat(&self) -> Self {} + //~^ ERROR mismatched types + //~| ERROR the size for values of type `Self` cannot be known } fn bar(x: &dyn Trait) {} //~ ERROR the trait `Trait` cannot be made into an object diff --git a/tests/ui/suggestions/object-unsafe-trait-references-self.stderr b/tests/ui/suggestions/object-unsafe-trait-references-self.stderr index 54f19fe9da4..64270068471 100644 --- a/tests/ui/suggestions/object-unsafe-trait-references-self.stderr +++ b/tests/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/object-unsafe-trait-references-self.rs:6:12 + --> $DIR/object-unsafe-trait-references-self.rs:9:12 | LL | fn bar(x: &dyn Trait) {} | ^^^^^^^^^ `Trait` cannot be made into an object @@ -11,25 +11,67 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn baz(&self, _: Self) {} | ^^^^ ...because method `baz` references the `Self` type in this parameter +LL | LL | fn bat(&self) -> Self {} | ^^^^ ...because method `bat` references the `Self` type in its return type = help: consider moving `baz` to another trait = help: consider moving `bat` to another trait error[E0038]: the trait `Other` cannot be made into an object - --> $DIR/object-unsafe-trait-references-self.rs:10:12 + --> $DIR/object-unsafe-trait-references-self.rs:13:12 | LL | fn foo(x: &dyn Other) {} | ^^^^^^^^^ `Other` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-unsafe-trait-references-self.rs:8:14 + --> $DIR/object-unsafe-trait-references-self.rs:11:14 | LL | trait Other: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/object-unsafe-trait-references-self.rs:2:19 + | +LL | fn baz(&self, _: Self) {} + | ^ doesn't have a size known at compile-time + | + = help: unsized fn params are gated as an unstable feature +help: consider further restricting `Self` + | +LL | fn baz(&self, _: Self) where Self: Sized {} + | +++++++++++++++++ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn baz(&self, _: &Self) {} + | + + +error[E0308]: mismatched types + --> $DIR/object-unsafe-trait-references-self.rs:4:27 + | +LL | trait Trait { + | ----------- expected this type parameter +... +LL | fn bat(&self) -> Self {} + | ^^ expected type parameter `Self`, found `()` + | + = note: expected type parameter `Self` + found unit type `()` + +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/object-unsafe-trait-references-self.rs:4:22 + | +LL | fn bat(&self) -> Self {} + | ^^^^ doesn't have a size known at compile-time + | + = note: the return type of a function must have a statically known size +help: consider further restricting `Self` + | +LL | fn bat(&self) -> Self where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0277, E0308. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr index ffd505fffb4..0098814f81e 100644 --- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr +++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr @@ -40,7 +40,7 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {} = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {} | +++ diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.rs b/tests/ui/trait-bounds/impl-bound-with-references-error.rs index e5d0a1aaed0..5ba35da8383 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.rs +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.rs @@ -13,7 +13,7 @@ where //~^ ERROR cannot find type `Cow` in this scope [E0412] { fn from(text: T) -> Self { - LabelText::Plain(text.into()) + LabelText::Plain(text.into()) //~ ERROR expected function, found `LabelText` } } diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr index 63280b8616f..b3ac5544e38 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr @@ -21,7 +21,18 @@ LL | | T: Into<Cow<'static, str>>, = note: conflicting implementation in crate `core`: - impl<T> From<T> for T; -error: aborting due to 2 previous errors +error[E0618]: expected function, found `LabelText` + --> $DIR/impl-bound-with-references-error.rs:16:9 + | +LL | Plain, + | ----- `LabelText::Plain` defined here +... +LL | LabelText::Plain(text.into()) + | ^^^^^^^^^^^^^^^^------------- + | | + | call expression requires function + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0119, E0412. +Some errors have detailed explanations: E0119, E0412, E0618. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/trait-bounds/suggest-maybe-sized-bound.rs b/tests/ui/trait-bounds/suggest-maybe-sized-bound.rs new file mode 100644 index 00000000000..15aa27349aa --- /dev/null +++ b/tests/ui/trait-bounds/suggest-maybe-sized-bound.rs @@ -0,0 +1,20 @@ +// issue: 120878 +fn main() { + struct StructA<A, B = A> { + _marker: std::marker::PhantomData<fn() -> (A, B)>, + } + + struct StructB { + a: StructA<isize, [u8]>, + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + } + + trait Trait { + type P<X>; + } + + impl Trait for () { + type P<X> = [u8]; + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + } +} diff --git a/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr b/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr new file mode 100644 index 00000000000..4ce936582f4 --- /dev/null +++ b/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr @@ -0,0 +1,37 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/suggest-maybe-sized-bound.rs:8:12 + | +LL | a: StructA<isize, [u8]>, + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `StructA` + --> $DIR/suggest-maybe-sized-bound.rs:3:23 + | +LL | struct StructA<A, B = A> { + | ^^^^^ required by the implicit `Sized` requirement on this type parameter in `StructA` +help: consider relaxing the implicit `Sized` restriction + | +LL | struct StructA<A, B: ?Sized = A> { + | ++++++++ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/suggest-maybe-sized-bound.rs:17:21 + | +LL | type P<X> = [u8]; + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Trait::P` + --> $DIR/suggest-maybe-sized-bound.rs:13:9 + | +LL | type P<X>; + | ^^^^^^^^^^ required by this bound in `Trait::P` +help: consider relaxing the implicit `Sized` restriction + | +LL | type P<X>: ?Sized; + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/trait-impl-bound-suggestions.fixed b/tests/ui/trait-impl-bound-suggestions.fixed index fb11286a175..342841b4838 100644 --- a/tests/ui/trait-impl-bound-suggestions.fixed +++ b/tests/ui/trait-impl-bound-suggestions.fixed @@ -10,19 +10,21 @@ struct ConstrainedStruct<X: Copy> { } #[allow(dead_code)] -trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy { +trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized, X: std::marker::Copy, X: std::marker::Copy { fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { //~^ ERROR the trait bound `X: Copy` is not satisfied ConstrainedStruct { x } + //~^ ERROR the trait bound `X: Copy` is not satisfied } } // Regression test for #120838 #[allow(dead_code)] -trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where X: std::marker::Copy { +trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized, X: std::marker::Copy, X: std::marker::Copy { fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { //~^ ERROR the trait bound `X: Copy` is not satisfied ConstrainedStruct { x } + //~^ ERROR the trait bound `X: Copy` is not satisfied } } diff --git a/tests/ui/trait-impl-bound-suggestions.rs b/tests/ui/trait-impl-bound-suggestions.rs index 46130a5e766..9a494402260 100644 --- a/tests/ui/trait-impl-bound-suggestions.rs +++ b/tests/ui/trait-impl-bound-suggestions.rs @@ -10,19 +10,21 @@ struct ConstrainedStruct<X: Copy> { } #[allow(dead_code)] -trait InsufficientlyConstrainedGeneric<X=()> { +trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized { fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { //~^ ERROR the trait bound `X: Copy` is not satisfied ConstrainedStruct { x } + //~^ ERROR the trait bound `X: Copy` is not satisfied } } // Regression test for #120838 #[allow(dead_code)] -trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where { +trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized { fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { //~^ ERROR the trait bound `X: Copy` is not satisfied ConstrainedStruct { x } + //~^ ERROR the trait bound `X: Copy` is not satisfied } } diff --git a/tests/ui/trait-impl-bound-suggestions.stderr b/tests/ui/trait-impl-bound-suggestions.stderr index 9883c5bda01..6a75cbdf639 100644 --- a/tests/ui/trait-impl-bound-suggestions.stderr +++ b/tests/ui/trait-impl-bound-suggestions.stderr @@ -11,11 +11,11 @@ LL | struct ConstrainedStruct<X: Copy> { | ^^^^ required by this bound in `ConstrainedStruct` help: consider further restricting type parameter `X` | -LL | trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy { - | ++++++++++++++++++++++++++ +LL | trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized, X: std::marker::Copy { + | ++++++++++++++++++++++ error[E0277]: the trait bound `X: Copy` is not satisfied - --> $DIR/trait-impl-bound-suggestions.rs:23:52 + --> $DIR/trait-impl-bound-suggestions.rs:24:52 | LL | fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `X` @@ -27,9 +27,41 @@ LL | struct ConstrainedStruct<X: Copy> { | ^^^^ required by this bound in `ConstrainedStruct` help: consider further restricting type parameter `X` | -LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where X: std::marker::Copy { - | ++++++++++++++++++++ +LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized, X: std::marker::Copy { + | ++++++++++++++++++++++ -error: aborting due to 2 previous errors +error[E0277]: the trait bound `X: Copy` is not satisfied + --> $DIR/trait-impl-bound-suggestions.rs:16:29 + | +LL | ConstrainedStruct { x } + | ^ the trait `Copy` is not implemented for `X` + | +note: required by a bound in `ConstrainedStruct` + --> $DIR/trait-impl-bound-suggestions.rs:8:29 + | +LL | struct ConstrainedStruct<X: Copy> { + | ^^^^ required by this bound in `ConstrainedStruct` +help: consider further restricting type parameter `X` + | +LL | trait InsufficientlyConstrainedGeneric<X=()> where Self: Sized, X: std::marker::Copy { + | ++++++++++++++++++++++ + +error[E0277]: the trait bound `X: Copy` is not satisfied + --> $DIR/trait-impl-bound-suggestions.rs:26:29 + | +LL | ConstrainedStruct { x } + | ^ the trait `Copy` is not implemented for `X` + | +note: required by a bound in `ConstrainedStruct` + --> $DIR/trait-impl-bound-suggestions.rs:8:29 + | +LL | struct ConstrainedStruct<X: Copy> { + | ^^^^ required by this bound in `ConstrainedStruct` +help: consider further restricting type parameter `X` + | +LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where Self: Sized, X: std::marker::Copy { + | ++++++++++++++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr index 6d56851bf34..f1e7a28654a 100644 --- a/tests/ui/traits/bound/not-on-bare-trait.stderr +++ b/tests/ui/traits/bound/not-on-bare-trait.stderr @@ -7,7 +7,7 @@ LL | fn foo(_x: Foo + Send) { = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | fn foo(_x: dyn Foo + Send) { | +++ diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs index d38d3c3b286..8adbac46a5b 100644 --- a/tests/ui/traits/issue-106072.rs +++ b/tests/ui/traits/issue-106072.rs @@ -1,5 +1,6 @@ #[derive(Clone)] //~ trait objects must include the `dyn` keyword //~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known +//~| ERROR: return type cannot have an unboxed trait object struct Foo; trait Foo {} //~ the name `Foo` is defined multiple times fn main() {} diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index aadadc45f21..6476c8b3237 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Foo` is defined multiple times - --> $DIR/issue-106072.rs:4:1 + --> $DIR/issue-106072.rs:5:1 | LL | struct Foo; | ----------- previous definition of the type `Foo` here @@ -19,6 +19,14 @@ note: required by a bound in `Clone` --> $SRC_DIR/core/src/clone.rs:LL:COL = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/issue-106072.rs:1:10 + | +LL | #[derive(Clone)] + | ^^^^^ doesn't have a size known at compile-time + | + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0782]: trait objects must include the `dyn` keyword --> $DIR/issue-106072.rs:1:10 | @@ -27,7 +35,7 @@ LL | #[derive(Clone)] | = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0428, E0782. +Some errors have detailed explanations: E0277, E0428, E0746, E0782. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr index adba5830b10..653ce05d285 100644 --- a/tests/ui/traits/issue-28576.stderr +++ b/tests/ui/traits/issue-28576.stderr @@ -36,8 +36,8 @@ LL | pub trait Bar: Foo<Assoc=()> + Sized { | +++++++ help: consider relaxing the implicit `Sized` restriction | -LL | pub trait Foo<RHS=Self: ?Sized> { - | ++++++++ +LL | pub trait Foo<RHS: ?Sized=Self> { + | ++++++++ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/issue-28576.rs:5:16 @@ -56,8 +56,8 @@ LL | ) where Self: Sized; | +++++++++++++++++ help: consider relaxing the implicit `Sized` restriction | -LL | pub trait Foo<RHS=Self: ?Sized> { - | ++++++++ +LL | pub trait Foo<RHS: ?Sized=Self> { + | ++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/traits/issue-33140-hack-boundaries.stderr b/tests/ui/traits/issue-33140-hack-boundaries.stderr index 06e1dfd3727..d9c4efbb721 100644 --- a/tests/ui/traits/issue-33140-hack-boundaries.stderr +++ b/tests/ui/traits/issue-33140-hack-boundaries.stderr @@ -77,9 +77,4 @@ LL | impl Trait0 for dyn Send {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> -note: the lint level is defined here - --> $DIR/issue-33140-hack-boundaries.rs:2:10 - | -LL | #![allow(order_dependent_trait_objects)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-5008-borrowed-traitobject-method-call.rs b/tests/ui/traits/issue-5008-borrowed-traitobject-method-call.rs index fc869ae4fec..fc869ae4fec 100644 --- a/tests/ui/issues/issue-5008-borrowed-traitobject-method-call.rs +++ b/tests/ui/traits/issue-5008-borrowed-traitobject-method-call.rs diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs index cc7ea32eb3a..ccd35a850f2 100644 --- a/tests/ui/traits/issue-50480.rs +++ b/tests/ui/traits/issue-50480.rs @@ -6,12 +6,15 @@ struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); //~| ERROR cannot find type `N` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR `i32` is not an iterator +//~| ERROR `i32` is not an iterator #[derive(Clone, Copy)] //~^ ERROR the trait `Copy` cannot be implemented for this type +//~| ERROR `i32` is not an iterator struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); //~^ ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR `i32` is not an iterator +//~| ERROR `i32` is not an iterator fn main() {} diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 68d3d5c80d0..6c019f59b09 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -38,7 +38,7 @@ LL | struct Foo<NotDefined>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, St | ++++++++++++ error[E0412]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:12:18 + --> $DIR/issue-50480.rs:14:18 | LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | - ^ @@ -55,7 +55,7 @@ LL | struct Bar<T, N>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, Strin | +++ error[E0412]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:12:21 + --> $DIR/issue-50480.rs:14:21 | LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^^^^^^^^ not found in this scope @@ -74,11 +74,11 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-50480.rs:10:17 + --> $DIR/issue-50480.rs:11:17 | LL | #[derive(Clone, Copy)] | ^^^^ -LL | +... LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | -------- ------ this field does not implement `Copy` | | @@ -96,15 +96,47 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:12:33 + --> $DIR/issue-50480.rs:14:33 + | +LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); + | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `i32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + +error[E0277]: `i32` is not an iterator + --> $DIR/issue-50480.rs:3:28 + | +LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); + | ^^^ `i32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `i32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + +error[E0277]: `i32` is not an iterator + --> $DIR/issue-50480.rs:11:10 + | +LL | #[derive(Clone, Copy)] + | ^^^^^ `i32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `i32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `i32` is not an iterator + --> $DIR/issue-50480.rs:14:33 | +LL | #[derive(Clone, Copy)] + | ----- in this derive macro expansion +... LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 10 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0204, E0277, E0412. For more information about an error, try `rustc --explain E0204`. diff --git a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs index 08f26686b2f..f9f5a1dc24d 100644 --- a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs +++ b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs @@ -1,9 +1,10 @@ // compile-flags: -Znext-solver -// check-pass - +// FIXME(-Znext-solver): This test is currently broken because the `deduce_closure_signature` +// is unable to look at nested obligations. trait Foo { fn test() -> impl Fn(u32) -> u32 { |x| x.count_ones() + //~^ ERROR type annotations needed } } diff --git a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr new file mode 100644 index 00000000000..3d7cd1af467 --- /dev/null +++ b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/deduce-closure-signature-after-normalization.rs:6:10 + | +LL | |x| x.count_ones() + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | |x: /* Type */| x.count_ones() + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr index bafc4ba18a7..158fefd1538 100644 --- a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr +++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr @@ -1,16 +1,9 @@ -error[E0283]: type annotations needed: cannot satisfy `Foo: Send` +error[E0284]: type annotations needed: cannot satisfy `Foo == _` --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18 | LL | needs_send::<Foo>(); - | ^^^ - | - = note: cannot satisfy `Foo: Send` -note: required by a bound in `needs_send` - --> $DIR/dont-type_of-tait-in-defining-scope.rs:12:18 - | -LL | fn needs_send<T: Send>() {} - | ^^^^ required by this bound in `needs_send` + | ^^^ cannot satisfy `Foo == _` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr index bafc4ba18a7..158fefd1538 100644 --- a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr +++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr @@ -1,16 +1,9 @@ -error[E0283]: type annotations needed: cannot satisfy `Foo: Send` +error[E0284]: type annotations needed: cannot satisfy `Foo == _` --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18 | LL | needs_send::<Foo>(); - | ^^^ - | - = note: cannot satisfy `Foo: Send` -note: required by a bound in `needs_send` - --> $DIR/dont-type_of-tait-in-defining-scope.rs:12:18 - | -LL | fn needs_send<T: Send>() {} - | ^^^^ required by this bound in `needs_send` + | ^^^ cannot satisfy `Foo == _` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs index ef0360248b5..9720a653e2b 100644 --- a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs +++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs @@ -13,7 +13,7 @@ fn needs_send<T: Send>() {} fn test(_: Foo) { needs_send::<Foo>(); - //~^ ERROR type annotations needed: cannot satisfy `Foo: Send` + //~^ ERROR type annotations needed: cannot satisfy `Foo == _` } fn defines(_: Foo) { diff --git a/tests/ui/traits/next-solver/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize-param-env-2.stderr index a52022e539e..86729eb8a4b 100644 --- a/tests/ui/traits/next-solver/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize-param-env-2.stderr @@ -30,6 +30,30 @@ LL | Self::Assoc: A<T>, | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`) -error: aborting due to 3 previous errors +error[E0275]: overflow evaluating the requirement `(): A<T>` + --> $DIR/normalize-param-env-2.rs:27:10 + | +LL | <() as A<T>>::f(); + | ^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`) + +error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>` + --> $DIR/normalize-param-env-2.rs:27:9 + | +LL | <() as A<T>>::f(); + | ^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`) +note: required by a bound in `A::f` + --> $DIR/normalize-param-env-2.rs:14:22 + | +LL | fn f() + | - required by a bound in this associated function +LL | where +LL | Self::Assoc: A<T>, + | ^^^^ required by this bound in `A::f` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr index dec820c61b0..2a017fac104 100644 --- a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr @@ -14,6 +14,19 @@ LL | <T as Trait>::Assoc: Trait, | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`) -error: aborting due to 2 previous errors +error[E0275]: overflow evaluating the requirement `T: Trait` + --> $DIR/normalize-param-env-4.rs:31:19 + | +LL | impls_trait::<T>(); + | ^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`) +note: required by a bound in `impls_trait` + --> $DIR/normalize-param-env-4.rs:14:19 + | +LL | fn impls_trait<T: Trait>() {} + | ^^^^^ required by this bound in `impls_trait` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs index d96936f60f7..9b35a267743 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.rs +++ b/tests/ui/traits/next-solver/specialization-transmute.rs @@ -15,7 +15,7 @@ impl<T> Default for T { // This will be fixed by #111994 fn intu(&self) -> &Self::Id { //~^ ERROR type annotations needed - self + self //~ ERROR cannot satisfy } } @@ -25,6 +25,6 @@ fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U { use std::num::NonZeroU8; fn main() { - let s = transmute::<u8, Option<NonZeroU8>>(0); // this call should then error + let s = transmute::<u8, Option<NonZeroU8>>(0); //~ ERROR cannot satisfy assert_eq!(s, None); } diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr index ea1ae387f56..c87612d6a26 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.stderr +++ b/tests/ui/traits/next-solver/specialization-transmute.stderr @@ -16,13 +16,31 @@ error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _` LL | fn intu(&self) -> &Self::Id { | ^^^^^^^^^ cannot satisfy `<T as Default>::Id == _` +error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id` + --> $DIR/specialization-transmute.rs:18:9 + | +LL | self + | ^^^^ cannot satisfy `T <: <T as Default>::Id` + +error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>` + --> $DIR/specialization-transmute.rs:28:13 + | +LL | let s = transmute::<u8, Option<NonZeroU8>>(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>` + | +note: required by a bound in `transmute` + --> $DIR/specialization-transmute.rs:22:25 + | +LL | fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U { + | ^^^^^^ required by this bound in `transmute` + error[E0282]: type annotations needed --> $DIR/specialization-transmute.rs:14:23 | LL | default type Id = T; | ^ cannot infer type for associated type `<T as Default>::Id` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted Some errors have detailed explanations: E0282, E0284. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/unspecified-self-in-trait-ref.stderr b/tests/ui/traits/unspecified-self-in-trait-ref.stderr index b5e8e88676c..3614348ceed 100644 --- a/tests/ui/traits/unspecified-self-in-trait-ref.stderr +++ b/tests/ui/traits/unspecified-self-in-trait-ref.stderr @@ -7,7 +7,7 @@ LL | let a = Foo::lol(); = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let a = <dyn Foo>::lol(); | ++++ + @@ -26,7 +26,7 @@ LL | let b = Foo::<_>::lol(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let b = <dyn Foo::<_>>::lol(); | ++++ + @@ -45,7 +45,7 @@ LL | let c = Bar::lol(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let c = <dyn Bar>::lol(); | ++++ + @@ -64,7 +64,7 @@ LL | let d = Bar::<usize, _>::lol(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let d = <dyn Bar::<usize, _>>::lol(); | ++++ + @@ -83,7 +83,7 @@ LL | let e = Bar::<usize>::lol(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` +help: if this is an object-safe trait, use `dyn` | LL | let e = <dyn Bar::<usize>>::lol(); | ++++ + diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs index 2b966609108..f2c2a471f72 100644 --- a/tests/ui/transmutability/issue-101739-1.rs +++ b/tests/ui/transmutability/issue-101739-1.rs @@ -7,6 +7,7 @@ mod assert { where Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope //~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume` + //~| ERROR: mismatched types { } } diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index bf947d0ea4a..e87693f247d 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -13,6 +13,13 @@ LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, note: required by a bound in `BikeshedIntrinsicFrom` --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/issue-101739-1.rs:8:50 + | +LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, + | ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs index 4cde9152032..8d670ec17ca 100644 --- a/tests/ui/transmutability/issue-101739-2.rs +++ b/tests/ui/transmutability/issue-101739-2.rs @@ -19,7 +19,7 @@ mod assert { //~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume` Src, Context, - ASSUME_ALIGNMENT, + ASSUME_ALIGNMENT, //~ ERROR: mismatched types ASSUME_LIFETIMES, ASSUME_VALIDITY, ASSUME_VISIBILITY, diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr index aed47f33f0d..adbb5ff5aff 100644 --- a/tests/ui/transmutability/issue-101739-2.stderr +++ b/tests/ui/transmutability/issue-101739-2.stderr @@ -25,6 +25,13 @@ LL | | >, note: required by a bound in `BikeshedIntrinsicFrom` --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/issue-101739-2.rs:22:13 + | +LL | ASSUME_ALIGNMENT, + | ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0107, E0308. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.rs b/tests/ui/treat-err-as-bug/eagerly-emit.rs deleted file mode 100644 index ede190575d5..00000000000 --- a/tests/ui/treat-err-as-bug/eagerly-emit.rs +++ /dev/null @@ -1,10 +0,0 @@ -// compile-flags: -Zeagerly-emit-delayed-bugs - -trait Foo {} - -fn main() {} - -fn f() -> impl Foo { - //~^ ERROR the trait bound `i32: Foo` is not satisfied - 1i32 -} diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.stderr b/tests/ui/treat-err-as-bug/eagerly-emit.stderr deleted file mode 100644 index 4ae596435aa..00000000000 --- a/tests/ui/treat-err-as-bug/eagerly-emit.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging - -error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/eagerly-emit.rs:7:11 - | -LL | fn f() -> impl Foo { - | ^^^^^^^^ the trait `Foo` is not implemented for `i32` -LL | -LL | 1i32 - | ---- return type was inferred to be `i32` here - | -help: this trait has no implementations, consider adding one - --> $DIR/eagerly-emit.rs:3:1 - | -LL | trait Foo {} - | ^^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs index 4090a706f99..74992497dab 100644 --- a/tests/ui/treat-err-as-bug/err.rs +++ b/tests/ui/treat-err-as-bug/err.rs @@ -1,7 +1,7 @@ // compile-flags: -Ztreat-err-as-bug // failure-status: 101 // error-pattern: aborting due to `-Z treat-err-as-bug=1` -// error-pattern: [eval_to_allocation_raw] const-evaluating + checking `C` +// error-pattern: [eval_static_initializer] evaluating initializer of static `C` // normalize-stderr-test "note: .*\n\n" -> "" // normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" // rustc-env:RUST_BACKTRACE=0 diff --git a/tests/ui/treat-err-as-bug/err.stderr b/tests/ui/treat-err-as-bug/err.stderr index f1b61c3607b..ca04ee9e0cf 100644 --- a/tests/ui/treat-err-as-bug/err.stderr +++ b/tests/ui/treat-err-as-bug/err.stderr @@ -7,6 +7,6 @@ LL | pub static C: u32 = 0 - 1; error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `C` +#0 [eval_static_initializer] evaluating initializer of static `C` #1 [lint_mod] linting top-level module end of query stack diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr index ab57812ba9b..019e01a07d3 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `i32` with `Foo` - --> $DIR/self-referential-2.rs:6:13 + --> $DIR/self-referential-2.rs:9:13 | LL | fn bar() -> Bar { | ^^^ no implementation for `i32 == Foo` diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index 8781196c39f..3a765a2e3ef 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,10 +1,13 @@ +// revisions: current next +//[next] compile-flags: -Znext-solver +//[next] check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq<Foo>; fn bar() -> Bar { - 42_i32 //~^ ERROR can't compare `i32` with `Foo` + 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr new file mode 100644 index 00000000000..b380dc66f03 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr @@ -0,0 +1,15 @@ +error[E0284]: type annotations needed: cannot satisfy `Foo == _` + --> $DIR/type-alias-impl-trait-tuple.rs:21:24 + | +LL | Blah { my_foo: make_foo(), my_u8: 12 } + | ^^^^^^^^^^ cannot satisfy `Foo == _` + +error[E0284]: type annotations needed: cannot satisfy `Foo == _` + --> $DIR/type-alias-impl-trait-tuple.rs:25:10 + | +LL | (self.my_foo, self.my_u8, make_foo()) + | ^^^^^^^^^^^ cannot satisfy `Foo == _` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs index 1f2d0e47ea3..7bf899a96be 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -1,4 +1,6 @@ -// check-pass +// revisions: current next +//[next] compile-flags: -Znext-solver +//[current] check-pass #![feature(type_alias_impl_trait)] #![allow(dead_code)] @@ -17,9 +19,11 @@ struct Blah { impl Blah { fn new() -> Blah { Blah { my_foo: make_foo(), my_u8: 12 } + //[next]~^ ERROR type annotations needed: cannot satisfy `Foo == _` } fn into_inner(self) -> (Foo, u8, Foo) { (self.my_foo, self.my_u8, make_foo()) + //[next]~^ ERROR type annotations needed: cannot satisfy `Foo == _` } } diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.stderr b/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr index 7d7cad874fa..22a3d7bd32f 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.stderr +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/type_of_a_let.rs:16:16 + --> $DIR/type_of_a_let.rs:20:16 | LL | let x: Foo = 22_u32; | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait @@ -9,7 +9,7 @@ LL | same_type((x, y)); | ^ value used here after move error[E0382]: use of moved value: `y` - --> $DIR/type_of_a_let.rs:17:6 + --> $DIR/type_of_a_let.rs:21:6 | LL | let y: Foo = x; | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.rs b/tests/ui/type-alias-impl-trait/type_of_a_let.rs index 36161171555..0f4dac6c683 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.rs +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.rs @@ -1,3 +1,7 @@ +// revisions: current next +//[next] compile-flags: -Znext-solver +//[next] check-pass + #![feature(type_alias_impl_trait)] #![allow(dead_code)] @@ -13,8 +17,8 @@ fn foo1() -> (u32, Foo) { fn foo2() -> (u32, Foo) { let x: Foo = 22_u32; let y: Foo = x; - same_type((x, y)); //~ ERROR use of moved value - (y, todo!()) //~ ERROR use of moved value + same_type((x, y)); //[current]~ ERROR use of moved value + (y, todo!()) //[current]~ ERROR use of moved value } fn same_type<T>(x: (T, T)) {} diff --git a/tests/ui/type/type-check/issue-40294.rs b/tests/ui/type/type-check/issue-40294.rs index 5493a4e5f10..46ba2296163 100644 --- a/tests/ui/type/type-check/issue-40294.rs +++ b/tests/ui/type/type-check/issue-40294.rs @@ -6,7 +6,7 @@ fn foo<'a,'b,T>(x: &'a T, y: &'b T) where &'a T : Foo, //~ ERROR type annotations needed &'b T : Foo { - x.foo(); + x.foo(); //~ ERROR type annotations needed y.foo(); } diff --git a/tests/ui/type/type-check/issue-40294.stderr b/tests/ui/type/type-check/issue-40294.stderr index c6c1d689324..178ea69563a 100644 --- a/tests/ui/type/type-check/issue-40294.stderr +++ b/tests/ui/type/type-check/issue-40294.stderr @@ -12,6 +12,20 @@ LL | where &'a T : Foo, LL | &'b T : Foo | ^^^ -error: aborting due to 1 previous error +error[E0283]: type annotations needed: cannot satisfy `&T: Foo` + --> $DIR/issue-40294.rs:9:7 + | +LL | x.foo(); + | ^^^ + | +note: multiple `impl`s or `where` clauses satisfying `&T: Foo` found + --> $DIR/issue-40294.rs:6:19 + | +LL | where &'a T : Foo, + | ^^^ +LL | &'b T : Foo + | ^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index 591a7278ddc..a95b44e807c 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -47,7 +47,7 @@ impl Test9 { fn test11(x: &usize) -> &_ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types - &x + &x //~ ERROR cannot return reference to function parameter } unsafe fn test12(x: *const usize) -> *const *const _ { @@ -229,3 +229,5 @@ fn evens_squared(n: usize) -> _ { const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); //~^ ERROR the placeholder +//~| ERROR cannot call non-const +//~| ERROR cannot call non-const diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index bfcc76c1dae..18f6edad5c0 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -666,7 +666,31 @@ LL | type F: std::ops::Fn(_); LL | impl Qux for Struct { | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation -error: aborting due to 72 previous errors +error[E0515]: cannot return reference to function parameter `x` + --> $DIR/typeck_type_placeholder_item.rs:50:5 + | +LL | &x + | ^^ returns a reference to data owned by the current function + +error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}>` in constants + --> $DIR/typeck_type_placeholder_item.rs:230:22 + | +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error[E0015]: cannot call non-const fn `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:230:49: 230:52}>` in constants + --> $DIR/typeck_type_placeholder_item.rs:230:45 + | +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + +error: aborting due to 75 previous errors -Some errors have detailed explanations: E0046, E0121, E0282, E0403. -For more information about an error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403, E0515. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.rs b/tests/ui/ufcs/ufcs-explicit-self-bad.rs index 3bb3d906d11..29586dccfc9 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.rs +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.rs @@ -7,7 +7,7 @@ struct Foo { impl Foo { fn foo(self: isize, x: isize) -> isize { //~^ ERROR invalid `self` parameter type - self.f + x + self.f + x //~ ERROR: doesn't have fields } } @@ -53,8 +53,10 @@ fn main() { f: 1, }); println!("{}", foo.foo(2)); + //~^ ERROR: no method named `foo` let bar = Box::new(Bar { f: 1, }); println!("{} {}", bar.foo(2), bar.bar(2)); + //~^ ERROR: no method named `bar` } diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index b0e71507a2e..7c250775475 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -118,7 +118,25 @@ note: ...does not necessarily outlive the anonymous lifetime defined here LL | fn dummy3(self: &&Bar<T>) {} | ^^^^^^^ -error: aborting due to 8 previous errors +error[E0610]: `isize` is a primitive type and therefore doesn't have fields + --> $DIR/ufcs-explicit-self-bad.rs:10:14 + | +LL | self.f + x + | ^ + +error[E0599]: no method named `foo` found for struct `Box<Foo>` in the current scope + --> $DIR/ufcs-explicit-self-bad.rs:55:24 + | +LL | println!("{}", foo.foo(2)); + | ^^^ method not found in `Box<Foo>` + +error[E0599]: no method named `bar` found for struct `Box<Bar<isize>>` in the current scope + --> $DIR/ufcs-explicit-self-bad.rs:60:39 + | +LL | println!("{} {}", bar.foo(2), bar.bar(2)); + | ^^^ method not found in `Box<Bar<isize>>` + +error: aborting due to 11 previous errors -Some errors have detailed explanations: E0053, E0307, E0308. +Some errors have detailed explanations: E0053, E0307, E0308, E0599, E0610. For more information about an error, try `rustc --explain E0053`. diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs index d2e48600227..2278285bf8f 100644 --- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs +++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.rs @@ -4,5 +4,5 @@ fn a<F: Fn<usize>>(f: F) {} //~^ ERROR type parameter to bare `Fn` trait must be a tuple fn main() { - a(|_: usize| {}); + a(|_: usize| {}); //~ ERROR: mismatched types } diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr index 66d393c67c5..0d4265ddf8b 100644 --- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr +++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr @@ -7,6 +7,21 @@ LL | fn a<F: Fn<usize>>(f: F) {} note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/non-tupled-arg-mismatch.rs:7:5 + | +LL | a(|_: usize| {}); + | ^^^^^^^^^^^^^^^^ types differ + | + = note: expected trait `Fn<usize>` + found trait `Fn(usize)` +note: required by a bound in `a` + --> $DIR/non-tupled-arg-mismatch.rs:3:9 + | +LL | fn a<F: Fn<usize>>(f: F) {} + | ^^^^^^^^^ required by this bound in `a` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0059`. +Some errors have detailed explanations: E0059, E0308. +For more information about an error, try `rustc --explain E0059`. diff --git a/tests/ui/wf/wf-in-fn-ret.rs b/tests/ui/wf/wf-in-fn-ret.rs index 4c9535184ff..3e9b9787cc5 100644 --- a/tests/ui/wf/wf-in-fn-ret.rs +++ b/tests/ui/wf/wf-in-fn-ret.rs @@ -3,12 +3,13 @@ #![feature(rustc_attrs)] #![allow(dead_code)] -struct MustBeCopy<T:Copy> { - t: T +struct MustBeCopy<T: Copy> { + t: T, } fn bar<T>() -> MustBeCopy<T> //~ ERROR E0277 +//~^ ERROR mismatched types { } -fn main() { } +fn main() {} diff --git a/tests/ui/wf/wf-in-fn-ret.stderr b/tests/ui/wf/wf-in-fn-ret.stderr index 85cf78c5987..1ae49a348cc 100644 --- a/tests/ui/wf/wf-in-fn-ret.stderr +++ b/tests/ui/wf/wf-in-fn-ret.stderr @@ -5,15 +5,27 @@ LL | fn bar<T>() -> MustBeCopy<T> | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` | note: required by a bound in `MustBeCopy` - --> $DIR/wf-in-fn-ret.rs:6:21 + --> $DIR/wf-in-fn-ret.rs:6:22 | -LL | struct MustBeCopy<T:Copy> { - | ^^^^ required by this bound in `MustBeCopy` +LL | struct MustBeCopy<T: Copy> { + | ^^^^ required by this bound in `MustBeCopy` help: consider restricting type parameter `T` | LL | fn bar<T: std::marker::Copy>() -> MustBeCopy<T> | +++++++++++++++++++ -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/wf-in-fn-ret.rs:10:16 + | +LL | fn bar<T>() -> MustBeCopy<T> + | --- ^^^^^^^^^^^^^ expected `MustBeCopy<T>`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected struct `MustBeCopy<T>` + found unit type `()` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/triagebot.toml b/triagebot.toml index 383b89b18df..9f2be743a5a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -651,6 +651,7 @@ compiler-team = [ "@petrochenkov", "@davidtwco", "@estebank", + "@lcnr", "@oli-obk", "@pnkfelix", "@wesleywiser", @@ -680,7 +681,6 @@ infra-ci = [ "@Kobzol", ] rustdoc = [ - "@jsha", "@GuillaumeGomez", "@notriddle", "@fmease", |
