diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 45a56cdf46a62..7ac9f489f92a4 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -10,7 +10,9 @@ use rustc_mir_dataflow::impls::{ use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice}; use tracing::debug; -use crate::{BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict}; +use crate::{ + AccessDepth, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict, +}; // This analysis is different to most others. Its results aren't computed with // `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are @@ -448,7 +450,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { // If the borrowed place is a local with no projections, all other borrows of this // local must conflict. This is purely an optimization so we don't have to call - // `places_conflict` for every borrow. + // `places_conflict::borrow_conflicts_with_place` for every borrow. if place.projection.is_empty() { if !self.body.local_decls[place.local].is_ref_to_static() { state.kill_all(other_borrows_of_local); @@ -461,11 +463,13 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { // will be assured that two places being compared definitely denotes the same sets of // locations. let definitely_conflicting_borrows = other_borrows_of_local.filter(|&i| { - places_conflict( + places_conflict::borrow_conflicts_with_place( self.tcx, self.body, self.borrow_set[i].borrowed_place, - place, + self.borrow_set[i].kind, + place.as_ref(), + AccessDepth::Deep, PlaceConflictBias::NoOverlap, ) }); diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index 80bbbfe4e9bc1..c9b921615f430 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock @@ -43,27 +43,27 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cranelift-assembler-x64" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a59ddc4abd9c5560f4742864b2cd8c19e73c7263f0c866b2c45c2d31587adc" +checksum = "d3307701abcb90554ee72fdb0db36ee0334a4abe380c4d87a5b04a6942613c3a" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8c361cd22fd0fdd8e61af6bfd86ad9c0c62f78b2b1caa2b9e4e97cd8f605fe" +checksum = "e62d0e19f9f5fa0c4243236df1ffdf139d207600b4402ac41ceba8dbe7ca0f3d" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86c34ae183cf2410318f899648fe1ef6ab9148486e7b938d7b4d814e61dafc9" +checksum = "47784bc3c4b57c0182bb8ff04aae5d5f5fc6bae8ba26b1212c9a659b90dab84e" dependencies = [ "cranelift-entity", "wasmtime-internal-core", @@ -71,18 +71,18 @@ dependencies = [ [[package]] name = "cranelift-bitset" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415f1a12668869e16ac3b66a729fb8cce8bbe6e50e68d1fa0142acd0c9c05f0c" +checksum = "e13d120406f713dbce1940751e77bbb14daad1261379b7200c19285953e79a1d" dependencies = [ "wasmtime-internal-core", ] [[package]] name = "cranelift-codegen" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73eecedc85ffca4f34dbe197c6545c8ade6579a61352457936f53c3bffa6353b" +checksum = "a53dbec33ff86909e44be6f0ec2d17841aa38b931013707c9fc7279f1f0e5760" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -107,9 +107,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66834005198c3e9e3d89cd69cf1541419402ab75250afbeaa3128db6d5254025" +checksum = "42295b38e9182954cb32a71812e3d64d66a90efc0a2ababb73e465ad4a1efccf" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -119,24 +119,24 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6efaf74077091a2ff41317cc8eb2779264dae4b8a16d955835f3fcda338f52" +checksum = "b5200fa877fb64cd30cabe0603f394333f88f69adf63e4db8d48a111d0c9d0dd" [[package]] name = "cranelift-control" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4258d4ed6ad4e698fe1fec4277b1fcbea6f2a17cb5ec3f04bddfb38ca83d93e" +checksum = "b86250e480795fbb4425ea703bca7b75282998458ce74f5360843a31949f2bbc" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f016b6f87b1a46a3f5df59b82d88bb352bf2fa6d7868875dfc4d6b65de5242d" +checksum = "903c6592c7d600c251d20929f143543b7303ac70b072ad3394d65b29caf56f69" dependencies = [ "cranelift-bitset", "wasmtime-internal-core", @@ -144,9 +144,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16f2b149dae6ea3886bee931445196d86d8e71b66f7c3b21abe434f77189be8" +checksum = "b929f09b82a270e2aae062945cf86cd9db39c59ad9bead6986ea6b09fcf8a969" dependencies = [ "cranelift-codegen", "hashbrown 0.17.0", @@ -157,15 +157,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00258ff3d37f52ed731df679205e66175c728846dbde186ee20e93973d12ee7" +checksum = "b1c5809e8636a37e5a25ecc35242d33d6e7391c49b67488b83446e2898af2a2f" [[package]] name = "cranelift-jit" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa063cc98af51fb9090cd40b674503e21bdfa705d2bff75ebf98b79ffc0f598d" +checksum = "a86db0c01bd2f7f86fedbebd6bee15ab40d74bd1a87b35e19b2a1a07612427ba" dependencies = [ "anyhow", "cranelift-codegen", @@ -184,31 +184,33 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff0025f1ff6a0470cbd2a61b125f8501311ea9e6c46ed5bb2110ee6710c6a76" +checksum = "bb4f4b6e71b257549ffa6f14ddc0c314f332f66c7531b3c9a645c290a9d1effa" dependencies = [ "anyhow", "cranelift-codegen", "cranelift-control", + "hashbrown 0.17.0", ] [[package]] name = "cranelift-native" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f31eb7e08f31e5bc9c167c35718b0325efa3d4e234e2e9342316e01b18a4b51" +checksum = "815c559daf605a5b4ea35530604643c1e87504353c0d1a14763f9c2b9d518493" dependencies = [ "cranelift-codegen", "libc", + "mach2 0.6.0", "target-lexicon", ] [[package]] name = "cranelift-object" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca0d86955529d5b9041c4c07745f6ffa42c32326e9f467a834e2b7bd9a9d156" +checksum = "78f98e6d6b502fa10bd1bb95776544033169d0c1860d6fe1ada03109ea500eb4" dependencies = [ "anyhow", "cranelift-codegen", @@ -221,9 +223,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.135.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e0b67d313f510520f40c1496c3446af0d6b30219d1ba9a4c09c77ec288a561b" +checksum = "d633ff621e7f31a943431da0d7dd37c4376766c60bd7171216de1c7ccabfb370" [[package]] name = "crc32fast" @@ -332,6 +334,12 @@ dependencies = [ "libc", ] +[[package]] +name = "mach2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" + [[package]] name = "memchr" version = "2.7.6" @@ -349,9 +357,9 @@ dependencies = [ [[package]] name = "object" -version = "0.39.1" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" +checksum = "dd229a0361b9d0d4396176e02d65897f487eebeab7caa6d443855ee152ca0b9c" dependencies = [ "crc32fast", "hashbrown 0.17.0", @@ -399,7 +407,7 @@ checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" dependencies = [ "bitflags", "libc", - "mach2", + "mach2 0.4.3", "windows-sys 0.52.0", ] @@ -493,9 +501,9 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "wasmtime-internal-core" -version = "48.0.0" +version = "50.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c01c81d781512e17b38c3a76ca9aa2564bc3f9fd8ff6ffc77ba3e1c290d488a" +checksum = "83d4ac46034b149aed44335595402503094a04e3b70d0cff8c169d83437318b8" dependencies = [ "hashbrown 0.17.0", "libm", @@ -503,9 +511,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "48.0.0" +version = "50.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a09abde04346919af1136a28f344e200685509e28815aef4c39dc08977cc1d8" +checksum = "cf25a1b3b925915f845927967554400554db9cebd3a7038a6fca0cf6e9bbaf6a" dependencies = [ "libc", "wasmtime-internal-core", diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index ca03be20cd100..9b919976f7455 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -8,15 +8,15 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.135.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.135.0" } -cranelift-module = { version = "0.135.0" } -cranelift-native = { version = "0.135.0" } -cranelift-jit = { version = "0.135.0", optional = true } -cranelift-object = { version = "0.135.0", default-features = false } +cranelift-codegen = { version = "0.137.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.137.0" } +cranelift-module = { version = "0.137.0" } +cranelift-native = { version = "0.137.0" } +cranelift-jit = { version = "0.137.0", optional = true } +cranelift-object = { version = "0.137.0", default-features = false } target-lexicon = "0.13" gimli = { version = "0.33", default-features = false, features = ["write"] } -object = { version = "0.39.1", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +object = { version = "0.40.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.9.0", optional = true } @@ -24,12 +24,12 @@ smallvec = "1.8.1" # Uncomment to use an unreleased version of cranelift #[patch.crates-io] -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-48.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-48.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-48.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-48.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-48.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-48.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-50.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-50.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-50.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-50.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-50.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-50.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-Disable-complex-type-tests.patch b/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-Disable-complex-type-tests.patch deleted file mode 100644 index d27810a988492..0000000000000 --- a/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-Disable-complex-type-tests.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 20d296e9a8b837e586fcc8fc648d4ab9687a2a47 Mon Sep 17 00:00:00 2001 -From: Folkert de Vries -Date: Mon, 28 Sep 2026 19:14:22 +0200 -Subject: [PATCH] sysroot_tests: Disable complex type tests - ---- - coretests/tests/num/complex.rs | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/coretests/tests/num/complex.rs b/coretests/tests/num/complex.rs -index d73d04b1afc..289c0baec17 100644 ---- a/coretests/tests/num/complex.rs -+++ b/coretests/tests/num/complex.rs -@@ -75,6 +75,7 @@ fn complex_negation() { - } - - #[test] -+#[cfg_attr(target_os = "windows", ignore = "hits an ABI issue with cranelift on windows")] - fn complex_multiplication() { - #[cfg(target_has_reliable_f16)] - assert_eq!(Complex::new(1.0f16, 2.0) * Complex::new(3.0, 4.0), Complex::new(-5.0, 10.0)); -@@ -105,6 +106,7 @@ fn complex_multiplication() { - } - - #[test] -+#[cfg_attr(target_os = "windows", ignore = "hits an ABI issue with cranelift on windows")] - fn complex_div() { - #[cfg(target_has_reliable_f16)] - assert_eq!(Complex::new(2.0f16, 11.0) / Complex::new(2.0, 1.0), Complex::new(3.0, 4.0)); --- -2.43.0 - diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index a6468283e1270..294e49afa7e45 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain.toml +++ b/compiler/rustc_codegen_cranelift/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2026-09-30" +channel = "nightly-2026-10-23" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" diff --git a/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml b/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml index 54f9445c8e524..0f744034f9c1a 100644 --- a/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml +++ b/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml @@ -6,9 +6,9 @@ 'OptionU128::conv_rust::repr_c::rustc_caller'.busted = "run" 'OptionU128::conv_rust::repr_c::cgclif_caller'.busted = "check" -[target.'cfg(all(target_arch = "x86_64", windows))'] -'simple::conv_rust'.busted = "check" -'simple::conv_rust::rustc_caller'.busted = "run" +[target.'cfg(all(target_arch = "x86_64", target_env = "msvc"))'] +# ICE: https://github.com/rust-lang/rust/issues/164207 +'EmptyStruct::conv_c::repr_c::rustc_calls_cgclif'.run = "skip" [target.'*'.'f16'] run = "skip" diff --git a/compiler/rustc_codegen_cranelift/scripts/rustup.sh b/compiler/rustc_codegen_cranelift/scripts/rustup.sh index 8bd41f98ce550..acfd095f01704 100755 --- a/compiler/rustc_codegen_cranelift/scripts/rustup.sh +++ b/compiler/rustc_codegen_cranelift/scripts/rustup.sh @@ -6,30 +6,30 @@ export GIT_CONFIG_GLOBAL=$(pwd)/../rust/josh.gitconfig export RUSTC_GIT=../rust case $1 in - "prepare") + "push") + username=${2:-bjorn3} + branch=sync_cg_clif-$(date +%Y-%m-%d) + rustc-josh-sync push "$branch" "$username" + ;; + "pull") echo "=> Uninstalling all old nightlies" for nightly in $(RUSTUP_AUTO_INSTALL=0 rustup toolchain list | grep nightly | grep -v nightly-x86_64); do rustup toolchain uninstall "$nightly" done + echo "=> Cleaning build artifacts" + ./clean_all.sh + + rustc-josh-sync pull + echo "=> Installing new nightly" rustup toolchain install - ./clean_all.sh - + echo "=> Fetching deps" ./y.sh prepare ;; - "push") - username=${2:-bjorn3} - branch=sync_cg_clif-$(date +%Y-%m-%d) - rustc-josh-sync push "$branch" "$username" - ;; - "pull") - git checkout -b sync_from_rust - rustc-josh-sync pull - ;; *) echo "Unknown command '$1'" - echo "Usage: ./rustup.sh prepare|pull|push [fork]" + echo "Usage: ./rustup.sh pull|push [fork]" ;; esac diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index 2899458db114a..f888e73813532 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh @@ -23,7 +23,7 @@ git -c user.name=Dummy -c user.email=dummy@example.com -c commit.gpgSign=false \ am ../patches/*-stdlib-*.patch cat > config.toml < rather than /rustc/FAKE_PREFIX rm tests/ui/process/println-with-broken-pipe.rs # same +rm -r tests/run-make/unspecified-edition # warning suppressed when extra args are passed to rustc # genuine bugs # ============ @@ -176,6 +177,8 @@ rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet suppo rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort rm -r tests/run-make/used-proc-macro # doesn't work on arm64 for some reason rm tests/ui/async-await/async-drop/async-drop-async-gen-return-pending.rs # rustc side fnsig issue +rm -r tests/run-make/no-alloc-shim # undefined reference to nearbyint +rm -r tests/run-make/remap-path-prefix-doctest-panic # wrong path remapping # bugs in the test suite # ====================== diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index f35aba7d4fe1e..b6d4c378740b5 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs @@ -168,6 +168,7 @@ impl FunctionDebugContext { let mcr = context.compiled_code().unwrap(); for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() { + let loc = loc.as_abs(); debug_context.dwarf.unit.line_program.row().address_offset = u64::from(start); if !loc.is_default() { let source_loc = self.source_loc_set[loc.bits() as usize]; diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index 18eb85289e520..48e1f7f3654a2 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs @@ -1,6 +1,6 @@ //! Unwind info generation (`.eh_frame`) -use cranelift_codegen::FinalizedMachExceptionHandler; +use cranelift_codegen::MachExceptionHandler; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::unwind::UnwindInfo; use cranelift_module::DataId; @@ -172,26 +172,19 @@ impl UnwindContext { } for &handler in call_site.exception_handlers { match handler { - FinalizedMachExceptionHandler::Tag(tag, landingpad) => { - match tag.as_u32() { - EXCEPTION_HANDLER_CLEANUP => { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: u64::from(landingpad), - action_entry: None, - }) - } - EXCEPTION_HANDLER_CATCH => { - gcc_except_table_data.call_sites.0.push(CallSite { - start: u64::from(call_site.ret_addr - 1), - length: 1, - landing_pad: u64::from(landingpad), - action_entry: Some(catch_action), - }) - } + MachExceptionHandler::Tag(tag, landingpad) => { + let landing_pad = u64::from(landingpad.as_offset()); + let action_entry = match tag.as_u32() { + EXCEPTION_HANDLER_CLEANUP => None, + EXCEPTION_HANDLER_CATCH => Some(catch_action), _ => unreachable!(), - } + }; + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad, + action_entry, + }); } _ => unreachable!(), } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index b5c3eceab9b4b..31349191073c4 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -478,17 +478,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let caller_location = with_caller_location.then(|| self.caller_location()); // The first order of business is to figure out the callee signature. - // However, that requires the list of variadic arguments. - // We use the *caller* information to determine where to split the list of arguments, - // and then later check that the callee indeed has the same number of fixed arguments. - let extra_tys = if caller_fn_abi.c_variadic { - let fixed_count = usize::try_from(caller_fn_abi.fixed_count).unwrap(); - let extra_tys = args[fixed_count..].iter().map(|arg| arg.layout().ty); - self.tcx.mk_type_list_from_iter(extra_tys) - } else { - ty::List::empty() - }; - let callee_fn_abi = self.fn_abi_of_instance_no_deduced_attrs(instance, extra_tys)?; + // We leave the list of extra c-variadic args empty because the callee cannot know about + // them, and we don't need them in the `FnAbi`. This also avoids ICEs if the callee is + // not actually c-variadic. + let extra_args = ty::List::empty(); + let callee_fn_abi = self.fn_abi_of_instance_no_deduced_attrs(instance, extra_args)?; if caller_fn_abi.conv != callee_fn_abi.conv { throw_ub_format!( @@ -641,11 +635,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ecx.eval_place(dest, /* skip_validity_for_simple_deref */ false)?; let mplace = ecx.force_allocation(&place)?; + // There should be no more callee ABI arguments. + assert!(callee_args_abis.next().is_none()); // Consume the remaining arguments by putting them into the variable argument // list. We disable retagging to avoid creating protected tags. Protection should // only use callee-side information, and the varargs have no static callee-side type. let varargs = M::with_retag_mode(ecx, RetagMode::None, |ecx| { - ecx.allocate_varargs(&mut caller_args, &mut callee_args_abis) + ecx.allocate_varargs(&mut caller_args) })?; // When the frame is dropped, these variable arguments are deallocated. diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 1bc6d43aa6dfb..19a1dfe3e567b 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -656,22 +656,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { impl<'a, 'tcx: 'a, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Consume the arguments provided by the iterator and store them as a list /// of variadic arguments. Return a list of the places that hold those arguments. - pub(crate) fn allocate_varargs( + pub(crate) fn allocate_varargs( &mut self, caller_args: I, - mut callee_abis: J, ) -> InterpResult<'tcx, Vec>> where I: Iterator, &'a ArgAbi<'tcx, Ty<'tcx>>)>, - J: Iterator>)>, { // Consume the remaining arguments and store them in fresh allocations. let mut varargs = Vec::new(); - for (fn_arg, caller_abi) in caller_args { - // The callee ABI is entirely computed based on which arguments the caller has - // provided so it should not be possible to get a mismatch here. - let (_idx, callee_abi) = callee_abis.next().unwrap(); - assert!(self.check_argument_compat(caller_abi, callee_abi)?); + for (fn_arg, _caller_abi) in caller_args { // FIXME: do we have to worry about in-place argument passing? let op = fn_arg.copy_fn_arg(); let mplace = self.allocate(op.layout, MemoryKind::Stack)?; @@ -679,7 +673,6 @@ impl<'a, 'tcx: 'a, M: Machine<'tcx>> InterpCx<'tcx, M> { varargs.push(mplace); } - assert!(callee_abis.next().is_none()); interp_ok(varargs) } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 9d8a133905301..930d2c45605d2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2199,7 +2199,7 @@ fn report_bivariance<'tcx>( ); if !usage_spans.is_empty() { - // First, check if the ADT/LTA is (probably) cyclical. We say probably here, since we're + // First, check if the ADT is (probably) cyclical. We say probably here, since we're // not actually looking into substitutions, just walking through fields / the "RHS". // We don't recurse into the hidden types of opaques or anything else fancy. let item_def_id = item.owner_id.to_def_id(); @@ -2207,7 +2207,7 @@ fn report_bivariance<'tcx>( IsProbablyCyclical { tcx, item_def_id, seen: Default::default() } .visit_def(item_def_id) .is_break(); - // If the ADT/LTA is cyclical, then if at least one usage of the type parameter or + // If the ADT is cyclical, then if at least one usage of the type parameter or // the `Self` alias is present in the, then it's probably a cyclical struct/ type // alias, and we should call those parameter usages recursive rather than just saying // they're unused... @@ -2247,8 +2247,8 @@ fn report_bivariance<'tcx>( } } -/// Detects cases where an ADT/LTA is trivially cyclical -- we want to detect this so -/// we only mention that its parameters are used cyclically if the ADT/LTA is truly +/// Detects cases where an ADT is trivially cyclical -- we want to detect this so +/// we only mention that its parameters are used cyclically if the ADT is truly /// cyclical. /// /// Notably, we don't consider substitutions here, so this may have false positives. diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index d2c3a08eb714f..43607f199b375 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -97,12 +97,6 @@ pub(crate) fn orphan_check_impl( ); if tcx.trait_is_auto(trait_def_id) { - // Expand free alias types (e.g. lazy type aliases) so that the checks below operate - // on the type the alias resolves to rather than the alias itself. Otherwise an impl - // whose self type is an alias expanding to an otherwise valid nominal type would be - // wrongly rejected, e.g. `unsafe impl Sync for Alias {}` where `type Alias = Local;`. - // Expansion also reveals genuinely problematic self types (trait objects, opaque - // types, type parameters), so those keep being rejected. See issue #157756. let self_ty = tcx.expand_free_alias_tys(trait_ref.self_ty()); // If the impl is in the same crate as the auto-trait, almost anything diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index 493f2adaf30ca..1db58bf063963 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -47,7 +47,7 @@ pub(super) fn inferred_outlives_of( } pub(super) fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CrateClausesMap<'_> { - // Compute a map from each ADT (struct/enum/union) and lazy type alias to + // Compute a map from each ADT (struct/enum/union) and checked type alias to // the **explicit** outlives clauses (`T: 'a`, `'a: 'b`) that the user wrote. // Typically there won't be many of these, except in older code where // they were mandatory. Nonetheless, we have to ensure that every such diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 4632c3ca1fc12..56889f84f38d6 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -308,7 +308,7 @@ rustc_queries! { /// Returns the *type* of the definition given by `DefId`. /// - /// For type aliases (whether eager or lazy) and associated types, this returns + /// For type aliases (whether unchecked or checked) and associated types, this returns /// the underlying aliased type (not the corresponding [alias type]). /// /// For opaque types, this returns and thus reveals the hidden type! If you diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 4c7246f54afcd..ce44e47325879 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -381,6 +381,8 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( }; body.basic_blocks_mut()[call_bb].terminator = Some(Terminator { source_info, kind }); + make_coroutine_state_argument_pinned(tcx, &mut body); + // Run derefer to fix Derefs that are not in the first place deref_finder(tcx, &mut body, false); diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index 7270763f924ae..0f36bfe5a398f 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -1744,15 +1744,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let child_doc_visible = doc_visible && did.is_none_or(|did| did.is_local() || !this.tcx.is_doc_hidden(did)); - // collect results based on the filter function - // avoid suggesting anything from the same module in which we are resolving - // avoid suggesting anything with a hygienic name - if ident.name == lookup_ident.name - && ns == namespace - && in_module != parent_scope.module - && ident.ctxt.is_root() - && filter_fn(res) - { + let mk_path = |target_name| { // create the path let mut segms = if lookup_ident.span.at_least_rust_2018() { // crate-local absolute paths start with `crate::` in edition 2018 @@ -1763,8 +1755,49 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; segms.append(&mut path_segments.clone()); - segms.push(ast::PathSegment::from_ident(ident.orig(orig_ident_span))); - let path = Path { span: name_binding.span, segments: segms }; + segms.push(ast::PathSegment::from_ident(Ident::new( + target_name, + orig_ident_span, + ))); + Path { span: name_binding.span, segments: segms } + }; + if let DeclKind::Import { import, source_decl, .. } = name_binding.kind + && let ImportKind::Single { source, target, .. } = import.kind + && source != target + && source.name == lookup_ident.name + && ns == namespace + && ident.ctxt.is_root() + && filter_fn(res) + && this.is_accessible_from(source_decl.vis(), parent_scope.module) + && this.is_accessible_from(name_binding.vis(), parent_scope.module) + && !matches!(res, Res::Err | Res::SelfTyAlias { .. } | Res::SelfTyParam { .. }) + && lookup_ident.name != kw::SelfLower + && lookup_ident.name != kw::SelfUpper + { + // Detect we've already imported the item with a different name. + candidates.push(ImportSuggestion { + did, + descr: res.descr(), + path: mk_path(target.name), + accessible: child_accessible, + doc_visible: child_doc_visible, + note: None, + via_import, + is_stable, + }); + } + + // collect results based on the filter function + // avoid suggesting anything from the same module in which we are resolving + // avoid suggesting anything with a hygienic name + if ident.name == lookup_ident.name + && ns == namespace + && in_module != parent_scope.module + && ident.ctxt.is_root() + && filter_fn(res) + && !matches!(res, Res::Err | Res::SelfTyAlias { .. } | Res::SelfTyParam { .. }) + { + let path = mk_path(ident.name); if child_accessible // Remove invisible match if exists @@ -4105,19 +4138,34 @@ fn show_candidates( let mut showed = false; let mut accessible_path_strings: Vec> = Vec::new(); + let mut accessible_renames: Vec> = Vec::new(); let mut inaccessible_path_strings: Vec> = Vec::new(); candidates.iter().for_each(|c| { if c.accessible { // Don't suggest `#[doc(hidden)]` items from other crates if c.doc_visible { - accessible_path_strings.push(( - pprust::path_to_string(&c.path), - c.descr, - c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))), - &c.note, - c.via_import, - )) + if let [first, .., last] | [first @ last] = &path + && !first.ident.span.in_external_macro(tcx.sess.source_map()) + && first.ident.span.eq_ctxt(last.ident.span) + && c.path.segments.len() == 1 + { + accessible_renames.push(( + pprust::path_to_string(&c.path), + c.descr, + c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))), + &c.note, + c.via_import, + )); + } else { + accessible_path_strings.push(( + pprust::path_to_string(&c.path), + c.descr, + c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))), + &c.note, + c.via_import, + )); + } } } else { inaccessible_path_strings.push(( @@ -4126,13 +4174,15 @@ fn show_candidates( c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))), &c.note, c.via_import, - )) + )); } }); // we want consistent results across executions, but candidates are produced // by iterating through a hash map, so make sure they are ordered: - for path_strings in [&mut accessible_path_strings, &mut inaccessible_path_strings] { + for path_strings in + [&mut accessible_path_strings, &mut accessible_renames, &mut inaccessible_path_strings] + { path_strings.sort_by(|a, b| a.0.cmp(&b.0)); path_strings.dedup_by(|a, b| a.0 == b.0); let core_path_strings = @@ -4155,6 +4205,39 @@ fn show_candidates( path_strings.extend(foreign_crate_path_strings); } + if !accessible_renames.is_empty() { + let (determiner, kind, s, through) = + if let [(_, descr, _, _, via_import)] = &accessible_renames[..] { + ("this", *descr, "", if *via_import { " through its public re-export" } else { "" }) + } else { + // Get the unique item kinds and if there's only one, we use the right kind name + // instead of the more generic "items". + let kinds = accessible_path_strings + .iter() + .map(|(_, descr, _, _, _)| *descr) + .collect::>(); + let kind = if let Some(kind) = kinds.get_only() { kind } else { "item" }; + let s = if kind.ends_with('s') { "es" } else { "s" }; + + ("one of these", kind, s, "") + }; + + let instead = if let Instead::Yes = instead { " instead" } else { "" }; + let msg = format!("consider using {determiner} {kind}{s}{through}{instead}"); + + for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) { + err.note(note.clone()); + } + + err.span_suggestions_with_style( + path[0].ident.span.to(path[path.len() - 1].ident.span), + msg, + accessible_renames.into_iter().map(|a| a.0), + Applicability::MaybeIncorrect, + SuggestionStyle::ShowAlways, + ); + showed = true; + } if !accessible_path_strings.is_empty() { let (determiner, kind, s, name, through) = if let [(name, descr, _, _, via_import)] = &accessible_path_strings[..] { diff --git a/compiler/rustc_trait_selection/src/diagnostics.rs b/compiler/rustc_trait_selection/src/diagnostics.rs index d453b3c809860..7eacbebc091dd 100644 --- a/compiler/rustc_trait_selection/src/diagnostics.rs +++ b/compiler/rustc_trait_selection/src/diagnostics.rs @@ -1921,6 +1921,20 @@ impl Subdiagnostic for AddPreciseCapturingAndParams { } } +pub(crate) struct AddPreciseCapturingAndNameLifetimes { + pub suggs: Vec<(Span, String)>, +} + +impl Subdiagnostic for AddPreciseCapturingAndNameLifetimes { + fn add_to_diag(self, diag: &mut Diag<'_>) { + diag.multipart_suggestion( + msg!("add `use<...>` bound and name the elided lifetimes to explicitly capture them"), + self.suggs, + Applicability::MachineApplicable, + ); + } +} + /// Given a set of captured `DefId` for an RPIT (opaque_def_id) and a given /// function (fn_def_id), try to suggest adding `+ use<...>` to capture just /// the specified parameters. If one of those parameters is an APIT, then try diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 20a3f56ef5e48..688272a5239f5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1,6 +1,6 @@ use std::iter; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{ Applicability, Diag, E0309, E0310, E0311, E0803, Subdiagnostic, msg, struct_span_code_err, }; @@ -8,6 +8,8 @@ use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, ParamName}; +use rustc_middle::hir::nested_filter; +use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::RegionHighlightMode; @@ -934,72 +936,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { lifetime: Region<'tcx>, add_lt_suggs: &mut Vec<(Span, String)>, ) -> Option { - struct LifetimeReplaceVisitor<'a> { - needle: hir::LifetimeKind, - new_lt: &'a str, - add_lt_suggs: &'a mut Vec<(Span, String)>, - } - - impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> { - fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) { - if lt.kind == self.needle { - self.add_lt_suggs.push(lt.suggestion(self.new_lt)); - } - } - } - - let (lifetime_def_id, lifetime_scope) = - match self.tcx.is_suitable_region(generic_param_scope, lifetime) { - Some(info) if !lifetime.is_named(self.tcx) => { - (info.region_def_id.expect_local(), info.scope) - } - _ => return Some(lifetime.get_name(self.tcx)?.to_string()), - }; - - let new_lt = { - let generics = self.tcx.generics_of(lifetime_scope); - let mut used_names = - iter::successors(Some(generics), |g| g.parent.map(|p| self.tcx.generics_of(p))) - .flat_map(|g| &g.own_params) - .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime)) - .map(|p| p.name) - .collect::>(); - let hir_id = self.tcx.local_def_id_to_hir_id(lifetime_scope); - // consider late-bound lifetimes ... - used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map( - |p| match p { - ty::BoundVariableKind::Region(lt) => lt.get_name(self.tcx), - _ => None, - }, - )); - (b'a'..=b'z') - .map(|c| format!("'{}", c as char)) - .find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate)) - .unwrap_or_else(|| "'lt".to_string()) - }; - - let mut visitor = LifetimeReplaceVisitor { - needle: hir::LifetimeKind::Param(lifetime_def_id), - add_lt_suggs, - new_lt: &new_lt, - }; - match self.tcx.expect_hir_owner_node(lifetime_scope) { - hir::OwnerNode::Item(i) => visitor.visit_item(i), - hir::OwnerNode::ForeignItem(i) => visitor.visit_foreign_item(i), - hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i), - hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i), - hir::OwnerNode::Crate(_) => bug!("OwnerNode::Crate doesn't not have generics"), - hir::OwnerNode::Synthetic => unreachable!(), - } - - let ast_generics = self.tcx.hir_get_generics(lifetime_scope).unwrap(); - let sugg = ast_generics - .span_for_lifetime_suggestion() - .map(|span| (span, format!("{new_lt}, "))) - .unwrap_or_else(|| (ast_generics.span, format!("<{new_lt}>"))); - add_lt_suggs.push(sugg); - - Some(new_lt) + let [name] = + suggest_name_regions(self.tcx, generic_param_scope, &[lifetime], add_lt_suggs)? + .try_into() + .unwrap(); + Some(name) } fn report_sub_sup_conflict( @@ -1169,6 +1110,101 @@ pub(super) fn note_and_explain_region<'tcx>( emit_msg_span(err, prefix, description, span, suffix); } +fn suggest_name_regions<'tcx>( + tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, + lifetimes: &[Region<'tcx>], + add_lt_suggs: &mut Vec<(Span, String)>, +) -> Option> { + struct LifetimeReplaceVisitor<'a> { + new_lts: &'a [(LocalDefId, String)], + add_lt_suggs: &'a mut Vec<(Span, String)>, + } + + impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> { + fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) { + if let hir::LifetimeKind::Param(def_id) = lt.kind + && let Some((_, new_lt)) = self.new_lts.iter().find(|(id, _)| *id == def_id) + { + self.add_lt_suggs.push(lt.suggestion(new_lt)); + } + } + } + + let mut lifetime_scope = None; + let mut used_names = vec![]; + let mut new_lts: Vec<(LocalDefId, String)> = vec![]; + let names: Vec<_> = lifetimes + .iter() + .map(|&lifetime| { + let (lifetime_def_id, scope) = + match tcx.is_suitable_region(generic_param_scope, lifetime) { + Some(info) if !lifetime.is_named(tcx) => { + (info.region_def_id.expect_local(), info.scope) + } + _ => return Some(lifetime.get_name(tcx)?.to_string()), + }; + if *lifetime_scope.get_or_insert_with(|| { + used_names.extend( + iter::successors(Some(tcx.generics_of(scope)), |g| { + g.parent.map(|p| tcx.generics_of(p)) + }) + .flat_map(|g| &g.own_params) + .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime)) + .map(|p| p.name), + ); + // consider late-bound lifetimes ... + used_names.extend( + tcx.late_bound_vars(tcx.local_def_id_to_hir_id(scope)).into_iter().filter_map( + |p| match p { + ty::BoundVariableKind::Region(lt) => lt.get_name(tcx), + _ => None, + }, + ), + ); + scope + }) != scope + { + return Some(lifetime.get_name(tcx)?.to_string()); + } + if let Some((_, name)) = new_lts.iter().find(|(id, _)| *id == lifetime_def_id) { + return Some(name.clone()); + } + let new_lt = (b'a'..=b'z') + .map(|c| format!("'{}", c as char)) + .find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate)) + .unwrap_or_else(|| "'lt".to_string()); + used_names.push(Symbol::intern(&new_lt)); + new_lts.push((lifetime_def_id, new_lt.clone())); + Some(new_lt) + }) + .collect::>()?; + + let Some(lifetime_scope) = lifetime_scope else { + return Some(names); + }; + + let mut visitor = LifetimeReplaceVisitor { new_lts: &new_lts, add_lt_suggs }; + match tcx.expect_hir_owner_node(lifetime_scope) { + hir::OwnerNode::Item(i) => visitor.visit_item(i), + hir::OwnerNode::ForeignItem(i) => visitor.visit_foreign_item(i), + hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i), + hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i), + hir::OwnerNode::Crate(_) => bug!("OwnerNode::Crate doesn't not have generics"), + hir::OwnerNode::Synthetic => unreachable!(), + } + + let new_lt = new_lts.into_iter().map(|(_, name)| name).collect::>().join(", "); + let ast_generics = tcx.hir_get_generics(lifetime_scope).unwrap(); + let sugg = ast_generics + .span_for_lifetime_suggestion() + .map(|span| (span, format!("{new_lt}, "))) + .unwrap_or_else(|| (ast_generics.span, format!("<{new_lt}>"))); + add_lt_suggs.push(sugg); + + Some(names) +} + fn explain_free_region<'tcx>( tcx: TyCtxt<'tcx>, err: &mut Diag<'_>, @@ -1319,7 +1355,14 @@ pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( "", ); if let Some(_) = tcx.is_suitable_region(generic_param_scope, hidden_region) { - suggest_precise_capturing(tcx, opaque_ty_key.def_id, hidden_region, &mut err); + suggest_precise_capturing( + tcx, + generic_param_scope, + opaque_ty_key.def_id, + hidden_ty.value, + hidden_region, + &mut err, + ); } } ty::RePlaceholder(_) => { @@ -1368,7 +1411,9 @@ pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( fn suggest_precise_capturing<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, opaque_def_id: LocalDefId, + hidden_ty: Ty<'tcx>, captured_lifetime: ty::Region<'tcx>, diag: &mut Diag<'_>, ) { @@ -1455,11 +1500,30 @@ fn suggest_precise_capturing<'tcx>( } } - if !captured_lifetimes.insert(new_lifetime) { + if captured_lifetimes.contains(&new_lifetime) { // Uh, strange. This lifetime appears to already be captured... return; } + // `'_` in a capture list only resolves when the signature has a single anonymous + // lifetime, so when there are several the suggestion has to name them first. + if synthetics.is_empty() + && let Some(suggs) = name_anon_lifetimes_suggestion( + tcx, + generic_param_scope, + opaque_def_id, + fn_def_id, + hidden_ty, + &captured_lifetimes, + &captured_non_lifetimes, + ) + { + diag.subdiagnostic(diagnostics::AddPreciseCapturingAndNameLifetimes { suggs }); + return; + } + + captured_lifetimes.insert(new_lifetime); + if synthetics.is_empty() { let concatenated_bounds = captured_lifetimes .into_iter() @@ -1543,3 +1607,103 @@ fn suggest_precise_capturing<'tcx>( } } } + +/// Build a suggestion that names every anonymous lifetime the hidden type captures and then +/// lists them in a `use<..>` bound. +/// +/// This exists because a `use<..>` list cannot refer to more than one anonymous lifetime: `'_` +/// resolves like any other elided lifetime, so with several in the signature it either picks the +/// wrong one or fails to resolve at all. Naming them is the only way to write the bound the hidden +/// type actually needs. +/// +/// Returns `None` whenever the plain `'_` suggestion is still correct, so that the common +/// single-lifetime case keeps its shorter form. +fn name_anon_lifetimes_suggestion<'tcx>( + tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, + opaque_def_id: LocalDefId, + fn_def_id: LocalDefId, + hidden_ty: Ty<'tcx>, + captured_lifetimes: &FxIndexSet, + captured_non_lifetimes: &FxIndexSet, +) -> Option> { + let fn_sig = tcx.hir_node_by_def_id(fn_def_id).fn_sig()?; + + let mut collector = AnonLifetimeCollector { tcx, anon_lifetimes: Default::default() }; + for input in fn_sig.decl.inputs { + collector.visit_ty_unambig(input); + } + // With a single anonymous lifetime in the signature `'_` resolves to it, so leave that case + // to the caller. + if collector.anon_lifetimes.len() < 2 { + return None; + } + + let mut hidden_regions = FxIndexMap::default(); + tcx.for_each_free_region(&hidden_ty, |region| { + if let Some(info) = tcx.is_suitable_region(generic_param_scope, region) { + hidden_regions.entry(info.region_def_id).or_insert(region); + } + }); + + // A lifetime the user already named stays as it is; only the anonymous ones need inventing + // a name, and they are named in the order they appear in the signature. + let named = hidden_regions + .iter() + .filter(|(def_id, _)| !collector.anon_lifetimes.contains(*def_id)) + .map(|(_, ®ion)| region); + let anon: Vec<_> = collector + .anon_lifetimes + .iter() + .filter_map(|def_id| hidden_regions.get(def_id).copied()) + .collect(); + if anon.is_empty() { + return None; + } + let regions: Vec<_> = named.chain(anon).collect(); + + let mut suggs = vec![]; + let mut bounds = captured_lifetimes.clone(); + bounds.extend( + suggest_name_regions(tcx, generic_param_scope, ®ions, &mut suggs)? + .iter() + .map(|name| Symbol::intern(name)), + ); + + let concatenated_bounds = bounds + .into_iter() + .chain(captured_non_lifetimes.iter().copied()) + .map(|sym| sym.to_string()) + .collect::>() + .join(", "); + suggs.push(( + tcx.def_span(opaque_def_id).shrink_to_hi(), + format!(" + use<{concatenated_bounds}>"), + )); + + Some(suggs) +} + +/// Collects every anonymous lifetime written in a function signature. +struct AnonLifetimeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + anon_lifetimes: FxIndexSet, +} + +impl<'tcx> Visitor<'tcx> for AnonLifetimeCollector<'tcx> { + type NestedFilter = nested_filter::OnlyBodies; + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx + } + + fn visit_lifetime(&mut self, lifetime: &'tcx hir::Lifetime) { + if lifetime.is_anonymous() + && let Some( + rbv::ResolvedArg::EarlyBound(def_id) | rbv::ResolvedArg::LateBound(_, _, def_id), + ) = self.tcx.named_bound_var(lifetime.hir_id) + { + self.anon_lifetimes.insert(def_id.to_def_id()); + } + } +} diff --git a/library/std/src/sys/thread_local/guard/key.rs b/library/std/src/sys/thread_local/guard/key.rs index f91471419c1cc..1d4e4c76a47a8 100644 --- a/library/std/src/sys/thread_local/guard/key.rs +++ b/library/std/src/sys/thread_local/guard/key.rs @@ -2,12 +2,11 @@ //! destructors for native TLS. Instead, we use one TLS key with a destructor //! that will run all native TLS destructors in the destructor list. -use crate::ptr; -use crate::sys::thread_local::key::{LazyKey, set}; - #[cfg(target_thread_local)] pub fn enable() { + use crate::ptr; use crate::sys::thread_local::destructors; + use crate::sys::thread_local::key::{LazyKey, set}; static DTORS: LazyKey = LazyKey::new(Some(run)); @@ -30,18 +29,26 @@ pub fn enable() { } } -/// On platforms with key-based TLS, the system runs the destructors for us. -/// We still have to make sure that [`crate::rt::thread_cleanup`] is called, -/// however. This is done by deferring the execution of a TLS destructor to -/// the next round of destruction inside the TLS destructors. #[cfg(not(target_thread_local))] -pub fn enable() { +pub use key_based::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending, enable}; + +#[cfg(not(target_thread_local))] +mod key_based { + use crate::ptr; + use crate::sys::thread_local::key::{LazyKey, get, set}; + const DEFER: *mut u8 = ptr::without_provenance_mut(1); const RUN: *mut u8 = ptr::without_provenance_mut(2); static CLEANUP: LazyKey = LazyKey::new(Some(run)); - unsafe { set(CLEANUP.force(), DEFER) } + /// On platforms with key-based TLS, the system runs the destructors for us. + /// We still have to make sure that [`crate::rt::thread_cleanup`] is called, + /// however. This is done by deferring the execution of a TLS destructor to + /// the next round of destruction inside the TLS destructors. + pub fn enable() { + unsafe { set(CLEANUP.force(), DEFER) } + } unsafe extern "C" fn run(state: *mut u8) { if state == DEFER { @@ -57,4 +64,16 @@ pub fn enable() { crate::rt::thread_cleanup(); } } + + /// Whether [`crate::rt::thread_cleanup`] has yet to run on this thread. + pub fn cleanup_pending() -> bool { + !unsafe { get(CLEANUP.force()) }.is_null() + } + + /// The OS may free the values of the keys without a destructor **before** + /// [`crate::rt::thread_cleanup`] runs (e.g. ESP-IDF, glibc and musl free + /// them in the first round of TLS destruction). Hence, local pointers need + /// a destructor, which stores the value again for as long as + /// [`cleanup_pending`] returns `true`. + pub const LOCAL_POINTER_NEEDS_DTOR: bool = true; } diff --git a/library/std/src/sys/thread_local/guard/retained.rs b/library/std/src/sys/thread_local/guard/retained.rs new file mode 100644 index 0000000000000..53efe790b4629 --- /dev/null +++ b/library/std/src/sys/thread_local/guard/retained.rs @@ -0,0 +1,11 @@ +//! Guards which run all TLS destructors themselves, and only then +//! [`crate::rt::thread_cleanup`], never free the values of keys without a +//! destructor before the cleanup. Hence, local pointers need no destructor. + +pub const LOCAL_POINTER_NEEDS_DTOR: bool = false; + +/// Only referenced by the `keep` destructor of `local_pointer!`, which is +/// never registered here (`LOCAL_POINTER_NEEDS_DTOR` is `false`). +pub fn cleanup_pending() -> bool { + rtabort!("`cleanup_pending` called although `LOCAL_POINTER_NEEDS_DTOR` is false") +} diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index f86d25e38efb5..5d3c23ce04678 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -104,6 +104,10 @@ pub(crate) mod guard { target_os = "windows" => { mod windows; pub(crate) use windows::enable; + #[cfg(not(target_thread_local))] + mod retained; + #[cfg(not(target_thread_local))] + pub(crate) use retained::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending}; } any( all(target_family = "wasm", not(target_os = "wasi")), @@ -130,6 +134,10 @@ pub(crate) mod guard { // `std` is the only runtime, so it just calls the destructor functions // itself when the time comes. pub(crate) fn enable() {} + #[cfg(not(target_thread_local))] + mod retained; + #[cfg(not(target_thread_local))] + pub(crate) use retained::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending}; } target_os = "solid_asp3" => { mod solid; @@ -138,6 +146,8 @@ pub(crate) mod guard { _ => { mod key; pub(crate) use key::enable; + #[cfg(not(target_thread_local))] + pub(crate) use key::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending}; } } } diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 8588fc994350b..5fb937d717e57 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -253,8 +253,25 @@ unsafe extern "C" fn destroy_value(ptr: *mut u8) #[rustc_macro_transparency = "semiopaque"] pub(crate) macro local_pointer { () => {}, + // A local pointer stays readable until `crate::rt::thread_cleanup` has run. + // The guard decides whether the key needs a destructor for that, which + // stores the value again for as long as the cleanup is pending. ($vis:vis static $name:ident; $($rest:tt)*) => { - $vis static $name: $crate::sys::thread_local::LocalPointer = $crate::sys::thread_local::LocalPointer::__new(); + $vis static $name: $crate::sys::thread_local::LocalPointer = { + unsafe extern "C" fn keep(value: *mut u8) { + if $crate::sys::thread_local::guard::cleanup_pending() { + $name.set(value.cast()); + } + } + + $crate::sys::thread_local::LocalPointer::__new( + if $crate::sys::thread_local::guard::LOCAL_POINTER_NEEDS_DTOR { + Some(keep) + } else { + None + }, + ) + }; $crate::sys::thread_local::local_pointer! { $($rest)* } }, } @@ -264,8 +281,8 @@ pub(crate) struct LocalPointer { } impl LocalPointer { - pub const fn __new() -> LocalPointer { - LocalPointer { key: LazyKey::new(None) } + pub const fn __new(dtor: Option) -> LocalPointer { + LocalPointer { key: LazyKey::new(dtor) } } pub fn get(&'static self) -> *mut () { diff --git a/library/std/tests/thread_local/lib.rs b/library/std/tests/thread_local/lib.rs index 26af5f1eb0a9d..c52914354253c 100644 --- a/library/std/tests/thread_local/lib.rs +++ b/library/std/tests/thread_local/lib.rs @@ -1,5 +1,3 @@ -#![feature(cfg_target_thread_local)] - #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] mod tests; diff --git a/library/std/tests/thread_local/tests.rs b/library/std/tests/thread_local/tests.rs index df9b99ef0af64..c2164a0bc2cff 100644 --- a/library/std/tests/thread_local/tests.rs +++ b/library/std/tests/thread_local/tests.rs @@ -353,14 +353,10 @@ fn join_orders_after_tls_destructors() { // Test that thread::current is still available in TLS destructors. // -// The test won't currently work without target_thread_local, aka with slow tls. -// The runtime tries very hard to drop last the TLS variable that keeps the information about the -// current thread, by using several tricks like deferring the drop to a later round of TLS destruction. -// However, this only seems to work with fast tls. -// -// With slow TLS, it seems that multiple libc implementations will just set the value to null the first -// time they encounter it, regardless of it having a destructor or not. This means that trying to -// retrieve it later in a drop impl of another TLS variable will not work. +// With slow TLS (i.e. without target_thread_local), multiple libc implementations set the value of +// a key to null the first time they encounter it, regardless of it having a destructor or not. The +// handle of the current thread is stored in a local pointer, which stays readable until it is +// dropped in the last round of TLS destruction. // // ** Apple libc: https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread_tsd.c#L293 // Sets the variable to null if it has a destructor and the value is not null. However, all variables @@ -368,7 +364,6 @@ fn join_orders_after_tls_destructors() { // it is null. // ** glibc: https://github.com/bminor/glibc/blob/e5893e6349541d871e8a25120bca014551d13ff5/nptl/nptl_deallocate_tsd.c#L59 // ** musl: https://github.com/kraj/musl/blob/1880359b54ff7dd9f5016002bfdae4b136007dde/src/thread/pthread_key_create.c#L87 -#[cfg(target_thread_local)] #[test] fn thread_current_in_dtor() { use std::thread::Builder; diff --git a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile index 0675c3cafd9e7..948c958595e08 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM ubuntu:22.04 # Enable source repositories, which are disabled by default on Ubuntu >= 18.04 RUN sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list diff --git a/src/tools/miri/tests/fail/c-variadic-ignored-argument.rs b/src/tools/miri/tests/fail/function_calls/c-variadic-ignored-argument.rs similarity index 100% rename from src/tools/miri/tests/fail/c-variadic-ignored-argument.rs rename to src/tools/miri/tests/fail/function_calls/c-variadic-ignored-argument.rs diff --git a/src/tools/miri/tests/fail/c-variadic-ignored-argument.stderr b/src/tools/miri/tests/fail/function_calls/c-variadic-ignored-argument.stderr similarity index 74% rename from src/tools/miri/tests/fail/c-variadic-ignored-argument.stderr rename to src/tools/miri/tests/fail/function_calls/c-variadic-ignored-argument.stderr index 6c1291611c4ae..3376f3617eba4 100644 --- a/src/tools/miri/tests/fail/c-variadic-ignored-argument.stderr +++ b/src/tools/miri/tests/fail/function_calls/c-variadic-ignored-argument.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: va_arg type mismatch: requested `i32` is incompatible with next argument of type `()` - --> tests/fail/c-variadic-ignored-argument.rs:LL:CC + --> tests/fail/function_calls/c-variadic-ignored-argument.rs:LL:CC | LL | ap.next_arg::(); | ^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here @@ -8,9 +8,9 @@ LL | ap.next_arg::(); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: stack backtrace: 0: main::variadic - at tests/fail/c-variadic-ignored-argument.rs:LL:CC + at tests/fail/function_calls/c-variadic-ignored-argument.rs:LL:CC 1: main - at tests/fail/c-variadic-ignored-argument.rs:LL:CC + at tests/fail/function_calls/c-variadic-ignored-argument.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/c-variadic-mismatch-count.rs b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch-count.rs similarity index 100% rename from src/tools/miri/tests/fail/c-variadic-mismatch-count.rs rename to src/tools/miri/tests/fail/function_calls/c-variadic-mismatch-count.rs diff --git a/src/tools/miri/tests/fail/c-variadic-mismatch-count.stderr b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch-count.stderr similarity index 89% rename from src/tools/miri/tests/fail/c-variadic-mismatch-count.stderr rename to src/tools/miri/tests/fail/function_calls/c-variadic-mismatch-count.stderr index 9350b99861964..c8e3bbbbe2095 100644 --- a/src/tools/miri/tests/fail/c-variadic-mismatch-count.stderr +++ b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch-count.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: calling a C-variadic function with 0 fixed arguments, but the function expects 1 - --> tests/fail/c-variadic-mismatch-count.rs:LL:CC + --> tests/fail/function_calls/c-variadic-mismatch-count.rs:LL:CC | LL | f(1); | ^^^^ Undefined Behavior occurred here diff --git a/src/tools/miri/tests/fail/c-variadic-mismatch.rs b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch.rs similarity index 90% rename from src/tools/miri/tests/fail/c-variadic-mismatch.rs rename to src/tools/miri/tests/fail/function_calls/c-variadic-mismatch.rs index 8387f6e12d4eb..d986d33db3d0c 100644 --- a/src/tools/miri/tests/fail/c-variadic-mismatch.rs +++ b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch.rs @@ -1,3 +1,4 @@ +//! Callee is variadic, caller not. unsafe extern "C" fn helper(_: i32, _: ...) {} fn main() { diff --git a/src/tools/miri/tests/fail/c-variadic-mismatch.stderr b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch.stderr similarity index 90% rename from src/tools/miri/tests/fail/c-variadic-mismatch.stderr rename to src/tools/miri/tests/fail/function_calls/c-variadic-mismatch.stderr index a68b96f738d22..4560b8f204c10 100644 --- a/src/tools/miri/tests/fail/c-variadic-mismatch.stderr +++ b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: calling a function where the caller and callee disagree on whether the function is C-variadic - --> tests/fail/c-variadic-mismatch.rs:LL:CC + --> tests/fail/function_calls/c-variadic-mismatch.rs:LL:CC | LL | f(1i32, 1i64); | ^^^^^^^^^^^^^ Undefined Behavior occurred here diff --git a/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.rs b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.rs new file mode 100644 index 0000000000000..a55c5d6d21131 --- /dev/null +++ b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.rs @@ -0,0 +1,14 @@ +//! Caller is variadic, callee not. +mod module { + #[unsafe(no_mangle)] + extern "C" fn weird() {} +} + +unsafe extern "C" { + fn weird(_: ...); +} + +fn main() { + unsafe { weird(1_i32) }; + //~^ ERROR: Undefined Behavior: calling a function where the caller and callee disagree on whether the function is C-variadic +} diff --git a/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.stderr b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.stderr new file mode 100644 index 0000000000000..96f28830d1fcb --- /dev/null +++ b/src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: calling a function where the caller and callee disagree on whether the function is C-variadic + --> tests/fail/function_calls/c-variadic-mismatch2.rs:LL:CC + | +LL | unsafe { weird(1_i32) }; + | ^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/c-variadic.rs b/src/tools/miri/tests/fail/function_calls/c-variadic.rs similarity index 100% rename from src/tools/miri/tests/fail/c-variadic.rs rename to src/tools/miri/tests/fail/function_calls/c-variadic.rs diff --git a/src/tools/miri/tests/fail/c-variadic.stderr b/src/tools/miri/tests/fail/function_calls/c-variadic.stderr similarity index 73% rename from src/tools/miri/tests/fail/c-variadic.stderr rename to src/tools/miri/tests/fail/function_calls/c-variadic.stderr index bc474c34e706c..2c604d33e11eb 100644 --- a/src/tools/miri/tests/fail/c-variadic.stderr +++ b/src/tools/miri/tests/fail/function_calls/c-variadic.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: more C-variadic arguments read than were passed - --> tests/fail/c-variadic.rs:LL:CC + --> tests/fail/function_calls/c-variadic.rs:LL:CC | LL | ap.next_arg::(); | ^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here @@ -8,11 +8,11 @@ LL | ap.next_arg::(); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: stack backtrace: 0: read_too_many::variadic - at tests/fail/c-variadic.rs:LL:CC + at tests/fail/function_calls/c-variadic.rs:LL:CC 1: read_too_many - at tests/fail/c-variadic.rs:LL:CC + at tests/fail/function_calls/c-variadic.rs:LL:CC 2: main - at tests/fail/c-variadic.rs:LL:CC + at tests/fail/function_calls/c-variadic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir index a4154615eca6c..340d8e7a2a6b4 100644 --- a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,14 +1,16 @@ // MIR for `add::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async -fn add::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:34:13: 34:18}, _2: &mut Context<'_>) -> Poll<()> { +fn add::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir index f398c48c3b8cc..d68ee8ad3916c 100644 --- a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `add::{closure#0}` 0 coroutine_drop_proxy_async -fn add::{closure#0}(_1: {async fn body of add()}, _2: &mut Context<'_>) -> Poll<()> { +fn add::{closure#0}(_1: Pin<&mut {async fn body of add()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of add()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { scope 3 { @@ -16,9 +17,10 @@ fn add::{closure#0}(_1: {async fn body of add()}, _2: &mut Context<'_>) -> Poll< } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of add()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir index 68b809e50f7b3..48b300e4b7036 100644 --- a/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.build_aggregate-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `build_aggregate::{closure#0}` 0 coroutine_drop_proxy_async -fn build_aggregate::{closure#0}(_1: {async fn body of build_aggregate()}, _2: &mut Context<'_>) -> Poll<()> { +fn build_aggregate::{closure#0}(_1: Pin<&mut {async fn body of build_aggregate()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of build_aggregate()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { scope 3 { @@ -24,9 +25,10 @@ fn build_aggregate::{closure#0}(_1: {async fn body of build_aggregate()}, _2: &m } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of build_aggregate()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir index b15cd698a68d1..047813965fedd 100644 --- a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,14 +1,16 @@ // MIR for `foo::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async -fn foo::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:21:13: 21:18}, _2: &mut Context<'_>) -> Poll<()> { +fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:21:13: 21:18}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:21:13: 21:18}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir index 3eba8934af246..0d01b66cae199 100644 --- a/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.foo-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `foo::{closure#0}` 0 coroutine_drop_proxy_async -fn foo::{closure#0}(_1: {async fn body of foo()}, _2: &mut Context<'_>) -> Poll<()> { +fn foo::{closure#0}(_1: Pin<&mut {async fn body of foo()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of foo()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { scope 3 { @@ -26,9 +27,10 @@ fn foo::{closure#0}(_1: {async fn body of foo()}, _2: &mut Context<'_>) -> Poll< } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of foo()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir index 891d350d6c32d..4e414f13bbb90 100644 --- a/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.hello_world-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `hello_world::{closure#0}` 0 coroutine_drop_proxy_async -fn hello_world::{closure#0}(_1: {async fn body of hello_world()}, _2: &mut Context<'_>) -> Poll<()> { +fn hello_world::{closure#0}(_1: Pin<&mut {async fn body of hello_world()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of hello_world()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { scope 3 { @@ -16,9 +17,10 @@ fn hello_world::{closure#0}(_1: {async fn body of hello_world()}, _2: &mut Conte } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of hello_world()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir index 8058024c54e96..f7a37bf788209 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,14 +1,16 @@ // MIR for `includes_never::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async -fn includes_never::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:61:18: 61:23}, _2: &mut Context<'_>) -> Poll<()> { +fn includes_never::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir index aa204dda81046..d4b0fe3addb0b 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop_proxy_async.0.mir @@ -1,14 +1,16 @@ // MIR for `includes_never::{closure#0}::{closure#1}` 0 coroutine_drop_proxy_async -fn includes_never::{closure#0}::{closure#1}(_1: {async block@$DIR/async_fn.rs:67:15: 67:20}, _2: &mut Context<'_>) -> Poll<()> { +fn includes_never::{closure#0}::{closure#1}(_1: Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir index 0acb7d03405bb..6451f7dfe1f35 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `includes_never::{closure#0}` 0 coroutine_drop_proxy_async -fn includes_never::{closure#0}(_1: {async fn body of includes_never()}, _2: &mut Context<'_>) -> Poll<()> { +fn includes_never::{closure#0}(_1: Pin<&mut {async fn body of includes_never()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of includes_never()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { scope 3 { @@ -24,9 +25,10 @@ fn includes_never::{closure#0}(_1: {async fn body of includes_never()}, _2: &mut } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of includes_never()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir index 95842dccc1e19..01470de2bf310 100644 --- a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,14 +1,16 @@ // MIR for `partial_init::{closure#0}::{closure#0}` 0 coroutine_drop_proxy_async -fn partial_init::{closure#0}::{closure#0}(_1: {async block@$DIR/async_fn.rs:80:50: 80:55}, _2: &mut Context<'_>) -> Poll<()> { +fn partial_init::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir index bbcda31ad6e55..ceafb93594fbe 100644 --- a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `partial_init::{closure#0}` 0 coroutine_drop_proxy_async -fn partial_init::{closure#0}(_1: {async fn body of partial_init()}, _2: &mut Context<'_>) -> Poll<()> { +fn partial_init::{closure#0}(_1: Pin<&mut {async fn body of partial_init()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of partial_init()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { } @@ -16,9 +17,10 @@ fn partial_init::{closure#0}(_1: {async fn body of partial_init()}, _2: &mut Con } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of partial_init()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir index 124debea519c1..29bb3f60a748e 100644 --- a/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir +++ b/tests/mir-opt/coroutine/async_fn.uninhabited_variant-{closure#0}.coroutine_drop_proxy_async.0.mir @@ -1,9 +1,10 @@ // MIR for `uninhabited_variant::{closure#0}` 0 coroutine_drop_proxy_async -fn uninhabited_variant::{closure#0}(_1: {async fn body of uninhabited_variant()}, _2: &mut Context<'_>) -> Poll<()> { +fn uninhabited_variant::{closure#0}(_1: Pin<&mut {async fn body of uninhabited_variant()}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: std::task::Poll<()>; - let mut _3: std::future::ResumeTy; - let mut _4: std::ptr::NonNull>; + let mut _3: &mut {async fn body of uninhabited_variant()}; + let mut _4: std::future::ResumeTy; + let mut _5: std::ptr::NonNull>; scope 1 { scope 2 { scope 3 { @@ -18,9 +19,10 @@ fn uninhabited_variant::{closure#0}(_1: {async fn body of uninhabited_variant()} } bb0: { - _4 = move _2 as std::ptr::NonNull> (Transmute); - _3 = std::future::ResumeTy(move _4); - drop(_1) -> [return: bb1, unwind continue]; + _5 = move _2 as std::ptr::NonNull> (Transmute); + _4 = std::future::ResumeTy(move _5); + _3 = copy (_1.0: &mut {async fn body of uninhabited_variant()}); + drop((*_3)) -> [return: bb1, unwind continue]; } bb1: { diff --git a/tests/ui/README.md b/tests/ui/README.md index 27995e0ab4cd5..ded2ef7496303 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -215,7 +215,7 @@ Tests for the `--check-cfg` compiler mechanism for checking cfg configurations, See [Checking conditional configurations | The rustc book](https://doc.rust-lang.org/rustc/check-cfg.html). -## `tests/ui/checked-type-alias/` +## `tests/ui/checked-type-aliases/` Tests for `#![feature(checked_type_aliases)]`. See [Tracking issue for checked type aliases](https://github.com/rust-lang/rust/issues/112792). diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.rs b/tests/ui/associated-inherent-types/type-alias-bounds.rs index 61641a83994ab..364ff77cd74b1 100644 --- a/tests/ui/associated-inherent-types/type-alias-bounds.rs +++ b/tests/ui/associated-inherent-types/type-alias-bounds.rs @@ -7,15 +7,15 @@ // FIXME(inherent_associated_types): // While we currently do take some clauses of the ParamEnv into consideration // when performing IAT selection, we do not perform full well-formedness checking -// for (eager) type alias definition and usage sites. +// for (unchecked) type alias definition and usage sites. // // Therefore it's *correct* for lint `type_alias_bounds` to fire here despite the // fact that removing `Bound` from `T` in `Alias` would lead to an error! // // Obviously, the present situation isn't ideal and we should fix it in one way // or another. Either we somehow delay IAT selection until after HIR ty lowering -// to avoid the need to specify any bounds inside (eager) type aliases or we -// force the overarching type alias to be *lazy* (similar to TAITs) which would +// to avoid the need to specify any bounds inside (unchecked) type aliases or we +// force the overarching type alias to be *checked* (similar to TAITs) which would // automatically lead to full wfchecking and lint TAB getting suppressed. pub type Alias = (Source::Assoc,); diff --git a/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.rs b/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.rs new file mode 100644 index 0000000000000..337cf78c2c200 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.rs @@ -0,0 +1,26 @@ +//@ run-pass +//@ check-run-results +//@ edition: 2024 + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::{future::Future, pin::pin, task::{Context, Poll, Waker}}; + +struct Bar; +impl Drop for Bar { + fn drop(&mut self) { println!("Bar dropped"); } +} + +async fn outer() { + let b = Bar; + let _inner = async move { let _x = &b; }; + println!("end of outer"); +} + +fn main() { + let mut f = pin!(outer()); + let mut cx = Context::from_waker(Waker::noop()); + while let Poll::Pending = f.as_mut().poll(&mut cx) {} + println!("done"); +} diff --git a/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.run.stdout b/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.run.stdout new file mode 100644 index 0000000000000..5b2df0a2ed572 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.run.stdout @@ -0,0 +1,3 @@ +end of outer +Bar dropped +done diff --git a/tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.rs b/tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.rs new file mode 100644 index 0000000000000..2828647348712 --- /dev/null +++ b/tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.rs @@ -0,0 +1,32 @@ +//! Regression test for . On assignment statements, +//! borrowck's dataflow analysis kills borrows that it knows conflict with the assigment: a borrow +//! of a place can't be live anymore after that place is assigned over. Previously, this didn't +//! account for fake borrows being shallow: it would kill any shallow borrows that would have +//! conflicted if they were normal borrows. This made it possible to circumvent fake borrows for +//! match guards and indexing expressions. + +fn test_match_guard() { + let mut a = (Some(&42u64), 0u8); + let mut b = (None::<&u64>, 0u8); + let mut p = &mut a; + // Writing to `(*p).1` in the match guard previously killed the fake borrow of `p` in the guard, + // making it possible to mutate `p` despite `(*p).0` being matched on. This would reach the + // `Some(r)` branch with `(*p).0` being `None`, so the `r` binding was invalid. + match p.0 { + Some(_) if { p.1 = 1; p = &mut b; false } => unreachable!(), + //~^ ERROR: cannot assign `p` in match guard + Some(r) => println!("{r}"), + None => unreachable!(), + } +} + +fn test_indexing() { + let mut x: &mut [&mut [u32]] = &mut [&mut [0]]; + let y: &mut [&mut [u32]] = &mut []; + // Writing to `x[0][0]` previously killed the fake borrow of `x` in the index expression, making + // it possible to access `y[0]` without a bounds-check. + x[0][{ x[0][0] = 1; x = y; 0 }]; + //~^ ERROR: cannot assign `x` in indexing expression +} + +fn main() {} diff --git a/tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.stderr b/tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.stderr new file mode 100644 index 0000000000000..b45a75a9c6340 --- /dev/null +++ b/tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.stderr @@ -0,0 +1,19 @@ +error[E0510]: cannot assign `p` in match guard + --> $DIR/dont-kill-shallow-borrows-on-child-writes.rs:16:31 + | +LL | match p.0 { + | --- value is immutable in match guard +LL | Some(_) if { p.1 = 1; p = &mut b; false } => unreachable!(), + | ^^^^^^^^^^ cannot assign + +error[E0510]: cannot assign `x` in indexing expression + --> $DIR/dont-kill-shallow-borrows-on-child-writes.rs:28:25 + | +LL | x[0][{ x[0][0] = 1; x = y; 0 }]; + | ---- ^^^^^ cannot assign + | | + | value is immutable in indexing expression + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0510`. diff --git a/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.rs b/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.rs deleted file mode 100644 index d8bf559690747..0000000000000 --- a/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ revisions: locally_eager locally_lazy -//@ aux-crate:lazy=lazy.rs -//@ edition: 2021 - -// Test that we treat lazy type aliases from external crates as lazy independently of whether the -// local crate enables `checked_type_aliases` or not. - -#![cfg_attr( - locally_lazy, - feature(checked_type_aliases), - allow(incomplete_features) -)] - -fn main() { - let _: lazy::Alias; //~ ERROR the trait bound `String: Copy` is not satisfied -} diff --git a/tests/ui/checked-type-alias/auto-trait-impls.rs b/tests/ui/checked-type-aliases/auto-trait-impls.rs similarity index 95% rename from tests/ui/checked-type-alias/auto-trait-impls.rs rename to tests/ui/checked-type-aliases/auto-trait-impls.rs index 978143ef7cf56..b3f0f463e5967 100644 --- a/tests/ui/checked-type-alias/auto-trait-impls.rs +++ b/tests/ui/checked-type-aliases/auto-trait-impls.rs @@ -1,4 +1,4 @@ -//! Auto-trait impls whose self type is a free (lazy) type alias are checked against the +//! Auto-trait impls whose self type is a free alias type are checked against the //! type the alias *expands* to, not the alias itself. An alias resolving to an otherwise //! valid nominal type is accepted, just as if the underlying type had been written //! directly; an alias resolving to a problematic type is still rejected. diff --git a/tests/ui/checked-type-alias/auto-trait-impls.stderr b/tests/ui/checked-type-aliases/auto-trait-impls.stderr similarity index 100% rename from tests/ui/checked-type-alias/auto-trait-impls.stderr rename to tests/ui/checked-type-aliases/auto-trait-impls.stderr diff --git a/tests/ui/checked-type-alias/auxiliary/lazy.rs b/tests/ui/checked-type-aliases/auxiliary/checked.rs similarity index 100% rename from tests/ui/checked-type-alias/auxiliary/lazy.rs rename to tests/ui/checked-type-aliases/auxiliary/checked.rs diff --git a/tests/ui/checked-type-alias/auxiliary/eager.rs b/tests/ui/checked-type-aliases/auxiliary/unchecked.rs similarity index 58% rename from tests/ui/checked-type-alias/auxiliary/eager.rs rename to tests/ui/checked-type-aliases/auxiliary/unchecked.rs index 8793a1701ec3e..46792602f8867 100644 --- a/tests/ui/checked-type-alias/auxiliary/eager.rs +++ b/tests/ui/checked-type-aliases/auxiliary/unchecked.rs @@ -1,6 +1,5 @@ -// This crate does *not* have lazy type aliases enabled. - -#![allow(type_alias_bounds)] +// This crate does *not* have checked type aliases enabled. +#![expect(type_alias_bounds)] // The `Copy` bound is ignored both locally and externally for backward compatibility. pub type Alias = Option; diff --git a/tests/ui/checked-type-alias/bad-lazy-type-alias.rs b/tests/ui/checked-type-aliases/bad-free-alias-type.rs similarity index 100% rename from tests/ui/checked-type-alias/bad-lazy-type-alias.rs rename to tests/ui/checked-type-aliases/bad-free-alias-type.rs diff --git a/tests/ui/checked-type-alias/bad-lazy-type-alias.stderr b/tests/ui/checked-type-aliases/bad-free-alias-type.stderr similarity index 88% rename from tests/ui/checked-type-alias/bad-lazy-type-alias.stderr rename to tests/ui/checked-type-aliases/bad-free-alias-type.stderr index 7aa34a22f736e..b04b05711fcb9 100644 --- a/tests/ui/checked-type-alias/bad-lazy-type-alias.stderr +++ b/tests/ui/checked-type-aliases/bad-free-alias-type.stderr @@ -1,11 +1,11 @@ error[E0107]: missing generics for type alias `ExplicitTypeOutlives` - --> $DIR/bad-lazy-type-alias.rs:8:24 + --> $DIR/bad-free-alias-type.rs:8:24 | LL | _significant_drop: ExplicitTypeOutlives, | ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument | note: type alias defined here, with 1 generic parameter: `T` - --> $DIR/bad-lazy-type-alias.rs:5:6 + --> $DIR/bad-free-alias-type.rs:5:6 | LL | type ExplicitTypeOutlives = T; | ^^^^^^^^^^^^^^^^^^^^ - diff --git a/tests/ui/checked-type-alias/coerce-behind-lazy.rs b/tests/ui/checked-type-aliases/coerce-behind-lazy.rs similarity index 100% rename from tests/ui/checked-type-alias/coerce-behind-lazy.rs rename to tests/ui/checked-type-aliases/coerce-behind-lazy.rs diff --git a/tests/ui/checked-type-alias/constrained-late-bound-regions.rs b/tests/ui/checked-type-aliases/constrained-late-bound-regions.rs similarity index 77% rename from tests/ui/checked-type-alias/constrained-late-bound-regions.rs rename to tests/ui/checked-type-aliases/constrained-late-bound-regions.rs index 140cfbdc8c1c0..9ca2fc3d17a64 100644 --- a/tests/ui/checked-type-alias/constrained-late-bound-regions.rs +++ b/tests/ui/checked-type-aliases/constrained-late-bound-regions.rs @@ -1,5 +1,5 @@ //@ check-pass -// Weak alias types constrain late-bound regions if their normalized form constrains them. +// Free alias types constrain late-bound regions if their expanded form constrains them. #![feature(checked_type_aliases)] #![allow(incomplete_features)] diff --git a/tests/ui/checked-type-alias/constrained-params-in-impl.rs b/tests/ui/checked-type-aliases/constrained-params-in-impl.rs similarity index 100% rename from tests/ui/checked-type-alias/constrained-params-in-impl.rs rename to tests/ui/checked-type-aliases/constrained-params-in-impl.rs diff --git a/tests/ui/checked-type-alias/deep-expansion.rs b/tests/ui/checked-type-aliases/deep-expansion.rs similarity index 100% rename from tests/ui/checked-type-alias/deep-expansion.rs rename to tests/ui/checked-type-aliases/deep-expansion.rs diff --git a/tests/ui/checked-type-alias/def-site-body-wf.rs b/tests/ui/checked-type-aliases/def-site-body-wf.rs similarity index 100% rename from tests/ui/checked-type-alias/def-site-body-wf.rs rename to tests/ui/checked-type-aliases/def-site-body-wf.rs diff --git a/tests/ui/checked-type-alias/def-site-body-wf.stderr b/tests/ui/checked-type-aliases/def-site-body-wf.stderr similarity index 100% rename from tests/ui/checked-type-alias/def-site-body-wf.stderr rename to tests/ui/checked-type-aliases/def-site-body-wf.stderr diff --git a/tests/ui/checked-type-alias/def-site-param-defaults-wf.rs b/tests/ui/checked-type-aliases/def-site-param-defaults-wf.rs similarity index 100% rename from tests/ui/checked-type-alias/def-site-param-defaults-wf.rs rename to tests/ui/checked-type-aliases/def-site-param-defaults-wf.rs diff --git a/tests/ui/checked-type-alias/def-site-param-defaults-wf.stderr b/tests/ui/checked-type-aliases/def-site-param-defaults-wf.stderr similarity index 100% rename from tests/ui/checked-type-alias/def-site-param-defaults-wf.stderr rename to tests/ui/checked-type-aliases/def-site-param-defaults-wf.stderr diff --git a/tests/ui/checked-type-alias/def-site-predicates-wf.rs b/tests/ui/checked-type-aliases/def-site-predicates-wf.rs similarity index 100% rename from tests/ui/checked-type-alias/def-site-predicates-wf.rs rename to tests/ui/checked-type-aliases/def-site-predicates-wf.rs diff --git a/tests/ui/checked-type-alias/def-site-predicates-wf.stderr b/tests/ui/checked-type-aliases/def-site-predicates-wf.stderr similarity index 100% rename from tests/ui/checked-type-alias/def-site-predicates-wf.stderr rename to tests/ui/checked-type-aliases/def-site-predicates-wf.stderr diff --git a/tests/ui/checked-type-alias/enum-variant.rs b/tests/ui/checked-type-aliases/enum-variant.rs similarity index 100% rename from tests/ui/checked-type-alias/enum-variant.rs rename to tests/ui/checked-type-aliases/enum-variant.rs diff --git a/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_checked.stderr similarity index 52% rename from tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr rename to tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_checked.stderr index 887b9e36008e3..d6bad6ebd850b 100644 --- a/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.locally_eager.stderr +++ b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_checked.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/extern-crate-has-lazy-type-aliases.rs:15:24 + --> $DIR/extern-crate-has-checked-type-aliases.rs:11:27 | -LL | let _: lazy::Alias; - | ^^^^^^ the trait `Copy` is not implemented for `String` +LL | let _: checked::Alias; + | ^^^^^^ the trait `Copy` is not implemented for `String` | -note: required by a bound in `lazy::Alias` - --> $DIR/auxiliary/lazy.rs:3:19 +note: required by a bound in `checked::Alias` + --> $DIR/auxiliary/checked.rs:3:19 | LL | pub type Alias = Option; | ^^^^ required by this bound in `Alias` diff --git a/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_unchecked.stderr similarity index 52% rename from tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr rename to tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_unchecked.stderr index 887b9e36008e3..d6bad6ebd850b 100644 --- a/tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.locally_lazy.stderr +++ b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_unchecked.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/extern-crate-has-lazy-type-aliases.rs:15:24 + --> $DIR/extern-crate-has-checked-type-aliases.rs:11:27 | -LL | let _: lazy::Alias; - | ^^^^^^ the trait `Copy` is not implemented for `String` +LL | let _: checked::Alias; + | ^^^^^^ the trait `Copy` is not implemented for `String` | -note: required by a bound in `lazy::Alias` - --> $DIR/auxiliary/lazy.rs:3:19 +note: required by a bound in `checked::Alias` + --> $DIR/auxiliary/checked.rs:3:19 | LL | pub type Alias = Option; | ^^^^ required by this bound in `Alias` diff --git a/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.rs b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.rs new file mode 100644 index 0000000000000..7d38b3c935549 --- /dev/null +++ b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.rs @@ -0,0 +1,12 @@ +//@ revisions: locally_unchecked locally_checked +//@ aux-crate:checked=checked.rs +//@ edition: 2021 + +// Test that we treat checked type aliases from external crates as checked independently of whether +// the local crate enables feature `checked_type_aliases` or not. + +#![cfg_attr(locally_checked, feature(checked_type_aliases))] + +fn main() { + let _: checked::Alias; //~ ERROR the trait bound `String: Copy` is not satisfied +} diff --git a/tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs b/tests/ui/checked-type-aliases/extern-crate-has-unchecked-type-aliases.rs similarity index 53% rename from tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs rename to tests/ui/checked-type-aliases/extern-crate-has-unchecked-type-aliases.rs index 52e1736975f46..902aa947c44b9 100644 --- a/tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs +++ b/tests/ui/checked-type-aliases/extern-crate-has-unchecked-type-aliases.rs @@ -1,24 +1,21 @@ // This test serves as a regression test for issue #114468 and it also ensures that we consider -// type aliases from external crates that don't have `checked_type_aliases` -// enabled to be eager. +// type aliases from external crates that don't have `checked_type_aliases` enabled to be unchecked. -//@ aux-crate:eager=eager.rs +//@ aux-crate:unchecked=unchecked.rs //@ edition: 2021 //@ check-pass - #![feature(checked_type_aliases)] -#![allow(incomplete_features)] // This used to crash when we were computing the variances of `Struct` since we would convert -// `eager::Alias` to a weak alias due to the presence of +// `unchecked::Alias` to a free alias type due to the presence of // `#![feature(checked_type_aliases)]` in this (!) crate and subsequently attempt to -// obtain the variances of the type alias associated with the weak alias which would -// panic because we don't compute this information for eager type aliases at all. -struct Struct(eager::Alias); +// obtain the variances of the type alias associated with the free alias type which would +// panic because we don't compute this information for unchecked type aliases at all. +struct Struct(unchecked::Alias); fn main() { // We want to ignore (or rather “end up ignoring”) the bound `T: Copy` since `Alias` should be - // treated as an eager type alias not just inside the crate it is defined in but also in + // treated as an unchecked type alias not just inside the crate it is defined in but also in // dependent crates (like this one). - let _: eager::Alias; + let _: unchecked::Alias; } diff --git a/tests/ui/checked-type-alias/implied-outlives-bounds.neg.stderr b/tests/ui/checked-type-aliases/implied-outlives-bounds.neg.stderr similarity index 100% rename from tests/ui/checked-type-alias/implied-outlives-bounds.neg.stderr rename to tests/ui/checked-type-aliases/implied-outlives-bounds.neg.stderr diff --git a/tests/ui/checked-type-alias/implied-outlives-bounds.rs b/tests/ui/checked-type-aliases/implied-outlives-bounds.rs similarity index 79% rename from tests/ui/checked-type-alias/implied-outlives-bounds.rs rename to tests/ui/checked-type-aliases/implied-outlives-bounds.rs index 50cbb136411ee..dae138a37192f 100644 --- a/tests/ui/checked-type-alias/implied-outlives-bounds.rs +++ b/tests/ui/checked-type-aliases/implied-outlives-bounds.rs @@ -1,4 +1,4 @@ -// Check that we imply outlives-bounds on lazy type aliases. +// Check that we imply outlives-bounds on checked type aliases. //@ revisions: pos neg //@[pos] check-pass @@ -9,11 +9,11 @@ type TypeOutlives<'a, T> = &'a T; type RegionOutlives<'a, 'b> = &'a &'b (); -// Ensure that we imply bounds from the explicit bounds of weak aliases. +// Ensure that we imply bounds from the explicit bounds of free alias types. struct Outer0<'a, T>(ExplicitTypeOutlives<'a, T>); type ExplicitTypeOutlives<'a, T: 'a> = (&'a (), T); -// Ensure that we imply bounds from the implied bounds of weak aliases. +// Ensure that we imply bounds from the implied bounds of free alias types. type Outer1<'b, U> = TypeOutlives<'b, U>; #[cfg(neg)] diff --git a/tests/ui/checked-type-alias/inherent-impls-conflicting.rs b/tests/ui/checked-type-aliases/inherent-impls-conflicting.rs similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-conflicting.rs rename to tests/ui/checked-type-aliases/inherent-impls-conflicting.rs diff --git a/tests/ui/checked-type-alias/inherent-impls-conflicting.stderr b/tests/ui/checked-type-aliases/inherent-impls-conflicting.stderr similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-conflicting.stderr rename to tests/ui/checked-type-aliases/inherent-impls-conflicting.stderr diff --git a/tests/ui/checked-type-alias/inherent-impls-not-nominal.rs b/tests/ui/checked-type-aliases/inherent-impls-not-nominal.rs similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-not-nominal.rs rename to tests/ui/checked-type-aliases/inherent-impls-not-nominal.rs diff --git a/tests/ui/checked-type-alias/inherent-impls-not-nominal.stderr b/tests/ui/checked-type-aliases/inherent-impls-not-nominal.stderr similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-not-nominal.stderr rename to tests/ui/checked-type-aliases/inherent-impls-not-nominal.stderr diff --git a/tests/ui/checked-type-alias/inherent-impls-overflow.current.stderr b/tests/ui/checked-type-aliases/inherent-impls-overflow.current.stderr similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-overflow.current.stderr rename to tests/ui/checked-type-aliases/inherent-impls-overflow.current.stderr diff --git a/tests/ui/checked-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/checked-type-aliases/inherent-impls-overflow.next.stderr similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-overflow.next.stderr rename to tests/ui/checked-type-aliases/inherent-impls-overflow.next.stderr diff --git a/tests/ui/checked-type-alias/inherent-impls-overflow.rs b/tests/ui/checked-type-aliases/inherent-impls-overflow.rs similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls-overflow.rs rename to tests/ui/checked-type-aliases/inherent-impls-overflow.rs diff --git a/tests/ui/checked-type-alias/inherent-impls.rs b/tests/ui/checked-type-aliases/inherent-impls.rs similarity index 100% rename from tests/ui/checked-type-alias/inherent-impls.rs rename to tests/ui/checked-type-aliases/inherent-impls.rs diff --git a/tests/ui/checked-type-alias/leading-where-clause.fixed b/tests/ui/checked-type-aliases/leading-where-clause.fixed similarity index 86% rename from tests/ui/checked-type-alias/leading-where-clause.fixed rename to tests/ui/checked-type-aliases/leading-where-clause.fixed index 8b681d3bee09d..df554e53d1a29 100644 --- a/tests/ui/checked-type-alias/leading-where-clause.fixed +++ b/tests/ui/checked-type-aliases/leading-where-clause.fixed @@ -4,7 +4,7 @@ #![allow(incomplete_features)] #![crate_type = "lib"] -// Check that we *reject* leading where-clauses on lazy type aliases. +// Check that we *reject* leading where-clauses on checked type aliases. pub type Leading0 = T where String: From; diff --git a/tests/ui/checked-type-alias/leading-where-clause.rs b/tests/ui/checked-type-aliases/leading-where-clause.rs similarity index 89% rename from tests/ui/checked-type-alias/leading-where-clause.rs rename to tests/ui/checked-type-aliases/leading-where-clause.rs index 98aa8066c2ea1..7f7eb85083c50 100644 --- a/tests/ui/checked-type-alias/leading-where-clause.rs +++ b/tests/ui/checked-type-aliases/leading-where-clause.rs @@ -4,7 +4,7 @@ #![allow(incomplete_features)] #![crate_type = "lib"] -// Check that we *reject* leading where-clauses on lazy type aliases. +// Check that we *reject* leading where-clauses on checked type aliases. pub type Leading0 where //~ ERROR where clauses are not allowed before the type for type aliases diff --git a/tests/ui/checked-type-alias/leading-where-clause.stderr b/tests/ui/checked-type-aliases/leading-where-clause.stderr similarity index 100% rename from tests/ui/checked-type-alias/leading-where-clause.stderr rename to tests/ui/checked-type-aliases/leading-where-clause.stderr diff --git a/tests/ui/checked-type-alias/opaq-ty-collection-infinite-recur.rs b/tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.rs similarity index 100% rename from tests/ui/checked-type-alias/opaq-ty-collection-infinite-recur.rs rename to tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.rs diff --git a/tests/ui/checked-type-alias/opaq-ty-collection-infinite-recur.stderr b/tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.stderr similarity index 100% rename from tests/ui/checked-type-alias/opaq-ty-collection-infinite-recur.stderr rename to tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.stderr diff --git a/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.rs b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.rs similarity index 81% rename from tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.rs rename to tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.rs index b39cc02ea7151..538732ac4f99f 100644 --- a/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.rs +++ b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.rs @@ -1,4 +1,4 @@ -//! Ensure a self-referencing lazy type alias with `gca_min_const_items` +//! Ensure a self-referencing checked type alias with `gca_min_const_items` //! doesn't ICE during normalization. //! //! Regression test for . diff --git a/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.stderr b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr similarity index 85% rename from tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.stderr rename to tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr index a8e68a05253b9..471fa8eb1fd67 100644 --- a/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.stderr +++ b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr @@ -1,5 +1,5 @@ error[E0275]: overflow normalizing the type alias `Arr2` - --> $DIR/recursive-lazy-type-alias-ice-152633.rs:12:1 + --> $DIR/recursive-type-alias-in-const-projection.rs:12:1 | LL | type Arr2 = [usize; ::ASSOC]; | ^^^^^^^^^ diff --git a/tests/ui/checked-type-alias/trailing-where-clause.rs b/tests/ui/checked-type-aliases/trailing-where-clause.rs similarity index 65% rename from tests/ui/checked-type-alias/trailing-where-clause.rs rename to tests/ui/checked-type-aliases/trailing-where-clause.rs index 08e558306a02b..cafd7f4e7e66f 100644 --- a/tests/ui/checked-type-alias/trailing-where-clause.rs +++ b/tests/ui/checked-type-aliases/trailing-where-clause.rs @@ -1,7 +1,6 @@ #![feature(checked_type_aliases)] -#![allow(incomplete_features)] -// Check that we allow & respect trailing where-clauses on lazy type aliases. +// Check that we allow & respect trailing where-clauses on checked type aliases. type Alias = T where diff --git a/tests/ui/checked-type-alias/trailing-where-clause.stderr b/tests/ui/checked-type-aliases/trailing-where-clause.stderr similarity index 88% rename from tests/ui/checked-type-alias/trailing-where-clause.stderr rename to tests/ui/checked-type-aliases/trailing-where-clause.stderr index e87db6a47ae79..88ac1a4427ea3 100644 --- a/tests/ui/checked-type-alias/trailing-where-clause.stderr +++ b/tests/ui/checked-type-aliases/trailing-where-clause.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `String: From<()>` is not satisfied - --> $DIR/trailing-where-clause.rs:12:18 + --> $DIR/trailing-where-clause.rs:11:18 | LL | let _: Alias<()>; | ^^ the trait `From<()>` is not implemented for `String` @@ -12,7 +12,7 @@ LL | let _: Alias<()>; From> From note: required by a bound in `Alias` - --> $DIR/trailing-where-clause.rs:8:13 + --> $DIR/trailing-where-clause.rs:7:13 | LL | type Alias = T LL | where diff --git a/tests/ui/checked-type-alias/type-alias-bounds-are-enforced.rs b/tests/ui/checked-type-aliases/type-alias-bounds-are-enforced.rs similarity index 100% rename from tests/ui/checked-type-alias/type-alias-bounds-are-enforced.rs rename to tests/ui/checked-type-aliases/type-alias-bounds-are-enforced.rs diff --git a/tests/ui/checked-type-alias/unconstrained-late-bound-regions.rs b/tests/ui/checked-type-aliases/unconstrained-late-bound-regions.rs similarity index 88% rename from tests/ui/checked-type-alias/unconstrained-late-bound-regions.rs rename to tests/ui/checked-type-aliases/unconstrained-late-bound-regions.rs index ac3b56a542825..c06a8d2c80ee2 100644 --- a/tests/ui/checked-type-alias/unconstrained-late-bound-regions.rs +++ b/tests/ui/checked-type-aliases/unconstrained-late-bound-regions.rs @@ -1,4 +1,4 @@ -// Weak alias types only constrain late-bound regions if their normalized form constrains them. +// Free alias types only constrain late-bound regions if their expanded form constrains them. #![feature(checked_type_aliases)] #![allow(incomplete_features)] diff --git a/tests/ui/checked-type-alias/unconstrained-late-bound-regions.stderr b/tests/ui/checked-type-aliases/unconstrained-late-bound-regions.stderr similarity index 100% rename from tests/ui/checked-type-alias/unconstrained-late-bound-regions.stderr rename to tests/ui/checked-type-aliases/unconstrained-late-bound-regions.stderr diff --git a/tests/ui/checked-type-alias/unconstrained-params-in-impl-due-to-overflow.rs b/tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.rs similarity index 100% rename from tests/ui/checked-type-alias/unconstrained-params-in-impl-due-to-overflow.rs rename to tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.rs diff --git a/tests/ui/checked-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.stderr similarity index 100% rename from tests/ui/checked-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr rename to tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.stderr diff --git a/tests/ui/checked-type-alias/unconstrained-params-in-impl.rs b/tests/ui/checked-type-aliases/unconstrained-params-in-impl.rs similarity index 100% rename from tests/ui/checked-type-alias/unconstrained-params-in-impl.rs rename to tests/ui/checked-type-aliases/unconstrained-params-in-impl.rs diff --git a/tests/ui/checked-type-alias/unconstrained-params-in-impl.stderr b/tests/ui/checked-type-aliases/unconstrained-params-in-impl.stderr similarity index 100% rename from tests/ui/checked-type-alias/unconstrained-params-in-impl.stderr rename to tests/ui/checked-type-aliases/unconstrained-params-in-impl.stderr diff --git a/tests/ui/checked-type-alias/unused-generic-arguments-not-wfchecked.next-fixed.stderr b/tests/ui/checked-type-aliases/unused-generic-arguments-not-wfchecked.next-fixed.stderr similarity index 100% rename from tests/ui/checked-type-alias/unused-generic-arguments-not-wfchecked.next-fixed.stderr rename to tests/ui/checked-type-aliases/unused-generic-arguments-not-wfchecked.next-fixed.stderr diff --git a/tests/ui/checked-type-alias/unused-generic-arguments-not-wfchecked.rs b/tests/ui/checked-type-aliases/unused-generic-arguments-not-wfchecked.rs similarity index 82% rename from tests/ui/checked-type-alias/unused-generic-arguments-not-wfchecked.rs rename to tests/ui/checked-type-aliases/unused-generic-arguments-not-wfchecked.rs index 393f8dfab2077..4dc9f49611b2a 100644 --- a/tests/ui/checked-type-alias/unused-generic-arguments-not-wfchecked.rs +++ b/tests/ui/checked-type-aliases/unused-generic-arguments-not-wfchecked.rs @@ -1,12 +1,12 @@ -// We currently fail to wfcheck generic arguments that correspond to unused LTA generic parameters +// We currently fail to wfcheck generic arguments that correspond to unused CTA generic parameters // since we generally normalize types before wfchecking them, so we accidentally "expand them away" // before we can check them. // // (We do still check predicates that reference unused parameters, of course.) // -// FIXME(checked_type_aliases): I consider #100041 to be a stabilization-blocking concern for -// the checked version of LTA! The *entire premise* of checked_LTA -// is wfchecking; we can't have such obvious holes in it! +// FIXME(checked_type_aliases): I consider #100041 to be a stabilization-blocking concern for CTA! +// The *entire premise* of CTA is wfchecking; we can't have such obvious holes in it! +// For a hypothetical `retained_type_aliases` this would not matter, of course. // //@ revisions: current-bugged next-bugged next-fixed // diff --git a/tests/ui/checked-type-alias/unused-generic-parameters.fail.stderr b/tests/ui/checked-type-aliases/unused-generic-parameters.fail.stderr similarity index 82% rename from tests/ui/checked-type-alias/unused-generic-parameters.fail.stderr rename to tests/ui/checked-type-aliases/unused-generic-parameters.fail.stderr index 05e3881cb090c..5f71563beb2a2 100644 --- a/tests/ui/checked-type-alias/unused-generic-parameters.fail.stderr +++ b/tests/ui/checked-type-aliases/unused-generic-parameters.fail.stderr @@ -1,44 +1,44 @@ error[E0478]: lifetime bound not satisfied - --> $DIR/unused-generic-parameters.rs:24:22 + --> $DIR/unused-generic-parameters.rs:22:22 | LL | #[cfg(fail)] fn a(_: A<'_>) {} | ^^^^^ | note: lifetime parameter instantiated with the anonymous lifetime defined here - --> $DIR/unused-generic-parameters.rs:24:22 + --> $DIR/unused-generic-parameters.rs:22:22 | LL | #[cfg(fail)] fn a(_: A<'_>) {} | ^^^^^ = note: but lifetime parameter must outlive the static lifetime error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unused-generic-parameters.rs:28:22 + --> $DIR/unused-generic-parameters.rs:26:22 | LL | #[cfg(fail)] fn b(_: B) {} | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` note: required by a bound on the type alias `B` - --> $DIR/unused-generic-parameters.rs:26:8 + --> $DIR/unused-generic-parameters.rs:24:8 | LL | type B = (); | ^ required by this bound error[E0080]: evaluation panicked: explicit panic - --> $DIR/unused-generic-parameters.rs:34:26 + --> $DIR/unused-generic-parameters.rs:32:26 | LL | #[cfg(fail)] fn c(_: C<{ panic!() }>) {} | ^^^^^^^^ evaluation of `c::{constant#0}` failed here error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unused-generic-parameters.rs:28:22 + --> $DIR/unused-generic-parameters.rs:26:22 | LL | #[cfg(fail)] fn b(_: B) {} | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` note: required by a bound on the type alias `B` - --> $DIR/unused-generic-parameters.rs:26:8 + --> $DIR/unused-generic-parameters.rs:24:8 | LL | type B = (); | ^ required by this bound diff --git a/tests/ui/checked-type-alias/unused-generic-parameters.rs b/tests/ui/checked-type-aliases/unused-generic-parameters.rs similarity index 63% rename from tests/ui/checked-type-alias/unused-generic-parameters.rs rename to tests/ui/checked-type-aliases/unused-generic-parameters.rs index 18a65043ef61a..210bb5606f256 100644 --- a/tests/ui/checked-type-alias/unused-generic-parameters.rs +++ b/tests/ui/checked-type-aliases/unused-generic-parameters.rs @@ -1,16 +1,14 @@ -// Check that we accept unused generic parameters on lazy type aliases (for context, we reject -// unused type parameters on eager type aliases). +// Check that we accept unused generic parameters on checked type aliases (for context, we reject +// unused type parameters on unchecked type aliases). // // As long as we check well-formedness before normalization there shouldn't be anything wrong with // such parameters since we know that the corresponding arguments will get wfchecked regardless. // // FIXME(checked_type_aliases, #100041): At the time of writing however, that's not the case. -// I consider this to be stabilization-blocking concern for the -// strong checked version of LTA! -// See also `unused-generic-arguments-not-wfchecked.rs`. +// I consider this to be stabilization-blocking concern for CTA! +// See also `unused-generic-arguments-not-wfchecked.rs`. // -// (We *do* ofc still detect unsatisfied predicates even if they -// reference unused parameters) +// (We *do* ofc still detect unsatisfied predicates even if they reference unused parameters) // // issue: // diff --git a/tests/ui/checked-type-alias/use-site-wf.rs b/tests/ui/checked-type-aliases/use-site-wf.rs similarity index 62% rename from tests/ui/checked-type-alias/use-site-wf.rs rename to tests/ui/checked-type-aliases/use-site-wf.rs index cd10a6c8330d2..fd03a8da9b41d 100644 --- a/tests/ui/checked-type-alias/use-site-wf.rs +++ b/tests/ui/checked-type-aliases/use-site-wf.rs @@ -1,5 +1,5 @@ -// Test that we check usage sites of lazy type aliases, aka free alias types, for well-formedness. -// We check trailing where-clauses separately in `trailing-where-clause.rs`. +// Test that we check usage sites of checked type aliases, aka free alias types, +// for well-formedness. We check trailing where-clauses separately in `trailing-where-clause.rs`. #![feature(checked_type_aliases)] diff --git a/tests/ui/checked-type-alias/use-site-wf.stderr b/tests/ui/checked-type-aliases/use-site-wf.stderr similarity index 100% rename from tests/ui/checked-type-alias/use-site-wf.stderr rename to tests/ui/checked-type-aliases/use-site-wf.stderr diff --git a/tests/ui/checked-type-alias/variance-0.rs b/tests/ui/checked-type-aliases/variance-0.rs similarity index 100% rename from tests/ui/checked-type-alias/variance-0.rs rename to tests/ui/checked-type-aliases/variance-0.rs diff --git a/tests/ui/checked-type-alias/variance-1.rs b/tests/ui/checked-type-aliases/variance-1.rs similarity index 72% rename from tests/ui/checked-type-alias/variance-1.rs rename to tests/ui/checked-type-aliases/variance-1.rs index 3fb857b8f91bf..0c46fd2b15644 100644 --- a/tests/ui/checked-type-alias/variance-1.rs +++ b/tests/ui/checked-type-aliases/variance-1.rs @@ -1,13 +1,12 @@ // Demonstrate that free alias types don't constrain their lifetime & type arguments if the corresp. -// lifetime & type parameters are unused in the lazy type alias (before normalization) since we +// lifetime & type parameters are unused in the checked type alias (before normalization) since we // eagerly expand them during variance computation unlike other alias types which constrain args to // be invariant. // FIXME(checked_type_aliases): Revisit this before stabilization (altho it's not blocking): -// Do we want to compute variances for lazy type aliases & free alias types -// again and "force bivariant parameters to be invariant" if they're not -// constrained by a projection? -// This would make `struct WrapDiscard` below compile. +// Do we want to compute variances for checked type aliases & free alias types again and +// "force bivariant parameters to be invariant" if they're not constrained by a projection? +// This would make `struct WrapDiscard` below compile. #![feature(checked_type_aliases)] @@ -31,7 +30,7 @@ type Co<'a> = std::vec::IntoIter<(&'a (), &'a ())>; // NOTE: If we end up switching back to computing variances for free alias types with the special // rule explained in the FIXME above, then this function should still compile since -// LTA `DiscardConstrained` should be bivariant over `'a` and `T`, not invariant due to them +// CTA `DiscardConstrained` should be bivariant over `'a` and `T`, not invariant due to them // being constrained by a projection. fn bi<'r>( x: WrapDiscardConstrained<'static, &'static (), Co<'static>>, diff --git a/tests/ui/checked-type-alias/variance-1.stderr b/tests/ui/checked-type-aliases/variance-1.stderr similarity index 93% rename from tests/ui/checked-type-alias/variance-1.stderr rename to tests/ui/checked-type-aliases/variance-1.stderr index 40b59b43910e8..a66c2d4303fdf 100644 --- a/tests/ui/checked-type-alias/variance-1.stderr +++ b/tests/ui/checked-type-aliases/variance-1.stderr @@ -1,5 +1,5 @@ error[E0392]: lifetime parameter `'a` is never used - --> $DIR/variance-1.rs:17:20 + --> $DIR/variance-1.rs:16:20 | LL | struct WrapDiscard<'a, T>(Discard<'a, T>); | ^^ unused lifetime parameter @@ -7,7 +7,7 @@ LL | struct WrapDiscard<'a, T>(Discard<'a, T>); = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` error[E0392]: type parameter `T` is never used - --> $DIR/variance-1.rs:17:24 + --> $DIR/variance-1.rs:16:24 | LL | struct WrapDiscard<'a, T>(Discard<'a, T>); | ^ - `T` is named here, but is not used in the type that wraps it diff --git a/tests/ui/checked-type-alias/variance-overflow.rs b/tests/ui/checked-type-aliases/variance-overflow.rs similarity index 100% rename from tests/ui/checked-type-alias/variance-overflow.rs rename to tests/ui/checked-type-aliases/variance-overflow.rs diff --git a/tests/ui/checked-type-alias/variance-overflow.stderr b/tests/ui/checked-type-aliases/variance-overflow.stderr similarity index 100% rename from tests/ui/checked-type-alias/variance-overflow.stderr rename to tests/ui/checked-type-aliases/variance-overflow.stderr diff --git a/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.rs b/tests/ui/checked-type-aliases/variance-unused-param-through-alias-chain.rs similarity index 100% rename from tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.rs rename to tests/ui/checked-type-aliases/variance-unused-param-through-alias-chain.rs diff --git a/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.stderr b/tests/ui/checked-type-aliases/variance-unused-param-through-alias-chain.stderr similarity index 100% rename from tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.stderr rename to tests/ui/checked-type-aliases/variance-unused-param-through-alias-chain.stderr diff --git a/tests/ui/coherence/orphan-check-weak-aliases-covering.rs b/tests/ui/coherence/orphan-check-free-aliases-covering.rs similarity index 80% rename from tests/ui/coherence/orphan-check-weak-aliases-covering.rs rename to tests/ui/coherence/orphan-check-free-aliases-covering.rs index 7e4dbf1465996..f33bc7098c4d7 100644 --- a/tests/ui/coherence/orphan-check-weak-aliases-covering.rs +++ b/tests/ui/coherence/orphan-check-free-aliases-covering.rs @@ -1,4 +1,4 @@ -// Weak aliases cover type parameters if they normalize to a (local) type that covers them. +// Free alias types cover type parameters if they normalize to a (local) type that covers them. //@ check-pass //@ revisions: classic next diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs b/tests/ui/coherence/orphan-check-free-aliases-not-covering.rs similarity index 84% rename from tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs rename to tests/ui/coherence/orphan-check-free-aliases-not-covering.rs index d43c42dfc9722..5944b00f167d0 100644 --- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs +++ b/tests/ui/coherence/orphan-check-free-aliases-not-covering.rs @@ -1,4 +1,4 @@ -// Weak aliases might not cover type parameters. +// Free alias types might not cover type parameters. //@ aux-crate:foreign=parametrized-trait.rs //@ edition:2021 diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr b/tests/ui/coherence/orphan-check-free-aliases-not-covering.stderr similarity index 92% rename from tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr rename to tests/ui/coherence/orphan-check-free-aliases-not-covering.stderr index 37f6684692564..ef17aa4090326 100644 --- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr +++ b/tests/ui/coherence/orphan-check-free-aliases-not-covering.stderr @@ -1,5 +1,5 @@ error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-weak-aliases-not-covering.rs:13:6 + --> $DIR/orphan-check-free-aliases-not-covering.rs:13:6 | LL | impl foreign::Trait1 for Identity {} | ^ uncovered type parameter diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs index efbbb07317e1c..f1d5b08809b29 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs @@ -20,6 +20,6 @@ fn main() { struct Store(dyn Trait); //~^ ERROR the value of the associated constant `K` in `Trait` must be specified -// item ctxt & no wfcking (eager ty alias) +// item ctxt & no wfcking (unchecked ty alias) type DynTrait = dyn Trait; //~^ ERROR the value of the associated constant `K` in `Trait` must be specified diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.lazy.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr similarity index 76% rename from tests/ui/const-generics/check_const_arg_type_in_free_alias.lazy.stderr rename to tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr index b9adb4e51e1af..371657baa5e6f 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.lazy.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr @@ -1,5 +1,5 @@ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:15:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:14:1 | LL | type ArrLen = [(); B]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` @@ -7,7 +7,7 @@ LL | type ArrLen = [(); B]; = note: the length of array `[(); B]` must be type `usize` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:17:24 + --> $DIR/check_const_arg_type_in_free_alias.rs:16:24 | LL | type AnonArrLen = [(); true]; | ^^^^ expected `usize`, found `bool` @@ -15,37 +15,37 @@ LL | type AnonArrLen = [(); true]; = note: array length can only be `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:19:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:18:1 | LL | type ConstArg = Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:21:25 + --> $DIR/check_const_arg_type_in_free_alias.rs:20:25 | LL | type AnonConstArg = Foo; | ^^^^ expected `usize`, found `bool` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:32:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:31:1 | LL | type Alias = <() as IdentityWithUnused>::This; | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required for `()` to implement `IdentityWithUnused` - --> $DIR/check_const_arg_type_in_free_alias.rs:28:25 + --> $DIR/check_const_arg_type_in_free_alias.rs:27:25 | LL | impl IdentityWithUnused for T { | -------------- ^^^^^^^^^^^^^^^^^^^^^ ^ @@ -53,61 +53,61 @@ LL | impl IdentityWithUnused for T { | unsatisfied trait bound introduced here error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:34:44 + --> $DIR/check_const_arg_type_in_free_alias.rs:33:44 | LL | type AnonAlias = <() as IdentityWithUnused>::This; | ^^^^ expected `usize`, found `bool` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:38:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:1 | LL | type UseFree = Free; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required by a bound on the type alias `Free` - --> $DIR/check_const_arg_type_in_free_alias.rs:37:11 + --> $DIR/check_const_arg_type_in_free_alias.rs:36:11 | LL | type Free = [(); N]; | ^^^^^^^^^^^^^^ required by this bound error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:40:25 + --> $DIR/check_const_arg_type_in_free_alias.rs:39:25 | LL | type AnonUseFree = Free; | ^^^^ expected `usize`, found `bool` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:37:11 + --> $DIR/check_const_arg_type_in_free_alias.rs:36:11 | LL | type Free = [(); N]; | ^^^^^^^^^^^^^^ error: the constant `N` is not of type `bool` - --> $DIR/check_const_arg_type_in_free_alias.rs:51:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:50:1 | LL | type UseFreeIndirectlyCorrect = UseFree; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `usize` | note: required by a bound on the type alias `UseFree` - --> $DIR/check_const_arg_type_in_free_alias.rs:38:14 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:14 | LL | type UseFree = Free; | ^^^^^^^^^^^^^ required by this bound error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:53:45 + --> $DIR/check_const_arg_type_in_free_alias.rs:52:45 | LL | type AnonUseFreeIndirectlyCorrect = UseFree<1_usize>; | ^^^^^^^ expected `bool`, found `usize` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:38:14 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:14 | LL | type UseFree = Free; | ^^^^^^^^^^^^^ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:58:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:57:1 | LL | type IndirectArr = Wrap>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` @@ -115,7 +115,7 @@ LL | type IndirectArr = Wrap>; = note: the length of array `[(); B]` must be type `usize` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:60:39 + --> $DIR/check_const_arg_type_in_free_alias.rs:59:39 | LL | type AnonIndirectArr = Wrap>; | ^^^^ expected `usize`, found `bool` @@ -123,25 +123,25 @@ LL | type AnonIndirectArr = Wrap>; = note: array length can only be `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:62:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:61:1 | LL | type IndirectConstArg = Wrap>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:64:43 + --> $DIR/check_const_arg_type_in_free_alias.rs:63:43 | LL | type AnonIndirectConstArg = Wrap>>; | ^^^^ expected `usize`, found `bool` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs b/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs index 10d6ceba85f43..009ccd63d886e 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs @@ -1,6 +1,5 @@ -//@ revisions: eager lazy -#![cfg_attr(lazy, feature(checked_type_aliases))] -#![cfg_attr(lazy, expect(incomplete_features))] +//@ revisions: unchecked checked +#![cfg_attr(checked, feature(checked_type_aliases))] // We currently do not check free type aliases for well formedness. // However, previously we desugared all const arguments to anon @@ -49,7 +48,7 @@ type AnonUseFree = Free; // parameters so this shouldn't be able to cause code to // pass that should error. type UseFreeIndirectlyCorrect = UseFree; -//[lazy]~^ ERROR: the constant `N` is not of type +//[checked]~^ ERROR: the constant `N` is not of type type AnonUseFreeIndirectlyCorrect = UseFree<1_usize>; //~^ ERROR: mismatched types diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.eager.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr similarity index 77% rename from tests/ui/const-generics/check_const_arg_type_in_free_alias.eager.stderr rename to tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr index f62023bd146bb..2e12050cbd777 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.eager.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr @@ -1,5 +1,5 @@ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:15:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:14:1 | LL | type ArrLen = [(); B]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` @@ -7,31 +7,31 @@ LL | type ArrLen = [(); B]; = note: the length of array `[(); B]` must be type `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:19:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:18:1 | LL | type ConstArg = Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:32:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:31:1 | LL | type Alias = <() as IdentityWithUnused>::This; | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required by a const generic parameter in `IdentityWithUnused` - --> $DIR/check_const_arg_type_in_free_alias.rs:24:26 + --> $DIR/check_const_arg_type_in_free_alias.rs:23:26 | LL | trait IdentityWithUnused { | ^^^^^^^^^^^^^^ required by this const generic parameter in `IdentityWithUnused` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:38:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:1 | LL | type UseFree = Free; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` @@ -39,7 +39,7 @@ LL | type UseFree = Free; = note: the length of array `[(); B]` must be type `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:58:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:57:1 | LL | type IndirectArr = Wrap>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` @@ -47,19 +47,19 @@ LL | type IndirectArr = Wrap>; = note: the length of array `[(); B]` must be type `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:62:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:61:1 | LL | type IndirectConstArg = Wrap>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:17:24 + --> $DIR/check_const_arg_type_in_free_alias.rs:16:24 | LL | type AnonArrLen = [(); true]; | ^^^^ expected `usize`, found `bool` @@ -67,49 +67,49 @@ LL | type AnonArrLen = [(); true]; = note: array length can only be `usize` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:21:25 + --> $DIR/check_const_arg_type_in_free_alias.rs:20:25 | LL | type AnonConstArg = Foo; | ^^^^ expected `usize`, found `bool` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:34:44 + --> $DIR/check_const_arg_type_in_free_alias.rs:33:44 | LL | type AnonAlias = <() as IdentityWithUnused>::This; | ^^^^ expected `usize`, found `bool` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:40:25 + --> $DIR/check_const_arg_type_in_free_alias.rs:39:25 | LL | type AnonUseFree = Free; | ^^^^ expected `usize`, found `bool` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:37:11 + --> $DIR/check_const_arg_type_in_free_alias.rs:36:11 | LL | type Free = [(); N]; | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:53:45 + --> $DIR/check_const_arg_type_in_free_alias.rs:52:45 | LL | type AnonUseFreeIndirectlyCorrect = UseFree<1_usize>; | ^^^^^^^ expected `bool`, found `usize` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:38:14 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:14 | LL | type UseFree = Free; | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:60:39 + --> $DIR/check_const_arg_type_in_free_alias.rs:59:39 | LL | type AnonIndirectArr = Wrap>; | ^^^^ expected `usize`, found `bool` @@ -117,13 +117,13 @@ LL | type AnonIndirectArr = Wrap>; = note: array length can only be `usize` error[E0308]: mismatched types - --> $DIR/check_const_arg_type_in_free_alias.rs:64:43 + --> $DIR/check_const_arg_type_in_free_alias.rs:63:43 | LL | type AnonIndirectConstArg = Wrap>>; | ^^^^ expected `usize`, found `bool` | note: expected because of the type of the const parameter - --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 | LL | struct Foo; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs index 775b28f8c73ad..a83d8aa423762 100644 --- a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs +++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs @@ -6,7 +6,7 @@ #![allow(incomplete_features)] // FIXME(generic_const_exprs): Revisit this before stabilization. -// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases +// Check that we don't emit the lint `type_alias_bounds` for (unchecked) type aliases // whose RHS contains a const projection (aka uneval'ed const). // Since anon consts inherit the parent generics and predicates and we effectively // check them before and after instantiaton for well-formedness, the type alias diff --git a/tests/ui/impl-restriction/restriction_resolution_errors.stderr b/tests/ui/impl-restriction/restriction_resolution_errors.stderr index db559468ea591..e417e01f3844d 100644 --- a/tests/ui/impl-restriction/restriction_resolution_errors.stderr +++ b/tests/ui/impl-restriction/restriction_resolution_errors.stderr @@ -21,10 +21,6 @@ help: there is a crate or module with a similar name LL - pub impl(in a::b) trait T1 {} LL + pub impl(in c::b) trait T1 {} | -help: consider importing this module - | -LL + use a; - | error[E0433]: cannot find module `c` in the crate root --> $DIR/restriction_resolution_errors.rs:22:28 diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs index 536deb2efc172..8c283e63cdaf2 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs @@ -11,7 +11,7 @@ struct W(T); // For `W>` to be WF, `A: Sized` must hold. However, when assembling // alias bounds for `A`, we try to normalize it, but it doesn't hold because // `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still -// encounter weak types in `assemble_alias_bound_candidates_recur`. +// encounter free alias types in `assemble_alias_bound_candidates_recur`. fn hello(_: W>) {} //~^ ERROR: the trait bound `usize: Foo` is not satisfied //~| ERROR: the trait bound `usize: Foo` is not satisfied diff --git a/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.fixed b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.fixed new file mode 100644 index 0000000000000..2779c8ba990e8 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.fixed @@ -0,0 +1,48 @@ +//@ edition: 2021 +//@ run-rustfix + +// regression test for https://github.com/rust-lang/rust/issues/132199. +// in edition 2024 impl Trait captures every in-scope lifetime by default, +// so none of these shapes error there. edition 2021 is used throughout. + +#![allow(dead_code)] + +struct T; +struct Foo<'a>(&'a u8); + +impl T { + // two_anon: two elided lifetimes, use<'_> captures only the first so a + // second E0700 follows with no suggestion. + fn two_anon<'a, 'b>(&'a self, t: &'b T) -> impl Sized + use<'a, 'b> { + (self, t) + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + } + + // one_anon: one elided lifetime, use<'_> is correct and must stay byte-identical. + fn one_anon(&self) -> impl Sized + use<'_> { + self + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + } + + // named: an already-named lifetime, unaffected by this change. + fn named<'a>(&'a self, t: &'a T) -> impl Sized + use<'a> { + (self, t) + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + } +} + +// second_anon: two elided lifetimes where use<'_> does not resolve and +// produces E0106 on top of the original error. +fn second_anon<'a>(_a: &u8, b: &'a T) -> impl Sized + use<'a> { + b + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +} + +// path_anon: elision inside a path argument, so the name goes in as Foo<'a> +// and exercises the other arm of hir::LifetimeName matching. +fn path_anon<'a, 'b>(x: Foo<'a>, y: Foo<'b>) -> impl Sized + use<'a, 'b> { + (x, y) + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.rs b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.rs new file mode 100644 index 0000000000000..b05245223680f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.rs @@ -0,0 +1,48 @@ +//@ edition: 2021 +//@ run-rustfix + +// regression test for https://github.com/rust-lang/rust/issues/132199. +// in edition 2024 impl Trait captures every in-scope lifetime by default, +// so none of these shapes error there. edition 2021 is used throughout. + +#![allow(dead_code)] + +struct T; +struct Foo<'a>(&'a u8); + +impl T { + // two_anon: two elided lifetimes, use<'_> captures only the first so a + // second E0700 follows with no suggestion. + fn two_anon(&self, t: &T) -> impl Sized { + (self, t) + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + } + + // one_anon: one elided lifetime, use<'_> is correct and must stay byte-identical. + fn one_anon(&self) -> impl Sized { + self + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + } + + // named: an already-named lifetime, unaffected by this change. + fn named<'a>(&'a self, t: &'a T) -> impl Sized { + (self, t) + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + } +} + +// second_anon: two elided lifetimes where use<'_> does not resolve and +// produces E0106 on top of the original error. +fn second_anon(_a: &u8, b: &T) -> impl Sized { + b + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +} + +// path_anon: elision inside a path argument, so the name goes in as Foo<'a> +// and exercises the other arm of hir::LifetimeName matching. +fn path_anon(x: Foo, y: Foo) -> impl Sized { + (x, y) + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.stderr b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.stderr new file mode 100644 index 0000000000000..5d4ed53e19427 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.stderr @@ -0,0 +1,78 @@ +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:17:9 + | +LL | fn two_anon(&self, t: &T) -> impl Sized { + | ----- ---------- opaque type defined here + | | + | hidden type `(&T, &T)` captures the anonymous lifetime defined here +LL | (self, t) + | ^^^^^^^^^ + | +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them + | +LL | fn two_anon<'a, 'b>(&'a self, t: &'b T) -> impl Sized + use<'a, 'b> { + | ++++++++ ++ ++ +++++++++++++ + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:23:9 + | +LL | fn one_anon(&self) -> impl Sized { + | ----- ---------- opaque type defined here + | | + | hidden type `&T` captures the anonymous lifetime defined here +LL | self + | ^^^^ + | +help: add a `use<...>` bound to explicitly capture `'_` + | +LL | fn one_anon(&self) -> impl Sized + use<'_> { + | +++++++++ + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:29:9 + | +LL | fn named<'a>(&'a self, t: &'a T) -> impl Sized { + | -- ---------- opaque type defined here + | | + | hidden type `(&'a T, &'a T)` captures the lifetime `'a` as defined here +LL | (self, t) + | ^^^^^^^^^ + | +help: add a `use<...>` bound to explicitly capture `'a` + | +LL | fn named<'a>(&'a self, t: &'a T) -> impl Sized + use<'a> { + | +++++++++ + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:37:5 + | +LL | fn second_anon(_a: &u8, b: &T) -> impl Sized { + | -- ---------- opaque type defined here + | | + | hidden type `&T` captures the anonymous lifetime defined here +LL | b + | ^ + | +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them + | +LL | fn second_anon<'a>(_a: &u8, b: &'a T) -> impl Sized + use<'a> { + | ++++ ++ +++++++++ + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:44:5 + | +LL | fn path_anon(x: Foo, y: Foo) -> impl Sized { + | --- ---------- opaque type defined here + | | + | hidden type `(Foo<'_>, Foo<'_>)` captures the anonymous lifetime defined here +LL | (x, y) + | ^^^^^^ + | +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them + | +LL | fn path_anon<'a, 'b>(x: Foo<'a>, y: Foo<'b>) -> impl Sized + use<'a, 'b> { + | ++++++++ ++++ ++++ +++++++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/lifetimes/issue-105227.fixed b/tests/ui/lifetimes/issue-105227.fixed new file mode 100644 index 0000000000000..c732567b0ff41 --- /dev/null +++ b/tests/ui/lifetimes/issue-105227.fixed @@ -0,0 +1,26 @@ +// Regression test for issue #105227. + +//@ run-rustfix + +#![allow(unused)] + +fn chars0<'a, 'b>(v :(&'a str, &'b str)) -> impl Iterator + use<'a, 'b> { + //~^ HELP add `use<...>` bound and name the elided lifetimes to explicitly capture them + v.0.chars().chain(v.1.chars()) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds +} + +fn chars1<'a, 'b>(v0 : &'a str, v1 : &'b str) -> impl Iterator + use<'a, 'b> { + //~^ HELP add `use<...>` bound and name the elided lifetimes to explicitly capture them + v0.chars().chain(v1.chars()) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound +} + +fn chars2<'a, 'c, 'b>(v0 : &'a str, v1 : &'c str, v2 : &'b str) -> (impl Iterator + use<'a, 'c>, &'b str) { + //~^ HELP add `use<...>` bound and name the elided lifetimes to explicitly capture them + (v0.chars().chain(v1.chars()), v2) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound +} + +fn main() { +} diff --git a/tests/ui/lifetimes/issue-105227.rs b/tests/ui/lifetimes/issue-105227.rs index 8a0a49e8f0c48..5367c72577d8f 100644 --- a/tests/ui/lifetimes/issue-105227.rs +++ b/tests/ui/lifetimes/issue-105227.rs @@ -1,23 +1,23 @@ // Regression test for issue #105227. -// FIXME(precise_capturing): Add rustfix here after dealing w/ elided lifetimes +//@ run-rustfix #![allow(unused)] fn chars0(v :(& str, &str)) -> impl Iterator { - //~^ HELP add a `use<...>` bound + //~^ HELP add `use<...>` bound and name the elided lifetimes to explicitly capture them v.0.chars().chain(v.1.chars()) //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds } fn chars1(v0 : & str, v1 : &str) -> impl Iterator { - //~^ HELP add a `use<...>` bound + //~^ HELP add `use<...>` bound and name the elided lifetimes to explicitly capture them v0.chars().chain(v1.chars()) //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound } fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) -> (impl Iterator, &'b str) { - //~^ HELP add a `use<...>` bound + //~^ HELP add `use<...>` bound and name the elided lifetimes to explicitly capture them (v0.chars().chain(v1.chars()), v2) //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound } diff --git a/tests/ui/lifetimes/issue-105227.stderr b/tests/ui/lifetimes/issue-105227.stderr index 35c05f2885479..190e91f5fb051 100644 --- a/tests/ui/lifetimes/issue-105227.stderr +++ b/tests/ui/lifetimes/issue-105227.stderr @@ -9,10 +9,10 @@ LL | LL | v.0.chars().chain(v.1.chars()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: add a `use<...>` bound to explicitly capture `'_` +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them | -LL | fn chars0(v :(& str, &str)) -> impl Iterator + use<'_> { - | +++++++++ +LL | fn chars0<'a, 'b>(v :(&'a str, &'b str)) -> impl Iterator + use<'a, 'b> { + | ++++++++ ++ ++ +++++++++++++ error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds --> $DIR/issue-105227.rs:15:5 @@ -25,10 +25,10 @@ LL | LL | v0.chars().chain(v1.chars()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: add a `use<...>` bound to explicitly capture `'_` +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them | -LL | fn chars1(v0 : & str, v1 : &str) -> impl Iterator + use<'_> { - | +++++++++ +LL | fn chars1<'a, 'b>(v0 : &'a str, v1 : &'b str) -> impl Iterator + use<'a, 'b> { + | ++++++++ ++ ++ +++++++++++++ error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds --> $DIR/issue-105227.rs:21:5 @@ -41,10 +41,11 @@ LL | LL | (v0.chars().chain(v1.chars()), v2) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: add a `use<...>` bound to explicitly capture `'_` +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them + | +LL - fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) -> (impl Iterator, &'b str) { +LL + fn chars2<'a, 'c, 'b>(v0 : &'a str, v1 : &'c str, v2 : &'b str) -> (impl Iterator + use<'a, 'c>, &'b str) { | -LL | fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) -> (impl Iterator + use<'_>, &'b str) { - | +++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/mut-restriction/restriction-resolution-errors.stderr b/tests/ui/mut-restriction/restriction-resolution-errors.stderr index 5e77296854d97..23c640371728b 100644 --- a/tests/ui/mut-restriction/restriction-resolution-errors.stderr +++ b/tests/ui/mut-restriction/restriction-resolution-errors.stderr @@ -21,10 +21,6 @@ help: there is a crate or module with a similar name LL - pub mut(in a::b) i1: i32, LL + pub mut(in c::b) i1: i32, | -help: consider importing this module - | -LL + use a; - | error[E0433]: cannot find module `c` in the crate root --> $DIR/restriction-resolution-errors.rs:13:31 diff --git a/tests/ui/offset-of/offset-of-self.stderr b/tests/ui/offset-of/offset-of-self.stderr index cd78fe492b807..3cf5c3cf3f5d4 100644 --- a/tests/ui/offset-of/offset-of-self.stderr +++ b/tests/ui/offset-of/offset-of-self.stderr @@ -10,11 +10,7 @@ error[E0425]: cannot find type `S` in module `self` LL | offset_of!(self::S, v); | ^ not found in `self` | -help: consider importing this struct - | -LL + use S; - | -help: if you import `S`, refer to it directly +help: consider using this struct | LL - offset_of!(self::S, v); LL + offset_of!(S, v); diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 333d94f41798d..bcab5d4d1f49b 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -172,7 +172,7 @@ pub mod mytest { use self::foo::i::A; //~ ERROR: module `i` is private pub mod foo { - pub use self::i::A as foo; + pub use self::i::A as Z; mod i { pub struct A; diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index 22cc16b12af79..95d681f9318ab 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -38,15 +38,18 @@ error[E0603]: module `i` is private --> $DIR/privacy1.rs:172:20 | LL | use self::foo::i::A; - | ^ - struct `A` is not publicly re-exported - | | - | private module + | ^ private module | note: the module `i` is defined here --> $DIR/privacy1.rs:177:9 | LL | mod i { | ^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use self::foo::i::A; +LL + use mytest::foo::Z; + | error[E0603]: module `baz` is private --> $DIR/privacy1.rs:148:18 diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.ed2015.stderr b/tests/ui/proc-macro/attributes-on-modules-fail.ed2015.stderr new file mode 100644 index 0000000000000..299ec4943c522 --- /dev/null +++ b/tests/ui/proc-macro/attributes-on-modules-fail.ed2015.stderr @@ -0,0 +1,29 @@ +error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s + --> $DIR/attributes-on-modules-fail.rs:22:1 + | +LL | #[derive(Copy)] + | ^^^^^^^^^^^^^^^ not applicable here +LL | mod n {} + | -------- not a `struct`, `enum` or `union` + +error[E0425]: cannot find type `Y` in this scope + --> $DIR/attributes-on-modules-fail.rs:14:14 + | +LL | type A = Y; + | ^ not found in this scope + +error[E0425]: cannot find type `X` in this scope + --> $DIR/attributes-on-modules-fail.rs:20:10 + | +LL | type A = X; + | ^ not found in this scope + | +help: consider importing this struct + | +LL + use m::X; + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0425, E0774. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.stderr b/tests/ui/proc-macro/attributes-on-modules-fail.ed2024.stderr similarity index 79% rename from tests/ui/proc-macro/attributes-on-modules-fail.stderr rename to tests/ui/proc-macro/attributes-on-modules-fail.ed2024.stderr index 78593bf8de897..04dfc1dd08c6c 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.stderr +++ b/tests/ui/proc-macro/attributes-on-modules-fail.ed2024.stderr @@ -1,5 +1,5 @@ error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s - --> $DIR/attributes-on-modules-fail.rs:17:1 + --> $DIR/attributes-on-modules-fail.rs:22:1 | LL | #[derive(Copy)] | ^^^^^^^^^^^^^^^ not applicable here @@ -7,25 +7,25 @@ LL | mod n {} | -------- not a `struct`, `enum` or `union` error[E0425]: cannot find type `Y` in this scope - --> $DIR/attributes-on-modules-fail.rs:11:14 + --> $DIR/attributes-on-modules-fail.rs:14:14 | LL | type A = Y; | ^ not found in this scope | help: consider importing this struct | -LL + use Y; +LL + use crate::Y; | error[E0425]: cannot find type `X` in this scope - --> $DIR/attributes-on-modules-fail.rs:15:10 + --> $DIR/attributes-on-modules-fail.rs:20:10 | LL | type A = X; | ^ not found in this scope | help: consider importing this struct | -LL + use m::X; +LL + use crate::m::X; | error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.rs b/tests/ui/proc-macro/attributes-on-modules-fail.rs index 6ad935d494458..af761ad83944e 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.rs +++ b/tests/ui/proc-macro/attributes-on-modules-fail.rs @@ -1,6 +1,9 @@ -//@ edition:2015 +//@ revisions: ed2015 ed2024 +//@ [ed2015] edition:2015 +//@ [ed2024] edition:2024 //@ proc-macro: test-macros.rs + #[macro_use] extern crate test_macros; @@ -9,6 +12,8 @@ mod m { pub struct X; type A = Y; //~ ERROR cannot find type `Y` in this scope + // In edition 2015 we'd suggest referring to `crate::Y` as `Y`, which is not a good suggestion, + // but in other editions we suggest the appropriate `crate::Y`. } struct Y; diff --git a/tests/ui/resolve/suggest-re-exported-name.fixed b/tests/ui/resolve/suggest-re-exported-name.fixed new file mode 100644 index 0000000000000..337fb7b593e6f --- /dev/null +++ b/tests/ui/resolve/suggest-re-exported-name.fixed @@ -0,0 +1,16 @@ +//@ run-rustfix +use std::fmt::Debug as OtherDebug; + +pub struct Debug; + +pub fn foo() -> impl OtherDebug { //~ ERROR: expected trait, found struct `Debug` + "" +} + +pub fn bar() -> impl OtherDebug { //~ ERROR: expected trait, found struct `crate::Debug` + "" +} + +pub fn baz() {} //~ ERROR: expected trait, found struct `Debug` + +fn main() {} diff --git a/tests/ui/resolve/suggest-re-exported-name.rs b/tests/ui/resolve/suggest-re-exported-name.rs new file mode 100644 index 0000000000000..bfe5c35f9719d --- /dev/null +++ b/tests/ui/resolve/suggest-re-exported-name.rs @@ -0,0 +1,16 @@ +//@ run-rustfix +use std::fmt::Debug as OtherDebug; + +pub struct Debug; + +pub fn foo() -> impl Debug { //~ ERROR: expected trait, found struct `Debug` + "" +} + +pub fn bar() -> impl crate::Debug { //~ ERROR: expected trait, found struct `crate::Debug` + "" +} + +pub fn baz() {} //~ ERROR: expected trait, found struct `Debug` + +fn main() {} diff --git a/tests/ui/resolve/suggest-re-exported-name.stderr b/tests/ui/resolve/suggest-re-exported-name.stderr new file mode 100644 index 0000000000000..b3046417b226a --- /dev/null +++ b/tests/ui/resolve/suggest-re-exported-name.stderr @@ -0,0 +1,37 @@ +error[E0404]: expected trait, found struct `Debug` + --> $DIR/suggest-re-exported-name.rs:6:22 + | +LL | pub fn foo() -> impl Debug { + | ^^^^^ not a trait + | +help: consider using this trait through its public re-export instead + | +LL | pub fn foo() -> impl OtherDebug { + | +++++ + +error[E0404]: expected trait, found struct `crate::Debug` + --> $DIR/suggest-re-exported-name.rs:10:22 + | +LL | pub fn bar() -> impl crate::Debug { + | ^^^^^^^^^^^^ not a trait + | +help: consider using this trait through its public re-export instead + | +LL - pub fn bar() -> impl crate::Debug { +LL + pub fn bar() -> impl OtherDebug { + | + +error[E0404]: expected trait, found struct `Debug` + --> $DIR/suggest-re-exported-name.rs:14:15 + | +LL | pub fn baz() {} + | ^^^^^ not a trait + | +help: consider using this trait through its public re-export instead + | +LL | pub fn baz() {} + | +++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/shadowed/shadowed-use-visibility.stderr b/tests/ui/shadowed/shadowed-use-visibility.stderr index bbec8380fd032..1980437ab9242 100644 --- a/tests/ui/shadowed/shadowed-use-visibility.stderr +++ b/tests/ui/shadowed/shadowed-use-visibility.stderr @@ -14,7 +14,10 @@ note: ...and refers to the module `foo` which is defined here | LL | mod foo { | ^^^^^^^ -help: consider importing this function instead +help: consider importing one of these functions instead + | +LL - use crate::foo::bar::f as g; +LL + use foo::bar as g; | LL - use crate::foo::bar::f as g; LL + use foo::f as g; @@ -36,11 +39,14 @@ note: ...and refers to the module `foo` which is defined here | LL | mod foo { | ^^^^^^^ -help: consider importing this function through its public re-export instead +help: consider importing one of these functions instead | LL - use bar::f::f; LL + use bar::f; | +LL - use bar::f::f; +LL + use foo::bar; + | error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs b/tests/ui/type-alias-impl-trait/debug-ty-with-free-alias.rs similarity index 100% rename from tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs rename to tests/ui/type-alias-impl-trait/debug-ty-with-free-alias.rs diff --git a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs b/tests/ui/type-alias-impl-trait/impl-auto-trait-for-free-alias.rs similarity index 100% rename from tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs rename to tests/ui/type-alias-impl-trait/impl-auto-trait-for-free-alias.rs diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-free-alias.rs similarity index 100% rename from tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs rename to tests/ui/type-alias-impl-trait/infinite-cycle-involving-free-alias.rs diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-free-alias.stderr similarity index 78% rename from tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr rename to tests/ui/type-alias-impl-trait/infinite-cycle-involving-free-alias.stderr index 426a6c29fff66..83aca51de02e9 100644 --- a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr +++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-free-alias.stderr @@ -1,5 +1,5 @@ error[E0720]: cannot resolve opaque type - --> $DIR/infinite-cycle-involving-weak.rs:6:13 + --> $DIR/infinite-cycle-involving-free-alias.rs:6:13 | LL | fn foo() -> T { | ^ diff --git a/tests/ui/type-alias/lack-of-wfcheck-gat-generic-const-args.rs b/tests/ui/type-alias/lack-of-wfcheck-gat-generic-const-args.rs index 6a6b0d2d6b799..b4f07457bd46c 100644 --- a/tests/ui/type-alias/lack-of-wfcheck-gat-generic-const-args.rs +++ b/tests/ui/type-alias/lack-of-wfcheck-gat-generic-const-args.rs @@ -1,5 +1,5 @@ // Demonstrate that generic const arguments in GAT constraints are rejected at -// the definition site of an eager type alias. +// the definition site of an unchecked type alias. //@ compile-flags: -Znext-solver=globally diff --git a/tests/ui/type-alias/lack-of-wfcheck.rs b/tests/ui/type-alias/lack-of-wfcheck.rs index 91fbee8d3f198..3fd6b2240d25f 100644 --- a/tests/ui/type-alias/lack-of-wfcheck.rs +++ b/tests/ui/type-alias/lack-of-wfcheck.rs @@ -1,8 +1,9 @@ -// Demonstrate that we don't check the definition site of (eager) type aliases for well-formedness. +// Demonstrate that we don't check the definition site of (unchecked) type aliases for +// well-formedness. // // Listed below are ill-formed type system entities which we don't reject since they appear inside -// the definition of (eager) type aliases. These type aliases are intentionally not referenced from -// anywhere to prevent the eagerly expanded / instantiated aliased types from getting wfchecked +// the definition of (unchecked) type aliases. These type aliases are intentionally not referenced +// from anywhere to prevent the eagerly expanded / instantiated aliased types from getting wfchecked // since that's not what we're testing here. //@ check-pass diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.checked.stderr similarity index 100% rename from tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr rename to tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.checked.stderr diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs index bc226d2893012..c93ecad9263da 100644 --- a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs @@ -1,26 +1,26 @@ -// Ensure that we don't suggest *type alias bounds* for **eager** type aliases. -// issue: rust-lang/rust#125789 +// Ensure that we don't suggest *type alias bounds* for **unchecked** type aliases. +// issue: -//@ revisions: eager lazy -#![cfg_attr(lazy, feature(checked_type_aliases), allow(incomplete_features))] +//@ revisions: unchecked checked +#![cfg_attr(checked, feature(checked_type_aliases))] trait Trait { type Assoc; } type AssocOf = T::Assoc; //~ ERROR associated type `Assoc` not found for `T` -//[eager]~^ HELP consider fully qualifying the associated type -//[lazy]~| HELP consider restricting type parameter `T` +//[unchecked]~^ HELP consider fully qualifying the associated type +//[checked]~| HELP consider restricting type parameter `T` type AssokOf = T::Assok; //~ ERROR associated type `Assok` not found for `T` -//[eager]~^ HELP consider fully qualifying and renaming the associated type -//[lazy]~| HELP consider restricting type parameter `T` -//[lazy]~| HELP and changing the associated type name +//[unchecked]~^ HELP consider fully qualifying and renaming the associated type +//[checked]~| HELP consider restricting type parameter `T` +//[checked]~| HELP and changing the associated type name trait Parametrized<'a, T, const N: usize> { type Proj; } type ProjOf = T::Proj; //~ ERROR associated type `Proj` not found for `T` -//[eager]~^ HELP consider fully qualifying the associated type -//[lazy]~| HELP consider restricting type parameter `T` +//[unchecked]~^ HELP consider fully qualifying the associated type +//[checked]~| HELP consider restricting type parameter `T` fn main() {} diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.unchecked.stderr similarity index 100% rename from tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr rename to tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.unchecked.stderr