From 4952963e29496d9f1139939983b548786c17237a Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 10 Aug 2026 22:08:40 -0700 Subject: [PATCH 01/27] respect borrow kind in `kill_borrows_on_place` --- compiler/rustc_borrowck/src/dataflow.rs | 12 ++++--- ...nt-kill-shallow-borrows-on-child-writes.rs | 32 +++++++++++++++++++ ...ill-shallow-borrows-on-child-writes.stderr | 19 +++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.rs create mode 100644 tests/ui/borrowck/dont-kill-shallow-borrows-on-child-writes.stderr diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 5bfe5ee64f050..dd6c98f806c4e 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -12,7 +12,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 @@ -474,7 +476,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); @@ -487,11 +489,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/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`. From 7bc7d5a836eebf88a5fe3123898e5c14bc8a53cb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Oct 2026 11:56:47 +0200 Subject: [PATCH 02/27] Prepare for merging from rust-lang/rust This updates the rust-toolchain.toml file to nightly-2026-10-08 (1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6). --- compiler/rustc_codegen_cranelift/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index a6468283e1270..7ed9e3a15b296 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-08" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From 228c2a19c80dd2bcd1b4ffb277c96f4a49ad7962 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Oct 2026 12:37:23 +0200 Subject: [PATCH 03/27] Fix rustc test suite --- .../scripts/setup_rust_fork.sh | 75 +++++++++++++++++++ .../scripts/test_rustc_tests.sh | 1 + 2 files changed, 76 insertions(+) diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index 2899458db114a..06a98d7417a0e 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh @@ -90,6 +90,81 @@ index 330fb465de..a4593ed96f 100644 // On CI, we should always have a non-upstream merge commit at the tip, EOF +# rust-lang/rust#162714 makes test failures unreadable, so revert it here +cat < { +@@ -175,6 +176,8 @@ impl TestCx<'_> { + + let mut cmd = Command::new(&recipe_bin); + cmd.current_dir(&rmake_out_dir) ++ .stdout(Stdio::piped()) ++ .stderr(Stdio::piped()) + // Provide the target-specific env var that is used to record dylib search paths. For + // example, this could be \`LD_LIBRARY_PATH\` on some linux distros but \`PATH\` on Windows. + .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) +@@ -337,39 +336,16 @@ impl TestCx<'_> { + } + } + ++ let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn \`rmake\`")); ++ let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); ++ let stdout = String::from_utf8_lossy(&stdout).into_owned(); ++ let stderr = String::from_utf8_lossy(&stderr).into_owned(); ++ // This conditions on \`status.success()\` so we don't print output twice on error. ++ // NOTE: this code is called from an executor thread, so it's hidden by default unless --no-capture is passed. ++ self.dump_output(status.success(), &cmd.get_program().to_string_lossy(), &stdout, &stderr); ++ if !status.success() { ++ let res = ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) }; ++ self.fatal_proc_rec("rmake recipe failed to complete", &res); +- if self.config.capture { +- cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); +- let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn \`rmake\`")); +- let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); +- let stdout = String::from_utf8_lossy(&stdout).into_owned(); +- let stderr = String::from_utf8_lossy(&stderr).into_owned(); +- // This conditions on \`status.success()\` so we don't print output twice on error. +- self.dump_output( +- status.success(), +- &cmd.get_program().to_string_lossy(), +- &stdout, +- &stderr, +- ); +- if !status.success() { +- let res = +- ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) }; +- self.fatal_proc_rec("rmake recipe failed to complete", &res); +- } +- } else { +- // When --no-capture is passed, we don't need to capture the output and just wait for the process to finish +- let mut proc = +- disable_error_reporting(|| cmd.spawn().expect("failed to spawn \`rmake\`")); +- let status = proc.wait().expect("failed to wait for \`rmake\`"); +- if !status.success() { +- let res = ProcRes { +- status, +- stdout: String::new(), +- stderr: String::new(), +- truncated: Truncated::No, +- cmdline: format!("{:?}", cmd), +- }; +- self.fatal_proc_rec("rmake recipe failed to complete", &res); +- } + } + } + } +EOF + popd # Allow the testsuite to use llvm tools diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 648f68588e04b..1a1b59c5b8c77 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -171,6 +171,7 @@ rm -r tests/run-make/export # something about rustc version mismatches rm tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind rm tests/ui/extern/extern-types-field-offset.rs # expects /rustc/ 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 # ============ From e8b09fb5cf299834512087208259cefbc546144f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 11 Oct 2026 18:21:52 +0000 Subject: [PATCH 04/27] Account for `use foo as bar;` on resolution error suggestions Do not suggest ``` help: consider importing this module | LL + use a; | ``` Suggest renamed re-exports: ``` error[E0603]: module `i` is private --> $DIR/privacy1.rs:172:20 | LL | use self::foo::i::A; | ^ 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; | ``` Suggest renamed imports: ``` error[E0404]: expected trait, found struct `Debug` --> $DIR/suggest-re-exported-name.rs:7: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 { | +++++ ``` --- .../rustc_resolve/src/diagnostics/impls.rs | 123 +++++++++++++++--- .../restriction_resolution_errors.stderr | 4 - .../restriction-resolution-errors.stderr | 4 - tests/ui/offset-of/offset-of-self.stderr | 6 +- tests/ui/privacy/privacy1.rs | 2 +- tests/ui/privacy/privacy1.stderr | 9 +- .../attributes-on-modules-fail.ed2015.stderr | 29 +++++ ... attributes-on-modules-fail.ed2024.stderr} | 10 +- .../proc-macro/attributes-on-modules-fail.rs | 7 +- .../ui/resolve/suggest-re-exported-name.fixed | 16 +++ tests/ui/resolve/suggest-re-exported-name.rs | 16 +++ .../resolve/suggest-re-exported-name.stderr | 37 ++++++ .../shadowed/shadowed-use-visibility.stderr | 10 +- 13 files changed, 228 insertions(+), 45 deletions(-) create mode 100644 tests/ui/proc-macro/attributes-on-modules-fail.ed2015.stderr rename tests/ui/proc-macro/{attributes-on-modules-fail.stderr => attributes-on-modules-fail.ed2024.stderr} (79%) create mode 100644 tests/ui/resolve/suggest-re-exported-name.fixed create mode 100644 tests/ui/resolve/suggest-re-exported-name.rs create mode 100644 tests/ui/resolve/suggest-re-exported-name.stderr diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index 06c2742c489be..808da8300a95b 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -1736,15 +1736,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 @@ -1755,8 +1747,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 @@ -4077,19 +4110,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(( @@ -4098,13 +4146,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 = @@ -4127,6 +4177,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/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/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 From 67ccc41cdc83652ba81f25c36d2221addda56919 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 12 Oct 2026 15:02:02 +0200 Subject: [PATCH 05/27] Prepare for merging from rust-lang/rust This updates the rust-toolchain.toml file to nightly-2026-10-12 (080cc27146389dbb5c8772c476b1937be9c6110f). --- compiler/rustc_codegen_cranelift/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index 7ed9e3a15b296..3fa34816c856e 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-10-08" +channel = "nightly-2026-10-12" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From ce7b4b3e36c29d642e926c88db742d4fa52e8b3e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 12 Oct 2026 15:13:58 +0200 Subject: [PATCH 06/27] Fix rustc test suite --- .../scripts/setup_rust_fork.sh | 77 +------------------ 1 file changed, 1 insertion(+), 76 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index 06a98d7417a0e..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 < { -@@ -175,6 +176,8 @@ impl TestCx<'_> { - - let mut cmd = Command::new(&recipe_bin); - cmd.current_dir(&rmake_out_dir) -+ .stdout(Stdio::piped()) -+ .stderr(Stdio::piped()) - // Provide the target-specific env var that is used to record dylib search paths. For - // example, this could be \`LD_LIBRARY_PATH\` on some linux distros but \`PATH\` on Windows. - .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) -@@ -337,39 +336,16 @@ impl TestCx<'_> { - } - } - -+ let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn \`rmake\`")); -+ let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); -+ let stdout = String::from_utf8_lossy(&stdout).into_owned(); -+ let stderr = String::from_utf8_lossy(&stderr).into_owned(); -+ // This conditions on \`status.success()\` so we don't print output twice on error. -+ // NOTE: this code is called from an executor thread, so it's hidden by default unless --no-capture is passed. -+ self.dump_output(status.success(), &cmd.get_program().to_string_lossy(), &stdout, &stderr); -+ if !status.success() { -+ let res = ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) }; -+ self.fatal_proc_rec("rmake recipe failed to complete", &res); -- if self.config.capture { -- cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); -- let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn \`rmake\`")); -- let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); -- let stdout = String::from_utf8_lossy(&stdout).into_owned(); -- let stderr = String::from_utf8_lossy(&stderr).into_owned(); -- // This conditions on \`status.success()\` so we don't print output twice on error. -- self.dump_output( -- status.success(), -- &cmd.get_program().to_string_lossy(), -- &stdout, -- &stderr, -- ); -- if !status.success() { -- let res = -- ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) }; -- self.fatal_proc_rec("rmake recipe failed to complete", &res); -- } -- } else { -- // When --no-capture is passed, we don't need to capture the output and just wait for the process to finish -- let mut proc = -- disable_error_reporting(|| cmd.spawn().expect("failed to spawn \`rmake\`")); -- let status = proc.wait().expect("failed to wait for \`rmake\`"); -- if !status.success() { -- let res = ProcRes { -- status, -- stdout: String::new(), -- stderr: String::new(), -- truncated: Truncated::No, -- cmdline: format!("{:?}", cmd), -- }; -- self.fatal_proc_rec("rmake recipe failed to complete", &res); -- } - } - } - } -EOF - popd # Allow the testsuite to use llvm tools From c915829271170214779bb665cf034e31f3ba074d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:41:58 +0200 Subject: [PATCH 07/27] Ignore abi-cafe test that ICEs cg_ssa on Windows --- compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml b/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml index 54f9445c8e524..d38c799c750e0 100644 --- a/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml +++ b/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml @@ -10,6 +10,10 @@ '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" From eeb0c65c1a4409c725961607b7ca82220821fb03 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 14 Oct 2026 11:33:01 +0200 Subject: [PATCH 08/27] Prepare for merging from rust-lang/rust This updates the rust-toolchain.toml file to nightly-2026-10-14 (822182db4c4a1827256881d8c7aa685f0bcf2b11). --- compiler/rustc_codegen_cranelift/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index 3fa34816c856e..a27d32ed83f3e 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-10-12" +channel = "nightly-2026-10-14" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From 6b7560c9d3c9bc1492b505f995f7f768c117425b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 14 Oct 2026 12:18:09 +0200 Subject: [PATCH 09/27] Improve rustup.sh --- .../rustc_codegen_cranelift/scripts/rustup.sh | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) 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 From d048b4d400c32ada8b2f322d153b363f21aa1afa Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Fri, 16 Oct 2026 23:09:37 +0800 Subject: [PATCH 10/27] Add test --- .../async-drop-shim-proxy-164433.rs | 26 +++++++++++++++++++ .../async-drop-shim-proxy-164433.run.stdout | 2 ++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.run.stdout 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..7659e06a8e689 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-shim-proxy-164433.run.stdout @@ -0,0 +1,2 @@ +end of outer +done From c7a023aabe31e29ef571b9db7d9c1231856dead4 Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Fri, 16 Oct 2026 23:17:30 +0800 Subject: [PATCH 11/27] Make async drop shim proxy pinned --- compiler/rustc_mir_transform/src/coroutine/drop.rs | 2 ++ ...0}-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...dd-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...te-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...0}-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...oo-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...ld-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...0}-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...0}-{closure#1}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...er-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...0}-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...it-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ ...nt-{closure#0}.coroutine_drop_proxy_async.0.mir | 14 ++++++++------ .../async-drop-shim-proxy-164433.run.stdout | 1 + 14 files changed, 99 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index aea2992bbce21..645c099a0c005 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -377,6 +377,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/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/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 index 7659e06a8e689..5b2df0a2ed572 100644 --- 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 @@ -1,2 +1,3 @@ end of outer +Bar dropped done From a881c33b7e5150fcb2b9ad566a6884d21a9a5274 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:12:00 +0200 Subject: [PATCH 12/27] Prepare for merging from rust-lang/rust This updates the rust-toolchain.toml file to nightly-2026-10-19 (b6eeb93c992027a03e1fd120b6652546396b142c). --- compiler/rustc_codegen_cranelift/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index a27d32ed83f3e..3bd7a294fb473 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-10-14" +channel = "nightly-2026-10-19" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From ff8022eb4e8349ebd28294daf17027dedd7694df Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:32:40 +0200 Subject: [PATCH 13/27] Fix rustc test suite --- compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 1a1b59c5b8c77..2cf5a568f7e58 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -179,6 +179,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 # ====================== From dfc01e274af9143fc36af3b5532fb289604b94df Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 21 Sep 2026 16:44:03 +0200 Subject: [PATCH 14/27] Update to Cranelift 0.137 --- compiler/rustc_codegen_cranelift/Cargo.lock | 86 ++++++++++--------- compiler/rustc_codegen_cranelift/Cargo.toml | 26 +++--- .../src/debuginfo/line_info.rs | 1 + .../src/debuginfo/unwind.rs | 33 +++---- 4 files changed, 74 insertions(+), 72 deletions(-) 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/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!(), } From db045cefc0587010e5444b010812da7d90fe2054 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 6 Oct 2026 11:45:27 +0200 Subject: [PATCH 15/27] Re-enable x86_64 windows abi-cafe tests --- compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml b/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml index d38c799c750e0..0f744034f9c1a 100644 --- a/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml +++ b/compiler/rustc_codegen_cranelift/scripts/abi-cafe-rules.toml @@ -6,10 +6,6 @@ '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" From 87d99ba94a57c385467895e9454323ee7184a574 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:09:13 +0200 Subject: [PATCH 16/27] Remove workaround for fixed ABI issue --- ...oot_tests-Disable-complex-type-tests.patch | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-Disable-complex-type-tests.patch 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 - From 23670f7640e429aa9abe42ef23327440f5ed36a8 Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Sat, 3 Oct 2026 08:38:22 +0600 Subject: [PATCH 17/27] add test for the use<..> suggestion on elided lifetimes records current behaviour. for an anonymous lifetime the suggestion renders use<'_>, which resolves to the first elided lifetime in the signature. two of the cases here still fail after applying it, and one stops resolving entirely and reports a missing lifetime specifier on top of the original error. --- ...e-anon-lifetime-suggestion-issue-132199.rs | 45 +++++++++++ ...on-lifetime-suggestion-issue-132199.stderr | 78 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.rs create mode 100644 tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.stderr 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..1a5c2eb1709f9 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.rs @@ -0,0 +1,45 @@ +//@ edition: 2021 + +// 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. + +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..4bf35e4261154 --- /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:14: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 a `use<...>` bound to explicitly capture `'_` + | +LL | fn two_anon(&self, t: &T) -> 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:20: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:26: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:34: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 a `use<...>` bound to explicitly capture `'_` + | +LL | fn second_anon(_a: &u8, b: &T) -> 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:41: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 a `use<...>` bound to explicitly capture `'_` + | +LL | fn path_anon(x: Foo, y: Foo) -> impl Sized + use<'_> { + | +++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0700`. From eee351a64f50c99f779e6ac17852ad76ecc5c6db Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Sat, 3 Oct 2026 09:23:54 +0600 Subject: [PATCH 18/27] name the elided lifetimes in the use<..> suggestion for E0700 for an anonymous lifetime the suggestion rendered use<'_>, which resolves to the first elided lifetime in the signature. with several of them it either captured the wrong one or stopped resolving and reported a missing lifetime specifier on top of the original error. when the hidden type captures more than one anonymous lifetime the suggestion now names them in the signature and lists those names in the bound. a signature with a single elided lifetime keeps the shorter use<'_> form. fixes https://github.com/rust-lang/rust/issues/132199 --- .../rustc_trait_selection/src/diagnostics.rs | 14 ++ .../src/error_reporting/infer/region.rs | 175 +++++++++++++++++- ...non-lifetime-suggestion-issue-132199.fixed | 48 +++++ ...e-anon-lifetime-suggestion-issue-132199.rs | 3 + ...on-lifetime-suggestion-issue-132199.stderr | 28 +-- tests/ui/lifetimes/issue-105227.fixed | 26 +++ tests/ui/lifetimes/issue-105227.rs | 8 +- tests/ui/lifetimes/issue-105227.stderr | 19 +- 8 files changed, 291 insertions(+), 30 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/name-anon-lifetime-suggestion-issue-132199.fixed create mode 100644 tests/ui/lifetimes/issue-105227.fixed 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..03bf7cbceaa41 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; @@ -1319,7 +1321,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 +1377,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 +1466,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 +1573,142 @@ 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 hir_generics = tcx.hir_get_generics(fn_def_id)?; + + 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 = FxIndexSet::default(); + tcx.for_each_free_region(&hidden_ty, |region| { + if let Some(info) = tcx.is_suitable_region(generic_param_scope, region) { + hidden_regions.insert(info.region_def_id); + } + }); + + // 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 mut bounds = captured_lifetimes.clone(); + for &def_id in &hidden_regions { + if !collector.anon_lifetimes.contains_key(&def_id) { + bounds.insert(tcx.item_name(def_id)); + } + } + let to_name: Vec<_> = collector + .anon_lifetimes + .iter() + .filter(|(def_id, _)| hidden_regions.contains(*def_id)) + .map(|(_, &lifetime)| lifetime) + .collect(); + if to_name.is_empty() { + return None; + } + + // Any name already written on the function, in scope around it, or already in the capture + // list is off limits. Late-bound lifetimes are missing from `generics_of`, so the written + // parameters have to come from HIR. + let mut taken = bounds.clone(); + taken.extend( + hir_generics + .params + .iter() + .filter(|param| param.is_lifetime()) + .map(|param| param.name.ident().name), + ); + let mut generics = tcx.generics_of(fn_def_id); + loop { + for param in &generics.own_params { + if let ty::GenericParamDefKind::Lifetime = param.kind { + taken.insert(param.name); + } + } + if let Some(parent) = generics.parent { + generics = tcx.generics_of(parent); + } else { + break; + } + } + let mut fresh_names = + ('a'..='z').map(|c| Symbol::intern(&format!("'{c}"))).filter(|name| !taken.contains(name)); + + let mut suggs = vec![]; + let mut new_params = vec![]; + for lifetime in to_name { + let name = fresh_names.next()?; + new_params.push(name.to_string()); + bounds.insert(name); + suggs.push(lifetime.suggestion(name.as_str())); + } + + let new_params = new_params.join(", "); + suggs.push(if let Some(params_span) = hir_generics.span_for_lifetime_suggestion() { + (params_span, format!("{new_params}, ")) + } else { + (hir_generics.span, format!("<{new_params}>")) + }); + + 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, together with the +/// lifetime parameter it resolves to. +struct AnonLifetimeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + anon_lifetimes: FxIndexMap, +} + +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.entry(def_id.to_def_id()).or_insert(lifetime); + } + } +} 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 index 1a5c2eb1709f9..b05245223680f 100644 --- 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 @@ -1,9 +1,12 @@ //@ 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); 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 index 4bf35e4261154..5d4ed53e19427 100644 --- 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 @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds - --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:14:9 + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:17:9 | LL | fn two_anon(&self, t: &T) -> impl Sized { | ----- ---------- opaque type defined here @@ -8,13 +8,13 @@ LL | fn two_anon(&self, t: &T) -> impl Sized { LL | (self, t) | ^^^^^^^^^ | -help: add a `use<...>` bound to explicitly capture `'_` +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them | -LL | fn two_anon(&self, t: &T) -> impl Sized + use<'_> { - | +++++++++ +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:20:9 + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:23:9 | LL | fn one_anon(&self) -> impl Sized { | ----- ---------- opaque type defined here @@ -29,7 +29,7 @@ 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:26:9 + --> $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 @@ -44,7 +44,7 @@ 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:34:5 + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:37:5 | LL | fn second_anon(_a: &u8, b: &T) -> impl Sized { | -- ---------- opaque type defined here @@ -53,13 +53,13 @@ LL | fn second_anon(_a: &u8, b: &T) -> impl Sized { LL | b | ^ | -help: add a `use<...>` bound to explicitly capture `'_` +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them | -LL | fn second_anon(_a: &u8, b: &T) -> impl Sized + use<'_> { - | +++++++++ +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:41:5 + --> $DIR/name-anon-lifetime-suggestion-issue-132199.rs:44:5 | LL | fn path_anon(x: Foo, y: Foo) -> impl Sized { | --- ---------- opaque type defined here @@ -68,10 +68,10 @@ LL | fn path_anon(x: Foo, y: Foo) -> impl Sized { LL | (x, y) | ^^^^^^ | -help: add a `use<...>` bound to explicitly capture `'_` +help: add `use<...>` bound and name the elided lifetimes to explicitly capture them | -LL | fn path_anon(x: Foo, y: Foo) -> impl Sized + use<'_> { - | +++++++++ +LL | fn path_anon<'a, 'b>(x: Foo<'a>, y: Foo<'b>) -> impl Sized + use<'a, 'b> { + | ++++++++ ++++ ++++ +++++++++++++ error: aborting due to 5 previous errors 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 From 81b952e2282d7a0b889308c5b01824ecdb15d33f Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Wed, 14 Oct 2026 16:46:15 +0600 Subject: [PATCH 19/27] reuse suggest_name_region for naming the elided lifetimes suggest_name_regions names several regions against one set of used names and adds the new generic parameters once, and suggest_name_region now delegates to it --- .../src/error_reporting/infer/region.rs | 241 +++++++++--------- 1 file changed, 118 insertions(+), 123 deletions(-) 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 03bf7cbceaa41..688272a5239f5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -936,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( @@ -1171,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<'_>, @@ -1594,7 +1628,6 @@ fn name_anon_lifetimes_suggestion<'tcx>( captured_non_lifetimes: &FxIndexSet, ) -> Option> { let fn_sig = tcx.hir_node_by_def_id(fn_def_id).fn_sig()?; - let hir_generics = tcx.hir_get_generics(fn_def_id)?; let mut collector = AnonLifetimeCollector { tcx, anon_lifetimes: Default::default() }; for input in fn_sig.decl.inputs { @@ -1606,73 +1639,36 @@ fn name_anon_lifetimes_suggestion<'tcx>( return None; } - let mut hidden_regions = FxIndexSet::default(); + 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.insert(info.region_def_id); + 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 mut bounds = captured_lifetimes.clone(); - for &def_id in &hidden_regions { - if !collector.anon_lifetimes.contains_key(&def_id) { - bounds.insert(tcx.item_name(def_id)); - } - } - let to_name: Vec<_> = collector + 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(|(def_id, _)| hidden_regions.contains(*def_id)) - .map(|(_, &lifetime)| lifetime) + .filter_map(|def_id| hidden_regions.get(def_id).copied()) .collect(); - if to_name.is_empty() { + if anon.is_empty() { return None; } + let regions: Vec<_> = named.chain(anon).collect(); - // Any name already written on the function, in scope around it, or already in the capture - // list is off limits. Late-bound lifetimes are missing from `generics_of`, so the written - // parameters have to come from HIR. - let mut taken = bounds.clone(); - taken.extend( - hir_generics - .params + let mut suggs = vec![]; + let mut bounds = captured_lifetimes.clone(); + bounds.extend( + suggest_name_regions(tcx, generic_param_scope, ®ions, &mut suggs)? .iter() - .filter(|param| param.is_lifetime()) - .map(|param| param.name.ident().name), + .map(|name| Symbol::intern(name)), ); - let mut generics = tcx.generics_of(fn_def_id); - loop { - for param in &generics.own_params { - if let ty::GenericParamDefKind::Lifetime = param.kind { - taken.insert(param.name); - } - } - if let Some(parent) = generics.parent { - generics = tcx.generics_of(parent); - } else { - break; - } - } - let mut fresh_names = - ('a'..='z').map(|c| Symbol::intern(&format!("'{c}"))).filter(|name| !taken.contains(name)); - - let mut suggs = vec![]; - let mut new_params = vec![]; - for lifetime in to_name { - let name = fresh_names.next()?; - new_params.push(name.to_string()); - bounds.insert(name); - suggs.push(lifetime.suggestion(name.as_str())); - } - - let new_params = new_params.join(", "); - suggs.push(if let Some(params_span) = hir_generics.span_for_lifetime_suggestion() { - (params_span, format!("{new_params}, ")) - } else { - (hir_generics.span, format!("<{new_params}>")) - }); let concatenated_bounds = bounds .into_iter() @@ -1688,11 +1684,10 @@ fn name_anon_lifetimes_suggestion<'tcx>( Some(suggs) } -/// Collects every anonymous lifetime written in a function signature, together with the -/// lifetime parameter it resolves to. +/// Collects every anonymous lifetime written in a function signature. struct AnonLifetimeCollector<'tcx> { tcx: TyCtxt<'tcx>, - anon_lifetimes: FxIndexMap, + anon_lifetimes: FxIndexSet, } impl<'tcx> Visitor<'tcx> for AnonLifetimeCollector<'tcx> { @@ -1708,7 +1703,7 @@ impl<'tcx> Visitor<'tcx> for AnonLifetimeCollector<'tcx> { rbv::ResolvedArg::EarlyBound(def_id) | rbv::ResolvedArg::LateBound(_, _, def_id), ) = self.tcx.named_bound_var(lifetime.hir_id) { - self.anon_lifetimes.entry(def_id.to_def_id()).or_insert(lifetime); + self.anon_lifetimes.insert(def_id.to_def_id()); } } } From acbf22b46c361dfb53e66eeff5b85af9323ccc26 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Mon, 5 Oct 2026 10:56:54 +0000 Subject: [PATCH 20/27] std: keep value of local_pointer! until thread_cleanup is run --- library/std/src/sys/thread_local/guard/key.rs | 37 ++++++++++++++----- .../src/sys/thread_local/guard/retained.rs | 11 ++++++ library/std/src/sys/thread_local/mod.rs | 10 +++++ library/std/src/sys/thread_local/os.rs | 23 ++++++++++-- library/std/tests/thread_local/lib.rs | 2 - library/std/tests/thread_local/tests.rs | 13 ++----- 6 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 library/std/src/sys/thread_local/guard/retained.rs 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 809ef5cfe9c60..b3f55da24117c 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_env = "p3")), @@ -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; From ca127455d71368d69ab944b3ed057792a94ff2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 23 Oct 2026 09:34:20 +0200 Subject: [PATCH 21/27] Bump dist-x86_64-illumos to Ubuntu 22.04 --- src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From b40a8169ce471f254c619c10590b06bdfe091ef4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 23 Oct 2026 14:00:17 +0200 Subject: [PATCH 22/27] Prepare for merging from rust-lang/rust This updates the rust-toolchain.toml file to nightly-2026-10-23 (7189d39d9ce936881b8132c6addeaf3e295cd455). --- compiler/rustc_codegen_cranelift/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index 3bd7a294fb473..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-10-19" +channel = "nightly-2026-10-23" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From bb99fe62b2af8740f576f42a39ca401c73552106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 18 Oct 2026 18:12:09 +0200 Subject: [PATCH 23/27] Replace "weak (alias)" with "free (alias (type))" --- tests/ui/checked-type-alias/constrained-late-bound-regions.rs | 2 +- .../checked-type-alias/extern-crate-has-eager-type-aliases.rs | 4 ++-- tests/ui/checked-type-alias/implied-outlives-bounds.rs | 4 ++-- .../ui/checked-type-alias/unconstrained-late-bound-regions.rs | 2 +- ...ases-covering.rs => orphan-check-free-aliases-covering.rs} | 2 +- ...-covering.rs => orphan-check-free-aliases-not-covering.rs} | 2 +- ...g.stderr => orphan-check-free-aliases-not-covering.stderr} | 2 +- tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs | 2 +- .../{debug-ty-with-weak.rs => debug-ty-with-free-alias.rs} | 0 ...pl_for_weak_alias.rs => impl-auto-trait-for-free-alias.rs} | 0 ...volving-weak.rs => infinite-cycle-involving-free-alias.rs} | 0 ...weak.stderr => infinite-cycle-involving-free-alias.stderr} | 2 +- 12 files changed, 11 insertions(+), 11 deletions(-) rename tests/ui/coherence/{orphan-check-weak-aliases-covering.rs => orphan-check-free-aliases-covering.rs} (80%) rename tests/ui/coherence/{orphan-check-weak-aliases-not-covering.rs => orphan-check-free-aliases-not-covering.rs} (84%) rename tests/ui/coherence/{orphan-check-weak-aliases-not-covering.stderr => orphan-check-free-aliases-not-covering.stderr} (92%) rename tests/ui/type-alias-impl-trait/{debug-ty-with-weak.rs => debug-ty-with-free-alias.rs} (100%) rename tests/ui/type-alias-impl-trait/{impl_for_weak_alias.rs => impl-auto-trait-for-free-alias.rs} (100%) rename tests/ui/type-alias-impl-trait/{infinite-cycle-involving-weak.rs => infinite-cycle-involving-free-alias.rs} (100%) rename tests/ui/type-alias-impl-trait/{infinite-cycle-involving-weak.stderr => infinite-cycle-involving-free-alias.stderr} (78%) diff --git a/tests/ui/checked-type-alias/constrained-late-bound-regions.rs b/tests/ui/checked-type-alias/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-alias/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/extern-crate-has-eager-type-aliases.rs b/tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs index 52e1736975f46..7e913b5a667b1 100644 --- a/tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs +++ b/tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs @@ -10,9 +10,9 @@ #![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 +// `eager::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 +// obtain the variances of the type alias associated with the free alias type which would // panic because we don't compute this information for eager type aliases at all. struct Struct(eager::Alias); diff --git a/tests/ui/checked-type-alias/implied-outlives-bounds.rs b/tests/ui/checked-type-alias/implied-outlives-bounds.rs index 50cbb136411ee..978efbaa9a9e7 100644 --- a/tests/ui/checked-type-alias/implied-outlives-bounds.rs +++ b/tests/ui/checked-type-alias/implied-outlives-bounds.rs @@ -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/unconstrained-late-bound-regions.rs b/tests/ui/checked-type-alias/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-alias/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/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/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/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 { | ^ From 92917605f6106e1a8ac1d0a34634a0c3b59f0a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 18 Oct 2026 18:35:00 +0200 Subject: [PATCH 24/27] Replace "lazy (type alias)" with "checked (type alias)" And "eager (type alias)" with "unchecked (type alias)". --- .../src/coherence/orphan.rs | 6 --- .../rustc_hir_analysis/src/outlives/mod.rs | 2 +- compiler/rustc_middle/src/queries.rs | 2 +- .../type-alias-bounds.rs | 6 +-- .../ui/checked-type-alias/auto-trait-impls.rs | 2 +- .../auxiliary/{lazy.rs => checked.rs} | 0 .../auxiliary/{eager.rs => unchecked.rs} | 5 +- ...y-type-alias.rs => bad-free-alias-type.rs} | 0 ...lias.stderr => bad-free-alias-type.stderr} | 4 +- ...ecked-type-aliases.locally_checked.stderr} | 10 ++-- ...ked-type-aliases.locally_unchecked.stderr} | 10 ++-- .../extern-crate-has-checked-type-aliases.rs | 12 +++++ .../extern-crate-has-lazy-type-aliases.rs | 16 ------- ...xtern-crate-has-unchecked-type-aliases.rs} | 17 +++---- .../implied-outlives-bounds.rs | 2 +- .../leading-where-clause.fixed | 2 +- .../leading-where-clause.rs | 2 +- ...cursive-type-alias-in-const-projection.rs} | 2 +- ...ive-type-alias-in-const-projection.stderr} | 2 +- .../trailing-where-clause.rs | 3 +- .../trailing-where-clause.stderr | 4 +- .../unused-generic-parameters.fail.stderr | 14 +++--- .../unused-generic-parameters.rs | 12 ++--- tests/ui/checked-type-alias/use-site-wf.rs | 4 +- tests/ui/checked-type-alias/variance-1.rs | 9 ++-- tests/ui/checked-type-alias/variance-1.stderr | 4 +- .../dyn-compat-unspecified-assoc-consts.rs | 2 +- ...nst_arg_type_in_free_alias.checked.stderr} | 46 +++++++++---------- .../check_const_arg_type_in_free_alias.rs | 7 ++- ...t_arg_type_in_free_alias.unchecked.stderr} | 40 ++++++++-------- .../generic_const_exprs/type-alias-bounds.rs | 2 +- .../lack-of-wfcheck-gat-generic-const-args.rs | 2 +- tests/ui/type-alias/lack-of-wfcheck.rs | 7 +-- ...ved-assoc-ty-suggest-trait.checked.stderr} | 0 .../unresolved-assoc-ty-suggest-trait.rs | 22 ++++----- ...d-assoc-ty-suggest-trait.unchecked.stderr} | 0 36 files changed, 131 insertions(+), 149 deletions(-) rename tests/ui/checked-type-alias/auxiliary/{lazy.rs => checked.rs} (100%) rename tests/ui/checked-type-alias/auxiliary/{eager.rs => unchecked.rs} (58%) rename tests/ui/checked-type-alias/{bad-lazy-type-alias.rs => bad-free-alias-type.rs} (100%) rename tests/ui/checked-type-alias/{bad-lazy-type-alias.stderr => bad-free-alias-type.stderr} (88%) rename tests/ui/checked-type-alias/{extern-crate-has-lazy-type-aliases.locally_lazy.stderr => extern-crate-has-checked-type-aliases.locally_checked.stderr} (52%) rename tests/ui/checked-type-alias/{extern-crate-has-lazy-type-aliases.locally_eager.stderr => extern-crate-has-checked-type-aliases.locally_unchecked.stderr} (52%) create mode 100644 tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.rs delete mode 100644 tests/ui/checked-type-alias/extern-crate-has-lazy-type-aliases.rs rename tests/ui/checked-type-alias/{extern-crate-has-eager-type-aliases.rs => extern-crate-has-unchecked-type-aliases.rs} (61%) rename tests/ui/{type-alias/recursive-lazy-type-alias-ice-152633.rs => checked-type-alias/recursive-type-alias-in-const-projection.rs} (81%) rename tests/ui/{type-alias/recursive-lazy-type-alias-ice-152633.stderr => checked-type-alias/recursive-type-alias-in-const-projection.stderr} (85%) rename tests/ui/const-generics/{check_const_arg_type_in_free_alias.lazy.stderr => check_const_arg_type_in_free_alias.checked.stderr} (76%) rename tests/ui/const-generics/{check_const_arg_type_in_free_alias.eager.stderr => check_const_arg_type_in_free_alias.unchecked.stderr} (77%) rename tests/ui/type-alias/{unresolved-assoc-ty-suggest-trait.lazy.stderr => unresolved-assoc-ty-suggest-trait.checked.stderr} (100%) rename tests/ui/type-alias/{unresolved-assoc-ty-suggest-trait.eager.stderr => unresolved-assoc-ty-suggest-trait.unchecked.stderr} (100%) 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 d0429df43d1dd..91dae642a3cb5 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/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/checked-type-alias/auto-trait-impls.rs b/tests/ui/checked-type-alias/auto-trait-impls.rs index 978143ef7cf56..b3f0f463e5967 100644 --- a/tests/ui/checked-type-alias/auto-trait-impls.rs +++ b/tests/ui/checked-type-alias/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/auxiliary/lazy.rs b/tests/ui/checked-type-alias/auxiliary/checked.rs similarity index 100% rename from tests/ui/checked-type-alias/auxiliary/lazy.rs rename to tests/ui/checked-type-alias/auxiliary/checked.rs diff --git a/tests/ui/checked-type-alias/auxiliary/eager.rs b/tests/ui/checked-type-alias/auxiliary/unchecked.rs similarity index 58% rename from tests/ui/checked-type-alias/auxiliary/eager.rs rename to tests/ui/checked-type-alias/auxiliary/unchecked.rs index 8793a1701ec3e..46792602f8867 100644 --- a/tests/ui/checked-type-alias/auxiliary/eager.rs +++ b/tests/ui/checked-type-alias/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-alias/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-alias/bad-free-alias-type.rs diff --git a/tests/ui/checked-type-alias/bad-lazy-type-alias.stderr b/tests/ui/checked-type-alias/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-alias/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-alias/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/extern-crate-has-lazy-type-aliases.locally_lazy.stderr b/tests/ui/checked-type-alias/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_lazy.stderr rename to tests/ui/checked-type-alias/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_lazy.stderr +++ b/tests/ui/checked-type-alias/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_eager.stderr b/tests/ui/checked-type-alias/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_eager.stderr rename to tests/ui/checked-type-alias/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_eager.stderr +++ b/tests/ui/checked-type-alias/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-alias/extern-crate-has-checked-type-aliases.rs b/tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.rs new file mode 100644 index 0000000000000..7d38b3c935549 --- /dev/null +++ b/tests/ui/checked-type-alias/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-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/extern-crate-has-eager-type-aliases.rs b/tests/ui/checked-type-alias/extern-crate-has-unchecked-type-aliases.rs similarity index 61% rename from tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs rename to tests/ui/checked-type-alias/extern-crate-has-unchecked-type-aliases.rs index 7e913b5a667b1..902aa947c44b9 100644 --- a/tests/ui/checked-type-alias/extern-crate-has-eager-type-aliases.rs +++ b/tests/ui/checked-type-alias/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 free alias type 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 free alias type which would -// panic because we don't compute this information for eager type aliases at all. -struct Struct(eager::Alias); +// 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.rs b/tests/ui/checked-type-alias/implied-outlives-bounds.rs index 978efbaa9a9e7..dae138a37192f 100644 --- a/tests/ui/checked-type-alias/implied-outlives-bounds.rs +++ b/tests/ui/checked-type-alias/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 diff --git a/tests/ui/checked-type-alias/leading-where-clause.fixed b/tests/ui/checked-type-alias/leading-where-clause.fixed index 8b681d3bee09d..df554e53d1a29 100644 --- a/tests/ui/checked-type-alias/leading-where-clause.fixed +++ b/tests/ui/checked-type-alias/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-alias/leading-where-clause.rs index 98aa8066c2ea1..7f7eb85083c50 100644 --- a/tests/ui/checked-type-alias/leading-where-clause.rs +++ b/tests/ui/checked-type-alias/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/type-alias/recursive-lazy-type-alias-ice-152633.rs b/tests/ui/checked-type-alias/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-alias/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-alias/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-alias/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-alias/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-alias/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-alias/trailing-where-clause.rs index 08e558306a02b..cafd7f4e7e66f 100644 --- a/tests/ui/checked-type-alias/trailing-where-clause.rs +++ b/tests/ui/checked-type-alias/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-alias/trailing-where-clause.stderr index e87db6a47ae79..88ac1a4427ea3 100644 --- a/tests/ui/checked-type-alias/trailing-where-clause.stderr +++ b/tests/ui/checked-type-alias/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/unused-generic-parameters.fail.stderr b/tests/ui/checked-type-alias/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-alias/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-alias/unused-generic-parameters.rs index 18a65043ef61a..41036b1d8aed6 100644 --- a/tests/ui/checked-type-alias/unused-generic-parameters.rs +++ b/tests/ui/checked-type-alias/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 the strong checked version of 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-alias/use-site-wf.rs index cd10a6c8330d2..fd03a8da9b41d 100644 --- a/tests/ui/checked-type-alias/use-site-wf.rs +++ b/tests/ui/checked-type-alias/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/variance-1.rs b/tests/ui/checked-type-alias/variance-1.rs index 3fb857b8f91bf..672580b930d4a 100644 --- a/tests/ui/checked-type-alias/variance-1.rs +++ b/tests/ui/checked-type-alias/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)] diff --git a/tests/ui/checked-type-alias/variance-1.stderr b/tests/ui/checked-type-alias/variance-1.stderr index 40b59b43910e8..a66c2d4303fdf 100644 --- a/tests/ui/checked-type-alias/variance-1.stderr +++ b/tests/ui/checked-type-alias/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/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/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 From 403a4764005374b0a02103b2ec38768d3d34bc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 18 Oct 2026 18:56:37 +0200 Subject: [PATCH 25/27] Replace "LTA" with "CTA" --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 8 ++++---- .../unused-generic-arguments-not-wfchecked.rs | 8 ++++---- tests/ui/checked-type-alias/unused-generic-parameters.rs | 2 +- tests/ui/checked-type-alias/variance-1.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) 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/tests/ui/checked-type-alias/unused-generic-arguments-not-wfchecked.rs b/tests/ui/checked-type-alias/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-alias/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.rs b/tests/ui/checked-type-alias/unused-generic-parameters.rs index 41036b1d8aed6..210bb5606f256 100644 --- a/tests/ui/checked-type-alias/unused-generic-parameters.rs +++ b/tests/ui/checked-type-alias/unused-generic-parameters.rs @@ -5,7 +5,7 @@ // 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 CTA! +// 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) diff --git a/tests/ui/checked-type-alias/variance-1.rs b/tests/ui/checked-type-alias/variance-1.rs index 672580b930d4a..0c46fd2b15644 100644 --- a/tests/ui/checked-type-alias/variance-1.rs +++ b/tests/ui/checked-type-alias/variance-1.rs @@ -30,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>>, From fe64545250b1ae47382e7ea0b0183f706979c116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 18 Oct 2026 19:09:16 +0200 Subject: [PATCH 26/27] Rename `tests/ui/checked-type-alias` to `tests/ui/checked-type-aliases` in accordance with the corresponding feature name, `checked_type_aliases`. --- tests/ui/README.md | 2 +- .../auto-trait-impls.rs | 0 .../auto-trait-impls.stderr | 0 .../auxiliary/checked.rs | 0 .../auxiliary/unchecked.rs | 0 .../bad-free-alias-type.rs | 0 .../bad-free-alias-type.stderr | 0 .../coerce-behind-lazy.rs | 0 .../constrained-late-bound-regions.rs | 0 .../constrained-params-in-impl.rs | 0 .../deep-expansion.rs | 0 .../def-site-body-wf.rs | 0 .../def-site-body-wf.stderr | 0 .../def-site-param-defaults-wf.rs | 0 .../def-site-param-defaults-wf.stderr | 0 .../def-site-predicates-wf.rs | 0 .../def-site-predicates-wf.stderr | 0 .../enum-variant.rs | 0 ...extern-crate-has-checked-type-aliases.locally_checked.stderr | 0 ...tern-crate-has-checked-type-aliases.locally_unchecked.stderr | 0 .../extern-crate-has-checked-type-aliases.rs | 0 .../extern-crate-has-unchecked-type-aliases.rs | 0 .../implied-outlives-bounds.neg.stderr | 0 .../implied-outlives-bounds.rs | 0 .../inherent-impls-conflicting.rs | 0 .../inherent-impls-conflicting.stderr | 0 .../inherent-impls-not-nominal.rs | 0 .../inherent-impls-not-nominal.stderr | 0 .../inherent-impls-overflow.current.stderr | 0 .../inherent-impls-overflow.next.stderr | 0 .../inherent-impls-overflow.rs | 0 .../inherent-impls.rs | 0 .../leading-where-clause.fixed | 0 .../leading-where-clause.rs | 0 .../leading-where-clause.stderr | 0 .../opaq-ty-collection-infinite-recur.rs | 0 .../opaq-ty-collection-infinite-recur.stderr | 0 .../recursive-type-alias-in-const-projection.rs | 0 .../recursive-type-alias-in-const-projection.stderr | 0 .../trailing-where-clause.rs | 0 .../trailing-where-clause.stderr | 0 .../type-alias-bounds-are-enforced.rs | 0 .../unconstrained-late-bound-regions.rs | 0 .../unconstrained-late-bound-regions.stderr | 0 .../unconstrained-params-in-impl-due-to-overflow.rs | 0 .../unconstrained-params-in-impl-due-to-overflow.stderr | 0 .../unconstrained-params-in-impl.rs | 0 .../unconstrained-params-in-impl.stderr | 0 .../unused-generic-arguments-not-wfchecked.next-fixed.stderr | 0 .../unused-generic-arguments-not-wfchecked.rs | 0 .../unused-generic-parameters.fail.stderr | 0 .../unused-generic-parameters.rs | 0 .../{checked-type-alias => checked-type-aliases}/use-site-wf.rs | 0 .../use-site-wf.stderr | 0 .../{checked-type-alias => checked-type-aliases}/variance-0.rs | 0 .../{checked-type-alias => checked-type-aliases}/variance-1.rs | 0 .../variance-1.stderr | 0 .../variance-overflow.rs | 0 .../variance-overflow.stderr | 0 .../variance-unused-param-through-alias-chain.rs | 0 .../variance-unused-param-through-alias-chain.stderr | 0 61 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/{checked-type-alias => checked-type-aliases}/auto-trait-impls.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/auto-trait-impls.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/auxiliary/checked.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/auxiliary/unchecked.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/bad-free-alias-type.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/bad-free-alias-type.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/coerce-behind-lazy.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/constrained-late-bound-regions.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/constrained-params-in-impl.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/deep-expansion.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/def-site-body-wf.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/def-site-body-wf.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/def-site-param-defaults-wf.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/def-site-param-defaults-wf.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/def-site-predicates-wf.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/def-site-predicates-wf.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/enum-variant.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/extern-crate-has-checked-type-aliases.locally_checked.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/extern-crate-has-checked-type-aliases.locally_unchecked.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/extern-crate-has-checked-type-aliases.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/extern-crate-has-unchecked-type-aliases.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/implied-outlives-bounds.neg.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/implied-outlives-bounds.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-conflicting.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-conflicting.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-not-nominal.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-not-nominal.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-overflow.current.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-overflow.next.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls-overflow.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/inherent-impls.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/leading-where-clause.fixed (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/leading-where-clause.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/leading-where-clause.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/opaq-ty-collection-infinite-recur.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/opaq-ty-collection-infinite-recur.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/recursive-type-alias-in-const-projection.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/recursive-type-alias-in-const-projection.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/trailing-where-clause.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/trailing-where-clause.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/type-alias-bounds-are-enforced.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unconstrained-late-bound-regions.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unconstrained-late-bound-regions.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unconstrained-params-in-impl-due-to-overflow.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unconstrained-params-in-impl-due-to-overflow.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unconstrained-params-in-impl.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unconstrained-params-in-impl.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unused-generic-arguments-not-wfchecked.next-fixed.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unused-generic-arguments-not-wfchecked.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unused-generic-parameters.fail.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/unused-generic-parameters.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/use-site-wf.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/use-site-wf.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-0.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-1.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-1.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-overflow.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-overflow.stderr (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-unused-param-through-alias-chain.rs (100%) rename tests/ui/{checked-type-alias => checked-type-aliases}/variance-unused-param-through-alias-chain.stderr (100%) 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/checked-type-alias/auto-trait-impls.rs b/tests/ui/checked-type-aliases/auto-trait-impls.rs similarity index 100% rename from tests/ui/checked-type-alias/auto-trait-impls.rs rename to tests/ui/checked-type-aliases/auto-trait-impls.rs 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/checked.rs b/tests/ui/checked-type-aliases/auxiliary/checked.rs similarity index 100% rename from tests/ui/checked-type-alias/auxiliary/checked.rs rename to tests/ui/checked-type-aliases/auxiliary/checked.rs diff --git a/tests/ui/checked-type-alias/auxiliary/unchecked.rs b/tests/ui/checked-type-aliases/auxiliary/unchecked.rs similarity index 100% rename from tests/ui/checked-type-alias/auxiliary/unchecked.rs rename to tests/ui/checked-type-aliases/auxiliary/unchecked.rs diff --git a/tests/ui/checked-type-alias/bad-free-alias-type.rs b/tests/ui/checked-type-aliases/bad-free-alias-type.rs similarity index 100% rename from tests/ui/checked-type-alias/bad-free-alias-type.rs rename to tests/ui/checked-type-aliases/bad-free-alias-type.rs diff --git a/tests/ui/checked-type-alias/bad-free-alias-type.stderr b/tests/ui/checked-type-aliases/bad-free-alias-type.stderr similarity index 100% rename from tests/ui/checked-type-alias/bad-free-alias-type.stderr rename to tests/ui/checked-type-aliases/bad-free-alias-type.stderr 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 100% rename from tests/ui/checked-type-alias/constrained-late-bound-regions.rs rename to tests/ui/checked-type-aliases/constrained-late-bound-regions.rs 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-checked-type-aliases.locally_checked.stderr b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_checked.stderr similarity index 100% rename from tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.locally_checked.stderr rename to tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_checked.stderr diff --git a/tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.locally_unchecked.stderr b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_unchecked.stderr similarity index 100% rename from tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.locally_unchecked.stderr rename to tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.locally_unchecked.stderr diff --git a/tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.rs b/tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.rs similarity index 100% rename from tests/ui/checked-type-alias/extern-crate-has-checked-type-aliases.rs rename to tests/ui/checked-type-aliases/extern-crate-has-checked-type-aliases.rs diff --git a/tests/ui/checked-type-alias/extern-crate-has-unchecked-type-aliases.rs b/tests/ui/checked-type-aliases/extern-crate-has-unchecked-type-aliases.rs similarity index 100% rename from tests/ui/checked-type-alias/extern-crate-has-unchecked-type-aliases.rs rename to tests/ui/checked-type-aliases/extern-crate-has-unchecked-type-aliases.rs 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 100% rename from tests/ui/checked-type-alias/implied-outlives-bounds.rs rename to tests/ui/checked-type-aliases/implied-outlives-bounds.rs 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 100% rename from tests/ui/checked-type-alias/leading-where-clause.fixed rename to tests/ui/checked-type-aliases/leading-where-clause.fixed diff --git a/tests/ui/checked-type-alias/leading-where-clause.rs b/tests/ui/checked-type-aliases/leading-where-clause.rs similarity index 100% rename from tests/ui/checked-type-alias/leading-where-clause.rs rename to tests/ui/checked-type-aliases/leading-where-clause.rs 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/checked-type-alias/recursive-type-alias-in-const-projection.rs b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.rs similarity index 100% rename from tests/ui/checked-type-alias/recursive-type-alias-in-const-projection.rs rename to tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.rs diff --git a/tests/ui/checked-type-alias/recursive-type-alias-in-const-projection.stderr b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr similarity index 100% rename from tests/ui/checked-type-alias/recursive-type-alias-in-const-projection.stderr rename to tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr diff --git a/tests/ui/checked-type-alias/trailing-where-clause.rs b/tests/ui/checked-type-aliases/trailing-where-clause.rs similarity index 100% rename from tests/ui/checked-type-alias/trailing-where-clause.rs rename to tests/ui/checked-type-aliases/trailing-where-clause.rs diff --git a/tests/ui/checked-type-alias/trailing-where-clause.stderr b/tests/ui/checked-type-aliases/trailing-where-clause.stderr similarity index 100% rename from tests/ui/checked-type-alias/trailing-where-clause.stderr rename to tests/ui/checked-type-aliases/trailing-where-clause.stderr 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 100% rename from tests/ui/checked-type-alias/unconstrained-late-bound-regions.rs rename to tests/ui/checked-type-aliases/unconstrained-late-bound-regions.rs 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 100% 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 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 100% rename from tests/ui/checked-type-alias/unused-generic-parameters.fail.stderr rename to tests/ui/checked-type-aliases/unused-generic-parameters.fail.stderr diff --git a/tests/ui/checked-type-alias/unused-generic-parameters.rs b/tests/ui/checked-type-aliases/unused-generic-parameters.rs similarity index 100% rename from tests/ui/checked-type-alias/unused-generic-parameters.rs rename to tests/ui/checked-type-aliases/unused-generic-parameters.rs diff --git a/tests/ui/checked-type-alias/use-site-wf.rs b/tests/ui/checked-type-aliases/use-site-wf.rs similarity index 100% rename from tests/ui/checked-type-alias/use-site-wf.rs rename to tests/ui/checked-type-aliases/use-site-wf.rs 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 100% rename from tests/ui/checked-type-alias/variance-1.rs rename to tests/ui/checked-type-aliases/variance-1.rs diff --git a/tests/ui/checked-type-alias/variance-1.stderr b/tests/ui/checked-type-aliases/variance-1.stderr similarity index 100% rename from tests/ui/checked-type-alias/variance-1.stderr rename to tests/ui/checked-type-aliases/variance-1.stderr 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 From 7594d4722a6acd3490516bd819810a6865fbd6c9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 23 Oct 2026 15:37:36 +0200 Subject: [PATCH 27/27] miri: fix ICE when caller signature is c-variadic but callee is not --- .../rustc_const_eval/src/interpret/call.rs | 20 ++++++++----------- .../rustc_const_eval/src/interpret/stack.rs | 11 ++-------- .../c-variadic-ignored-argument.rs | 0 .../c-variadic-ignored-argument.stderr | 6 +++--- .../c-variadic-mismatch-count.rs | 0 .../c-variadic-mismatch-count.stderr | 2 +- .../c-variadic-mismatch.rs | 1 + .../c-variadic-mismatch.stderr | 2 +- .../function_calls/c-variadic-mismatch2.rs | 14 +++++++++++++ .../c-variadic-mismatch2.stderr | 13 ++++++++++++ .../fail/{ => function_calls}/c-variadic.rs | 0 .../{ => function_calls}/c-variadic.stderr | 8 ++++---- 12 files changed, 47 insertions(+), 30 deletions(-) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic-ignored-argument.rs (100%) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic-ignored-argument.stderr (74%) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic-mismatch-count.rs (100%) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic-mismatch-count.stderr (89%) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic-mismatch.rs (90%) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic-mismatch.stderr (90%) create mode 100644 src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.rs create mode 100644 src/tools/miri/tests/fail/function_calls/c-variadic-mismatch2.stderr rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic.rs (100%) rename src/tools/miri/tests/fail/{ => function_calls}/c-variadic.stderr (73%) 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/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