From 5e2ccb2c7fcc305abf0a41f13d01600388419dc1 Mon Sep 17 00:00:00 2001 From: Luca Versari Date: Mon, 1 Jun 2026 21:34:00 +0200 Subject: [PATCH 01/59] stabilize optimize attribute (size, speed, and none) This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control of optimization levels. --- .../src/attributes/codegen_attrs.rs | 2 +- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/builtin_attrs.rs | 3 +- compiler/rustc_feature/src/unstable.rs | 2 - library/alloc/src/lib.rs | 1 - library/alloctests/lib.rs | 1 - library/core/src/lib.rs | 1 - library/std/src/lib.rs | 1 - .../issues/issue-136329-optnone-noinline.rs | 2 - tests/codegen-llvm/optimize-attr-1.rs | 1 - tests/mir-opt/optimize_none.rs | 2 - tests/rustdoc-json/attrs/optimize.rs | 2 - tests/ui/attributes/args-checked.rs | 1 - tests/ui/attributes/args-checked.stderr | 52 +++--- tests/ui/attributes/malformed-attrs.rs | 1 - tests/ui/attributes/malformed-attrs.stderr | 174 +++++++++--------- tests/ui/attributes/optimize-smoke-test.rs | 2 - tests/ui/attributes/optimize.rs | 9 +- tests/ui/attributes/optimize.stderr | 22 +-- tests/ui/coroutine/other-attribute-on-gen.rs | 1 - ...tation-attribute-allowlist-issue-159015.rs | 1 - ...on-attribute-allowlist-issue-159015.stderr | 16 +- .../feature-gate-optimize_attribute.rs | 15 -- .../feature-gate-optimize_attribute.stderr | 64 ------- 24 files changed, 144 insertions(+), 234 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-optimize_attribute.rs delete mode 100644 tests/ui/feature-gates/feature-gate-optimize_attribute.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index bff7d7ad81cb9..aa12bc5b75566 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -28,7 +28,7 @@ impl SingleAttributeParser for OptimizeParser { Allow(Target::Method(MethodKind::Inherent)), ]); const TEMPLATE: AttributeTemplate = template!(List: &["size", "speed", "none"]); - const STABILITY: AttributeStability = unstable!(optimize_attribute); + const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { let single = cx.expect_single_element_list(args, cx.attr_span)?; diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 37a3594e374ea..3491b02de510e 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -349,6 +349,8 @@ declare_features! ( (accepted, non_modrs_mods, "1.30.0", Some(44660)), /// Allows using multiple nested field accesses in offset_of! (accepted, offset_of_nested, "1.82.0", Some(120140)), + /// Allows using `#[optimize(X)]`. + (accepted, optimize_attribute, "CURRENT_RUSTC_VERSION", Some(54882)), /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883)), /// Allows using `+bundle,+whole-archive` link modifiers with native libs. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index bb35a3281ccdc..ebaa2a8ca7205 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -156,6 +156,7 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ sym::force_target_feature, sym::sanitize, sym::coverage, + sym::optimize, sym::doc, @@ -179,8 +180,6 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ sym::marker, sym::thread_local, sym::no_core, - // RFC 2412 - sym::optimize, sym::ffi_pure, sym::ffi_const, diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index a7138a88ee399..9a4cc2982ff83 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -664,8 +664,6 @@ declare_features! ( (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! (unstable, offset_of_slice, "1.81.0", Some(126151)), - /// Allows using `#[optimize(X)]`. - (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. (unstable, patchable_function_entry, "1.81.0", Some(123115)), /// Experimental features that make `Pin` more ergonomic. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 6bbd8e8617413..e178d9204c988 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -209,7 +209,6 @@ #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] #![feature(negative_impls)] -#![feature(optimize_attribute)] #![feature(rustc_attrs)] #![feature(slice_internals)] #![feature(staged_api)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index eca8444812521..fe438bce08ddf 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -62,7 +62,6 @@ #![feature(const_trait_impl)] #![feature(dropck_eyepatch)] #![feature(min_specialization)] -#![feature(optimize_attribute)] #![feature(prelude_import)] #![feature(rustc_attrs)] #![feature(staged_api)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c215560122022..b0a00e7a8d3f6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -146,7 +146,6 @@ #![feature(must_not_suspend)] #![feature(negative_impls)] #![feature(no_core)] -#![feature(optimize_attribute)] #![feature(pattern_types)] #![feature(pin_macro_internals)] #![feature(prelude_import)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 18ff174af2375..e05f7b2c8085f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -302,7 +302,6 @@ #![feature(must_not_suspend)] #![feature(needs_panic_runtime)] #![feature(negative_impls)] -#![feature(optimize_attribute)] #![feature(prelude_import)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] diff --git a/tests/codegen-llvm/issues/issue-136329-optnone-noinline.rs b/tests/codegen-llvm/issues/issue-136329-optnone-noinline.rs index 57c9e47a4992a..1dd4ee585d6e1 100644 --- a/tests/codegen-llvm/issues/issue-136329-optnone-noinline.rs +++ b/tests/codegen-llvm/issues/issue-136329-optnone-noinline.rs @@ -2,8 +2,6 @@ //@ compile-flags: -Copt-level=3 -#![feature(optimize_attribute)] - #[optimize(none)] pub fn foo() { let _x = 123; diff --git a/tests/codegen-llvm/optimize-attr-1.rs b/tests/codegen-llvm/optimize-attr-1.rs index db6bdcf9a8b90..c4cb8e460476f 100644 --- a/tests/codegen-llvm/optimize-attr-1.rs +++ b/tests/codegen-llvm/optimize-attr-1.rs @@ -3,7 +3,6 @@ //@[SIZE-OPT] compile-flags: -Copt-level=s -Ccodegen-units=1 //@[SPEED-OPT] compile-flags: -Copt-level=3 -Ccodegen-units=1 -#![feature(optimize_attribute)] #![crate_type = "rlib"] // CHECK-LABEL: define{{.*}}i32 @nothing diff --git a/tests/mir-opt/optimize_none.rs b/tests/mir-opt/optimize_none.rs index 657cfd0675503..f21562835f079 100644 --- a/tests/mir-opt/optimize_none.rs +++ b/tests/mir-opt/optimize_none.rs @@ -2,8 +2,6 @@ //@[NO-OPT] compile-flags: -Copt-level=0 //@[SPEED-OPT] compile-flags: -Copt-level=3 -Coverflow-checks=y -#![feature(optimize_attribute)] - #[optimize(none)] pub fn add_noopt() -> i32 { // CHECK-LABEL: fn add_noopt( diff --git a/tests/rustdoc-json/attrs/optimize.rs b/tests/rustdoc-json/attrs/optimize.rs index 5988120ab2f75..eac9aef5912d9 100644 --- a/tests/rustdoc-json/attrs/optimize.rs +++ b/tests/rustdoc-json/attrs/optimize.rs @@ -1,5 +1,3 @@ -#![feature(optimize_attribute)] - //@ is "$.index[?(@.name=='speed')].attrs" '[{"other": "#[attr = Optimize(Speed)]"}]' #[optimize(speed)] pub fn speed() {} diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index 18369acfea034..b9c6769449577 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -1,5 +1,4 @@ #![feature(rustc_attrs)] -#![feature(optimize_attribute)] #![feature(coverage_attribute)] #![feature(custom_test_frameworks)] #![allow(unused_attributes)] diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 54f7b71ab128c..a5e0176ed37a2 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -1,5 +1,5 @@ error[E0565]: malformed `test_runner` attribute input - --> $DIR/args-checked.rs:7:4 + --> $DIR/args-checked.rs:6:4 | LL | #![test_runner(x = 5)] | ^^^^^^^^^^^^-----^ @@ -13,7 +13,7 @@ LL + #![test_runner(path)] | error[E0565]: malformed `test_runner` attribute input - --> $DIR/args-checked.rs:9:4 + --> $DIR/args-checked.rs:8:4 | LL | #![test_runner(x(x,y,z))] | ^^^^^^^^^^^^--------^ @@ -27,7 +27,7 @@ LL + #![test_runner(path)] | error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:12:3 + --> $DIR/args-checked.rs:11:3 | LL | #[inline(always = 5)] | ^^^^^^^----------^ @@ -48,7 +48,7 @@ LL + #[inline(never)] | error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:14:3 + --> $DIR/args-checked.rs:13:3 | LL | #[inline(always(x, y, z))] | ^^^^^^^---------------^ @@ -69,7 +69,7 @@ LL + #[inline(never)] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:16:3 + --> $DIR/args-checked.rs:15:3 | LL | #[instruction_set(arm::a32 = 5)] | ^^^^^^^^^^^^^^^^------------^ @@ -84,7 +84,7 @@ LL + #[instruction_set(set)] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:18:3 + --> $DIR/args-checked.rs:17:3 | LL | #[instruction_set(arm::a32(x, y, z))] | ^^^^^^^^^^^^^^^^-----------------^ @@ -99,7 +99,7 @@ LL + #[instruction_set(set)] | error[E0539]: malformed `optimize` attribute input - --> $DIR/args-checked.rs:20:3 + --> $DIR/args-checked.rs:19:3 | LL | #[optimize(size = 5)] | ^^^^^^^^^--------^ @@ -119,7 +119,7 @@ LL + #[optimize(speed)] | error[E0539]: malformed `optimize` attribute input - --> $DIR/args-checked.rs:22:3 + --> $DIR/args-checked.rs:21:3 | LL | #[optimize(size(x, y, z))] | ^^^^^^^^^-------------^ @@ -139,19 +139,19 @@ LL + #[optimize(speed)] | error: multiple `optimize` attributes - --> $DIR/args-checked.rs:22:1 + --> $DIR/args-checked.rs:21:1 | LL | #[optimize(size(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/args-checked.rs:20:1 + --> $DIR/args-checked.rs:19:1 | LL | #[optimize(size = 5)] | ^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `coverage` attribute input - --> $DIR/args-checked.rs:25:3 + --> $DIR/args-checked.rs:24:3 | LL | #[coverage(off = 5)] | ^^^^^^^^^-------^ @@ -168,7 +168,7 @@ LL + #[coverage(on)] | error[E0539]: malformed `coverage` attribute input - --> $DIR/args-checked.rs:27:3 + --> $DIR/args-checked.rs:26:3 | LL | #[coverage(off(x, y, z))] | ^^^^^^^^^------------^ @@ -185,7 +185,7 @@ LL + #[coverage(on)] | error[E0539]: malformed `rustc_abi` attribute input - --> $DIR/args-checked.rs:29:3 + --> $DIR/args-checked.rs:28:3 | LL | #[rustc_abi(debug = 5)] | ^^^^^^^^^----------- @@ -202,7 +202,7 @@ LL + #[rustc_abi(debug)] | error[E0539]: malformed `rustc_abi` attribute input - --> $DIR/args-checked.rs:31:3 + --> $DIR/args-checked.rs:30:3 | LL | #[rustc_abi(debug(x, y, z))] | ^^^^^^^^^---------------- @@ -219,19 +219,19 @@ LL + #[rustc_abi(debug)] | error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:47:33 + --> $DIR/args-checked.rs:46:33 | LL | #[rustc_allow_const_fn_unstable(x = 5)] | ^^^^^ error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:49:33 + --> $DIR/args-checked.rs:48:33 | LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] | ^^^^^^^^^^ error[E0539]: malformed `used` attribute input - --> $DIR/args-checked.rs:53:3 + --> $DIR/args-checked.rs:52:3 | LL | #[used(always = 5)] | ^^^^^----------^ @@ -251,7 +251,7 @@ LL + #[used(linker)] | error[E0539]: malformed `used` attribute input - --> $DIR/args-checked.rs:55:3 + --> $DIR/args-checked.rs:54:3 | LL | #[used(always(x, y, z))] | ^^^^^---------------^ @@ -271,7 +271,7 @@ LL + #[used(linker)] | error[E0565]: malformed `rustc_must_implement_one_of` attribute input - --> $DIR/args-checked.rs:59:3 + --> $DIR/args-checked.rs:58:3 | LL | #[rustc_must_implement_one_of(eq = 5, neq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^^ @@ -285,7 +285,7 @@ LL + #[rustc_must_implement_one_of(function1, function2, ...)] | error[E0565]: malformed `rustc_must_implement_one_of` attribute input - --> $DIR/args-checked.rs:61:3 + --> $DIR/args-checked.rs:60:3 | LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^ @@ -299,7 +299,7 @@ LL + #[rustc_must_implement_one_of(function1, function2, ...)] | error[E0565]: malformed `rustc_dump_layout` attribute input - --> $DIR/args-checked.rs:67:3 + --> $DIR/args-checked.rs:66:3 | LL | #[rustc_dump_layout(debug = 5)] | ^^^^^^^^^^^^^^^^^^---------^ @@ -307,7 +307,7 @@ LL | #[rustc_dump_layout(debug = 5)] | didn't expect a literal here error[E0565]: malformed `rustc_dump_layout` attribute input - --> $DIR/args-checked.rs:69:3 + --> $DIR/args-checked.rs:68:3 | LL | #[rustc_dump_layout(debug(x, y, z))] | ^^^^^^^^^^^^^^^^^^--------------^ @@ -315,7 +315,7 @@ LL | #[rustc_dump_layout(debug(x, y, z))] | didn't expect a literal here error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)` - --> $DIR/args-checked.rs:37:3 + --> $DIR/args-checked.rs:36:3 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | #[macro_export(local_inner_macros = 5)] = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)` - --> $DIR/args-checked.rs:40:3 + --> $DIR/args-checked.rs:39:3 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -339,7 +339,7 @@ Some errors have detailed explanations: E0539, E0565. For more information about an error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)` - --> $DIR/args-checked.rs:37:3 + --> $DIR/args-checked.rs:36:3 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -350,7 +350,7 @@ LL | #[macro_export(local_inner_macros = 5)] Future breakage diagnostic: error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)` - --> $DIR/args-checked.rs:40:3 + --> $DIR/args-checked.rs:39:3 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 36ad21a54bd51..e8802261eb74f 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -5,7 +5,6 @@ #![feature(allow_internal_unstable)] // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity #![feature(fn_align)] -#![feature(optimize_attribute)] #![feature(dropck_eyepatch)] #![feature(export_stable)] #![allow(incomplete_features)] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 72e7776e09209..adbf66fa48507 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `cfg` attribute input - --> $DIR/malformed-attrs.rs:109:3 + --> $DIR/malformed-attrs.rs:108:3 | LL | #[cfg] | ^^^ expected this to be a list @@ -11,7 +11,7 @@ LL | #[cfg(predicate)] | +++++++++++ error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:111:3 + --> $DIR/malformed-attrs.rs:110:3 | LL | #[cfg_attr] | ^^^^^^^^ expected this to be a list @@ -23,13 +23,13 @@ LL | #[cfg_attr(predicate, attr1, attr2, ...)] | ++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:212:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:179:1 + --> $DIR/malformed-attrs.rs:178:1 | LL | #[allow] | ^^^^^^^^ @@ -45,7 +45,7 @@ LL | #[allow(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:181:1 + --> $DIR/malformed-attrs.rs:180:1 | LL | #[expect] | ^^^^^^^^^ @@ -61,7 +61,7 @@ LL | #[expect(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:182:1 | LL | #[warn] | ^^^^^^^ @@ -77,7 +77,7 @@ LL | #[warn(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:184:1 | LL | #[deny] | ^^^^^^^ @@ -93,7 +93,7 @@ LL | #[deny(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:186:1 | LL | #[forbid] | ^^^^^^^^^ @@ -109,25 +109,25 @@ LL | #[forbid(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: the `proc_macro` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:106:3 + --> $DIR/malformed-attrs.rs:105:3 | LL | #[proc_macro = 18] | ^^^^^^^^^^ error: the `proc_macro_attribute` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:123:3 + --> $DIR/malformed-attrs.rs:122:3 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^ error: the `proc_macro_derive` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:130:3 + --> $DIR/malformed-attrs.rs:129:3 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^ error[E0539]: malformed `windows_subsystem` attribute input - --> $DIR/malformed-attrs.rs:26:4 + --> $DIR/malformed-attrs.rs:25:4 | LL | #![windows_subsystem] | ^^^^^^^^^^^^^^^^^ expected this to be of the form `windows_subsystem = "..."` @@ -141,7 +141,7 @@ LL | #![windows_subsystem = "windows"] | +++++++++++ error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:29:3 + --> $DIR/malformed-attrs.rs:28:3 | LL | #[unsafe(export_name)] | ^^^^^^^^^^^^^^^^^^^ @@ -152,19 +152,19 @@ LL | #[unsafe(export_name = "name")] | ++++++++ error: `rustc_allow_const_fn_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:31:1 + --> $DIR/malformed-attrs.rs:30:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow_internal_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:34:1 + --> $DIR/malformed-attrs.rs:33:1 | LL | #[allow_internal_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `rustc_confusables` attribute input - --> $DIR/malformed-attrs.rs:36:3 + --> $DIR/malformed-attrs.rs:35:3 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^ expected this to be a list @@ -175,7 +175,7 @@ LL | #[rustc_confusables("name1", "name2", ...)] | +++++++++++++++++++++++ error: the `rustc_confusables` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:36:3 + --> $DIR/malformed-attrs.rs:35:3 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL | #[rustc_confusables] = help: the `rustc_confusables` attribute can only be applied to inherent methods error[E0539]: malformed `deprecated` attribute input - --> $DIR/malformed-attrs.rs:39:3 + --> $DIR/malformed-attrs.rs:38:3 | LL | #[deprecated = 5] | ^^^^^^^^^^^^^- @@ -191,7 +191,7 @@ LL | #[deprecated = 5] | expected a string literal here error[E0539]: malformed `rustc_macro_transparency` attribute input - --> $DIR/malformed-attrs.rs:45:3 + --> $DIR/malformed-attrs.rs:44:3 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +206,7 @@ LL | #[rustc_macro_transparency = "transparent"] | +++++++++++++++ error: the `rustc_macro_transparency` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:45:3 + --> $DIR/malformed-attrs.rs:44:3 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ LL | #[rustc_macro_transparency] = help: the `rustc_macro_transparency` attribute can only be applied to macro defs error[E0539]: malformed `repr` attribute input - --> $DIR/malformed-attrs.rs:48:3 + --> $DIR/malformed-attrs.rs:47:3 | LL | #[repr] | ^^^^ expected this to be a list @@ -222,7 +222,7 @@ LL | #[repr] = note: for more information, visit error[E0565]: malformed `rustc_as_ptr` attribute input - --> $DIR/malformed-attrs.rs:50:3 + --> $DIR/malformed-attrs.rs:49:3 | LL | #[rustc_as_ptr = 5] | ^^^^^^^^^^^^^--- @@ -236,7 +236,7 @@ LL + #[rustc_as_ptr] | error[E0539]: malformed `rustc_align` attribute input - --> $DIR/malformed-attrs.rs:55:3 + --> $DIR/malformed-attrs.rs:54:3 | LL | #[rustc_align] | ^^^^^^^^^^^ expected this to be a list @@ -247,7 +247,7 @@ LL | #[rustc_align()] | ++++++++++++++++++++++ error[E0539]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:57:3 + --> $DIR/malformed-attrs.rs:56:3 | LL | #[optimize] | ^^^^^^^^ expected this to be a list @@ -262,7 +262,7 @@ LL | #[optimize(speed)] | +++++++ error[E0805]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:59:3 + --> $DIR/malformed-attrs.rs:58:3 | LL | #[optimize(none, none)] | ^^^^^^^^------------ @@ -282,7 +282,7 @@ LL + #[optimize(speed)] | error[E0805]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:61:3 + --> $DIR/malformed-attrs.rs:60:3 | LL | #[optimize(none, speed)] | ^^^^^^^^------------- @@ -302,7 +302,7 @@ LL + #[optimize(speed)] | error[E0565]: malformed `cold` attribute input - --> $DIR/malformed-attrs.rs:63:3 + --> $DIR/malformed-attrs.rs:62:3 | LL | #[cold = 1] | ^^^^^--- @@ -316,7 +316,7 @@ LL + #[cold] | error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:65:3 + --> $DIR/malformed-attrs.rs:64:3 | LL | #[must_use()] | ^^^^^^^^-- @@ -334,7 +334,7 @@ LL + #[must_use = "reason"] | error[E0565]: malformed `no_mangle` attribute input - --> $DIR/malformed-attrs.rs:67:3 + --> $DIR/malformed-attrs.rs:66:3 | LL | #[no_mangle = 1] | ^^^^^^^^^^--- @@ -348,7 +348,7 @@ LL + #[no_mangle] | error[E0565]: malformed `naked` attribute input - --> $DIR/malformed-attrs.rs:69:3 + --> $DIR/malformed-attrs.rs:68:3 | LL | #[unsafe(naked())] | ^^^^^^^^^^^^--^ @@ -362,7 +362,7 @@ LL + #[unsafe(naked)] | error[E0565]: malformed `track_caller` attribute input - --> $DIR/malformed-attrs.rs:71:3 + --> $DIR/malformed-attrs.rs:70:3 | LL | #[track_caller()] | ^^^^^^^^^^^^-- @@ -376,7 +376,7 @@ LL + #[track_caller] | error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:73:3 + --> $DIR/malformed-attrs.rs:72:3 | LL | #[export_name()] | ^^^^^^^^^^^^^ @@ -388,7 +388,7 @@ LL + #[export_name = "name"] | error[E0805]: malformed `used` attribute input - --> $DIR/malformed-attrs.rs:75:3 + --> $DIR/malformed-attrs.rs:74:3 | LL | #[used()] | ^^^^-- @@ -406,7 +406,7 @@ LL | #[used(linker)] | ++++++ error: the `used` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:75:3 + --> $DIR/malformed-attrs.rs:74:3 | LL | #[used()] | ^^^^ @@ -414,7 +414,7 @@ LL | #[used()] = help: the `used` attribute can only be applied to statics error[E0539]: malformed `crate_name` attribute input - --> $DIR/malformed-attrs.rs:78:3 + --> $DIR/malformed-attrs.rs:77:3 | LL | #[crate_name] | ^^^^^^^^^^ @@ -425,7 +425,7 @@ LL | #[crate_name = "name"] | ++++++++ error[E0539]: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:81:3 + --> $DIR/malformed-attrs.rs:80:3 | LL | #[target_feature] | ^^^^^^^^^^^^^^ expected this to be a list @@ -436,7 +436,7 @@ LL | #[target_feature(enable = "feat1, feat2")] | +++++++++++++++++++++++++ error[E0565]: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:83:3 + --> $DIR/malformed-attrs.rs:82:3 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^--- @@ -450,7 +450,7 @@ LL + #[export_stable] | error[E0539]: malformed `link` attribute input - --> $DIR/malformed-attrs.rs:85:3 + --> $DIR/malformed-attrs.rs:84:3 | LL | #[link] | ^^^^ expected this to be a list @@ -458,7 +458,7 @@ LL | #[link] = note: for more information, visit error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:89:3 + --> $DIR/malformed-attrs.rs:88:3 | LL | #[link_name] | ^^^^^^^^^ @@ -470,7 +470,7 @@ LL | #[link_name = "name"] | ++++++++ error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:93:3 + --> $DIR/malformed-attrs.rs:92:3 | LL | #[link_section] | ^^^^^^^^^^^^ @@ -482,7 +482,7 @@ LL | #[link_section = "name"] | ++++++++ error[E0539]: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:95:3 + --> $DIR/malformed-attrs.rs:94:3 | LL | #[coverage] | ^^^^^^^^ expected this to be a list @@ -495,13 +495,13 @@ LL | #[coverage(on)] | ++++ error[E0539]: malformed `sanitize` attribute input - --> $DIR/malformed-attrs.rs:97:3 + --> $DIR/malformed-attrs.rs:96:3 | LL | #[sanitize] | ^^^^^^^^ expected this to be a list error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:102:3 + --> $DIR/malformed-attrs.rs:101:3 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^---- @@ -515,7 +515,7 @@ LL + #[no_implicit_prelude] | error[E0565]: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:106:3 + --> $DIR/malformed-attrs.rs:105:3 | LL | #[proc_macro = 18] | ^^^^^^^^^^^---- @@ -529,7 +529,7 @@ LL + #[proc_macro] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:113:3 + --> $DIR/malformed-attrs.rs:112:3 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^ expected this to be a list @@ -541,7 +541,7 @@ LL | #[instruction_set(set)] | +++++ error[E0539]: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:115:3 + --> $DIR/malformed-attrs.rs:114:3 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -552,7 +552,7 @@ LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "sect | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0565]: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:118:7 + --> $DIR/malformed-attrs.rs:117:7 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^---- @@ -566,7 +566,7 @@ LL + #[coroutine] || {} | error[E0565]: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:123:3 + --> $DIR/malformed-attrs.rs:122:3 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^---- @@ -580,7 +580,7 @@ LL + #[proc_macro_attribute] | error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:126:3 + --> $DIR/malformed-attrs.rs:125:3 | LL | #[must_use = 1] | ^^^^^^^^^^^- @@ -598,7 +598,7 @@ LL + #[must_use = "reason"] | error[E0539]: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:130:3 + --> $DIR/malformed-attrs.rs:129:3 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^ expected this to be a list @@ -612,7 +612,7 @@ LL | #[proc_macro_derive(TraitName, attributes(name1, name2, ...))] | ++++++++++++++++++++++++++++++++++++++++++ error[E0539]: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:135:3 + --> $DIR/malformed-attrs.rs:134:3 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^-- @@ -628,7 +628,7 @@ LL | #[must_not_suspend(count)] | +++++ error[E0539]: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:137:3 + --> $DIR/malformed-attrs.rs:136:3 | LL | #[cfi_encoding = ""] | ^^^^^^^^^^^^^^^-- @@ -641,7 +641,7 @@ LL | #[cfi_encoding = "encoding"] | ++++++++ error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:156:3 + --> $DIR/malformed-attrs.rs:155:3 | LL | #[marker = 3] | ^^^^^^^--- @@ -655,7 +655,7 @@ LL + #[marker] | error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:158:3 + --> $DIR/malformed-attrs.rs:157:3 | LL | #[fundamental()] | ^^^^^^^^^^^-- @@ -669,7 +669,7 @@ LL + #[fundamental] | error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:166:7 + --> $DIR/malformed-attrs.rs:165:7 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^---^ @@ -683,7 +683,7 @@ LL + #[unsafe(ffi_pure)] | error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:168:7 + --> $DIR/malformed-attrs.rs:167:7 | LL | #[link_ordinal] | ^^^^^^^^^^^^ expected this to be a list @@ -695,7 +695,7 @@ LL | #[link_ordinal(ordinal)] | +++++++++ error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:172:7 + --> $DIR/malformed-attrs.rs:171:7 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^---^ @@ -709,13 +709,13 @@ LL + #[unsafe(ffi_const)] | error[E0539]: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:174:7 + --> $DIR/malformed-attrs.rs:173:7 | LL | #[linkage] | ^^^^^^^ expected this to be of the form `linkage = "..."` error[E0539]: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:189:3 + --> $DIR/malformed-attrs.rs:188:3 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -727,7 +727,7 @@ LL | #[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")] | ++++++++++++++++++++++++++++++++++++++++++++++ error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:191:3 + --> $DIR/malformed-attrs.rs:190:3 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^---- @@ -741,7 +741,7 @@ LL + #[automatically_derived] | error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:199:3 + --> $DIR/malformed-attrs.rs:198:3 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^--- @@ -755,7 +755,7 @@ LL + #[non_exhaustive] | error[E0565]: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:205:3 + --> $DIR/malformed-attrs.rs:204:3 | LL | #[thread_local()] | ^^^^^^^^^^^^-- @@ -769,7 +769,7 @@ LL + #[thread_local] | error[E0565]: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:209:3 + --> $DIR/malformed-attrs.rs:208:3 | LL | #[no_link()] | ^^^^^^^-- @@ -783,7 +783,7 @@ LL + #[no_link] | error[E0539]: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:211:3 + --> $DIR/malformed-attrs.rs:210:3 | LL | #[macro_use = 1] | ^^^^^^^^^^--- @@ -801,7 +801,7 @@ LL + #[macro_use(name1, name2, ...)] | error[E0539]: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:216:3 + --> $DIR/malformed-attrs.rs:215:3 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^---- @@ -818,7 +818,7 @@ LL + #[macro_export(local_inner_macros)] | error[E0658]: the `allow_internal_unsafe` attribute side-steps the `unsafe_code` lint - --> $DIR/malformed-attrs.rs:218:3 + --> $DIR/malformed-attrs.rs:217:3 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^ @@ -827,7 +827,7 @@ LL | #[allow_internal_unsafe = 1] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:218:3 + --> $DIR/malformed-attrs.rs:217:3 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^--- @@ -841,7 +841,7 @@ LL + #[allow_internal_unsafe] | error: attribute should be applied to `const fn` - --> $DIR/malformed-attrs.rs:31:1 + --> $DIR/malformed-attrs.rs:30:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -853,7 +853,7 @@ LL | | } | |_- not a `const fn` error: valid forms for the attribute are `doc = "doc comment"`, `doc(alias)`, `doc(auto_cfg)`, `doc(cfg)`, `doc(hidden)`, `doc(html_favicon_url)`, `doc(html_logo_url)`, `doc(html_no_source)`, `doc(html_playground_url)`, `doc(html_root_url)`, `doc(inline)`, `doc(issue_tracker_base_url)`, `doc(masked)`, `doc(no_inline)`, `doc(notable_trait)`, and `doc(test)` - --> $DIR/malformed-attrs.rs:41:3 + --> $DIR/malformed-attrs.rs:40:3 | LL | #[doc] | ^^^ @@ -865,13 +865,13 @@ LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ error: valid forms for the attribute are `doc = "doc comment"`, `doc(alias)`, `doc(auto_cfg)`, `doc(cfg)`, `doc(hidden)`, `doc(html_favicon_url)`, `doc(html_logo_url)`, `doc(html_no_source)`, `doc(html_playground_url)`, `doc(html_root_url)`, `doc(inline)`, `doc(issue_tracker_base_url)`, `doc(masked)`, `doc(no_inline)`, `doc(notable_trait)`, and `doc(test)` - --> $DIR/malformed-attrs.rs:43:3 + --> $DIR/malformed-attrs.rs:42:3 | LL | #[doc()] | ^^^^^ error: valid forms for the attribute are `inline`, `inline(always)`, and `inline(never)` - --> $DIR/malformed-attrs.rs:52:3 + --> $DIR/malformed-attrs.rs:51:3 | LL | #[inline = 5] | ^^^^^^^^^^ @@ -881,13 +881,13 @@ LL | #[inline = 5] = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/malformed-attrs.rs:78:1 + --> $DIR/malformed-attrs.rs:77:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ | note: this attribute does not have an `!`, which means it is applied to this function - --> $DIR/malformed-attrs.rs:117:1 + --> $DIR/malformed-attrs.rs:116:1 | LL | / fn test() { LL | | #[coroutine = 63] || {} @@ -897,7 +897,7 @@ LL | | } = note: requested on the command line with `-W unused-attributes` warning: the `link` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:85:3 + --> $DIR/malformed-attrs.rs:84:3 | LL | #[link] | ^^^^ @@ -906,7 +906,7 @@ LL | #[link] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: the `link_name` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:89:3 + --> $DIR/malformed-attrs.rs:88:3 | LL | #[link_name] | ^^^^^^^^^ @@ -915,7 +915,7 @@ LL | #[link_name] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: valid forms for the attribute are `ignore` and `ignore = "reason"` - --> $DIR/malformed-attrs.rs:99:3 + --> $DIR/malformed-attrs.rs:98:3 | LL | #[ignore()] | ^^^^^^^^ @@ -924,7 +924,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 warning: the `no_implicit_prelude` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:102:3 + --> $DIR/malformed-attrs.rs:101:3 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^ @@ -933,7 +933,7 @@ LL | #[no_implicit_prelude = 23] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: missing options for `diagnostic::on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:141:1 + --> $DIR/malformed-attrs.rs:140:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -942,7 +942,7 @@ LL | #[diagnostic::on_unimplemented] = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: malformed `diagnostic::on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:143:1 + --> $DIR/malformed-attrs.rs:142:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -950,13 +950,13 @@ LL | #[diagnostic::on_unimplemented = 1] = help: only `message`, `note` and `label` are allowed as options warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:150:1 + --> $DIR/malformed-attrs.rs:149:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the `automatically_derived` attribute cannot be used on modules - --> $DIR/malformed-attrs.rs:191:3 + --> $DIR/malformed-attrs.rs:190:3 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^ @@ -965,7 +965,7 @@ LL | #[automatically_derived = 18] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: valid forms for the attribute are `ignore` and `ignore = "reason"` - --> $DIR/malformed-attrs.rs:225:3 + --> $DIR/malformed-attrs.rs:224:3 | LL | #[ignore = 1] | ^^^^^^^^^^ @@ -974,7 +974,7 @@ LL | #[ignore = 1] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:118:23 + --> $DIR/malformed-attrs.rs:117:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -982,7 +982,7 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:118:23: 118:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:117:23: 117:25}` error: aborting due to 74 previous errors; 8 warnings emitted @@ -990,7 +990,7 @@ Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805 For more information about an error, try `rustc --explain E0308`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `inline`, `inline(always)`, and `inline(never)` - --> $DIR/malformed-attrs.rs:52:3 + --> $DIR/malformed-attrs.rs:51:3 | LL | #[inline = 5] | ^^^^^^^^^^ @@ -1001,7 +1001,7 @@ LL | #[inline = 5] Future breakage diagnostic: error: valid forms for the attribute are `ignore` and `ignore = "reason"` - --> $DIR/malformed-attrs.rs:99:3 + --> $DIR/malformed-attrs.rs:98:3 | LL | #[ignore()] | ^^^^^^^^ @@ -1012,7 +1012,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `ignore` and `ignore = "reason"` - --> $DIR/malformed-attrs.rs:225:3 + --> $DIR/malformed-attrs.rs:224:3 | LL | #[ignore = 1] | ^^^^^^^^^^ diff --git a/tests/ui/attributes/optimize-smoke-test.rs b/tests/ui/attributes/optimize-smoke-test.rs index 9d8e75c4bec5e..d379450fcaad9 100644 --- a/tests/ui/attributes/optimize-smoke-test.rs +++ b/tests/ui/attributes/optimize-smoke-test.rs @@ -1,8 +1,6 @@ //! Basic smoke test for `#[optimize(..)]` attributes. //@ run-pass -#![feature(optimize_attribute)] - #[optimize(speed)] fn optimized_speed() -> i32 { 42 diff --git a/tests/ui/attributes/optimize.rs b/tests/ui/attributes/optimize.rs index f1e07f35e0971..41c716e0e9854 100644 --- a/tests/ui/attributes/optimize.rs +++ b/tests/ui/attributes/optimize.rs @@ -1,4 +1,3 @@ -#![feature(optimize_attribute)] #![feature(stmt_expr_attributes)] #![deny(unused_attributes)] #![allow(dead_code)] @@ -74,3 +73,11 @@ fn inline_conflict_b() {} #[inline(never)] #[optimize(none)] fn inline_conflict_c() {} + +#[optimize(none)] +fn valid_none() {} + +#[optimize(none)] +async fn async_fn_none() { + () +} diff --git a/tests/ui/attributes/optimize.stderr b/tests/ui/attributes/optimize.stderr index db45f96d143c8..5c9ab33a6e590 100644 --- a/tests/ui/attributes/optimize.stderr +++ b/tests/ui/attributes/optimize.stderr @@ -1,5 +1,5 @@ error: the `optimize` attribute cannot be used on structs - --> $DIR/optimize.rs:8:3 + --> $DIR/optimize.rs:7:3 | LL | #[optimize(speed)] | ^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[optimize(speed)] = help: the `optimize` attribute can only be applied to functions error: the `optimize` attribute cannot be used on expressions - --> $DIR/optimize.rs:12:7 + --> $DIR/optimize.rs:11:7 | LL | #[optimize(speed)] | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | #[optimize(speed)] = help: the `optimize` attribute can only be applied to functions error: the `optimize` attribute cannot be used on modules - --> $DIR/optimize.rs:21:3 + --> $DIR/optimize.rs:20:3 | LL | #[optimize(speed)] | ^^^^^^^^ @@ -23,7 +23,7 @@ LL | #[optimize(speed)] = help: the `optimize` attribute can only be applied to functions error: the `optimize` attribute cannot be used on inherent impl blocks - --> $DIR/optimize.rs:24:3 + --> $DIR/optimize.rs:23:3 | LL | #[optimize(speed)] | ^^^^^^^^ @@ -31,7 +31,7 @@ LL | #[optimize(speed)] = help: the `optimize` attribute can only be applied to functions error: the `optimize` attribute cannot be used on required trait methods - --> $DIR/optimize.rs:45:7 + --> $DIR/optimize.rs:44:7 | LL | #[optimize(speed)] | ^^^^^^^^ @@ -39,31 +39,31 @@ LL | #[optimize(speed)] = help: the `optimize` attribute can only be applied to functions with a body error: multiple `optimize` attributes - --> $DIR/optimize.rs:59:1 + --> $DIR/optimize.rs:58:1 | LL | #[optimize(speed)] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/optimize.rs:58:1 + --> $DIR/optimize.rs:57:1 | LL | #[optimize(speed)] | ^^^^^^^^^^^^^^^^^^ error: multiple `optimize` attributes - --> $DIR/optimize.rs:63:1 + --> $DIR/optimize.rs:62:1 | LL | #[optimize(size)] | ^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/optimize.rs:62:1 + --> $DIR/optimize.rs:61:1 | LL | #[optimize(speed)] | ^^^^^^^^^^^^^^^^^^ error: `#[optimize(none)]` cannot be used with `#[inline]` attributes - --> $DIR/optimize.rs:66:1 + --> $DIR/optimize.rs:65:1 | LL | #[optimize(none)] | ^^^^^^^^^^^^^^^^^ `#[optimize(none)]` here @@ -71,7 +71,7 @@ LL | #[inline] | --------- `#[inline]` here error: `#[optimize(none)]` cannot be used with `#[inline]` attributes - --> $DIR/optimize.rs:71:1 + --> $DIR/optimize.rs:70:1 | LL | #[inline(always)] | ----------------- `#[inline]` here diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs index e13a0abcbfd63..8fb428fd81b25 100644 --- a/tests/ui/coroutine/other-attribute-on-gen.rs +++ b/tests/ui/coroutine/other-attribute-on-gen.rs @@ -1,7 +1,6 @@ //@ edition: 2024 //@ run-pass #![feature(gen_blocks)] -#![feature(optimize_attribute)] #![feature(async_iterator)] #![allow(dead_code)] diff --git a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs index d27ea2a833e0f..e486b8620b777 100644 --- a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs +++ b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs @@ -6,7 +6,6 @@ #![feature(coverage_attribute)] #![feature(extern_item_impls)] -#![feature(optimize_attribute)] #![feature(sanitize)] #[eii] diff --git a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr index af9673099f20f..bda69efd5630d 100644 --- a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr +++ b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr @@ -1,5 +1,5 @@ error: `#[foo]` is not allowed to have `#[no_mangle]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:46:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:45:1 | LL | #[foo] | ------ `#[foo]` is not allowed to have `#[no_mangle]` @@ -7,7 +7,7 @@ LL | #[unsafe(no_mangle)] | ^^^^^^^^^^^^^^^^^^^^ error: `#[baz]` is not allowed to have `#[export_name]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:54:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:53:1 | LL | #[baz] | ------ `#[baz]` is not allowed to have `#[export_name]` @@ -15,7 +15,7 @@ LL | #[unsafe(export_name = "qux")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[quux]` is not allowed to have `#[link_section]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:62:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:61:1 | LL | #[quux] | ------- `#[quux]` is not allowed to have `#[link_section]` @@ -23,7 +23,7 @@ LL | #[unsafe(link_section = "__TEXT,__text")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[grault]` is not allowed to have `#[track_caller]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:70:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:69:1 | LL | #[grault] | --------- `#[grault]` is not allowed to have `#[track_caller]` @@ -31,7 +31,7 @@ LL | #[track_caller] | ^^^^^^^^^^^^^^^ error: `#[naked_attr]` is not allowed to have `#[naked]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:78:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:77:1 | LL | #[naked_attr] | ------------- `#[naked_attr]` is not allowed to have `#[naked]` @@ -39,7 +39,7 @@ LL | #[unsafe(naked)] | ^^^^^^^^^^^^^^^^ error: `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:88:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:87:1 | LL | #[multiple_invalid_attrs] | ------------------------- `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` @@ -47,7 +47,7 @@ LL | #[unsafe(no_mangle)] | ^^^^^^^^^^^^^^^^^^^^ error: `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:90:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:89:1 | LL | #[multiple_invalid_attrs] | ------------------------- `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` @@ -56,7 +56,7 @@ LL | #[track_caller] | ^^^^^^^^^^^^^^^ error: `#[static_eii]` is not allowed to have `#[used]` - --> $DIR/implementation-attribute-allowlist-issue-159015.rs:98:1 + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:97:1 | LL | #[static_eii] | ------------- `#[static_eii]` is not allowed to have `#[used]` diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs deleted file mode 100644 index b1da0dca9c85b..0000000000000 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![crate_type="rlib"] - -#[optimize(size)] //~ ERROR the `optimize` attribute is an experimental feature -fn size() {} - -#[optimize(speed)] //~ ERROR the `optimize` attribute is an experimental feature -fn speed() {} - -#[optimize(none)] //~ ERROR the `optimize` attribute is an experimental feature -fn none() {} - -#[optimize(banana)] -//~^ ERROR the `optimize` attribute is an experimental feature -//~| ERROR malformed `optimize` attribute input [E0539] -fn not_known() {} diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr deleted file mode 100644 index 67f0b832866ca..0000000000000 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr +++ /dev/null @@ -1,64 +0,0 @@ -error[E0658]: the `optimize` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:3:3 - | -LL | #[optimize(size)] - | ^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `optimize` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:6:3 - | -LL | #[optimize(speed)] - | ^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `optimize` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:9:3 - | -LL | #[optimize(none)] - | ^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `optimize` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:12:3 - | -LL | #[optimize(banana)] - | ^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0539]: malformed `optimize` attribute input - --> $DIR/feature-gate-optimize_attribute.rs:12:3 - | -LL | #[optimize(banana)] - | ^^^^^^^^^------^ - | | - | valid arguments are `size`, `speed` or `none` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[optimize(banana)] -LL + #[optimize(none)] - | -LL - #[optimize(banana)] -LL + #[optimize(size)] - | -LL - #[optimize(banana)] -LL + #[optimize(speed)] - | - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0539, E0658. -For more information about an error, try `rustc --explain E0539`. From 3b3ba8b5e45eddb8456d3ab3eb82d0d41e32ea77 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Aug 2026 09:33:14 +0200 Subject: [PATCH 02/59] peel_transparent_wrappers only works on non-1ZST --- compiler/rustc_abi/src/layout/ty.rs | 19 +++++++++++++++---- compiler/rustc_codegen_llvm/src/va_arg.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/place.rs | 6 ++++-- .../rustc_codegen_ssa/src/traits/builder.rs | 13 +++++++------ .../src/hir_ty_lowering/cmse.rs | 2 +- compiler/rustc_target/src/callconv/s390x.rs | 3 ++- compiler/rustc_target/src/callconv/wasm.rs | 7 +++++-- compiler/rustc_target/src/callconv/x86.rs | 3 ++- 8 files changed, 38 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index b8928aecf0cc5..0bc8f7e13ee2c 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -247,15 +247,25 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { where Ty: TyAbiInterface<'a, C> + Copy, { - let base = self.peel_transparent_wrappers(cx); + // FIXME: Peeling the wrappers above would not work correctly if we are a 1-ZST. So we make + // `#[rustc_pass_indirectly_in_non_rustic_abis]` a NOP on 1-ZST. In the future, + // `non_1zst_field` should become `non_trivial_abi_field` and + // `#[rustc_pass_indirectly_in_non_rustic_abis]` should make a type have non-trivial ABI. + if self.is_1zst() { + return false; + } + + let base = self.peel_transparent_wrappers_from_non_1zst(cx); Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(base) } /// Recursively peel away transparent wrappers, returning the inner value. + /// Will not peel anything if `self` is a 1-ZST! Callers need to either check + /// that the result is not a 1-ZST, or have separate logic for that. /// /// The return value is not `repr(transparent)` and/or does /// not have a non-1zst field. - pub fn peel_transparent_wrappers(mut self, cx: &C) -> Self + pub fn peel_transparent_wrappers_from_non_1zst(mut self, cx: &C) -> Self where Ty: TyAbiInterface<'a, C> + Copy, { @@ -321,12 +331,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { where Ty: TyAbiInterface<'a, C> + Copy, { - let complex = self.peel_transparent_wrappers(cx); + // We're checking for scalar repr below which excludes 1-ZST. + let complex = self.peel_transparent_wrappers_from_non_1zst(cx); if !Ty::is_complex_number_lang_item(complex, cx) { return None; } - let component = complex.field(cx, 0).peel_transparent_wrappers(cx); + let component = complex.field(cx, 0).peel_transparent_wrappers_from_non_1zst(cx); let BackendRepr::Scalar(scalar) = component.backend_repr else { return None; diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 2a02df05f26f5..c6bce87252d16 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -308,7 +308,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( let va_list_addr = list.immediate(); // Peel off any newtype wrappers. - let layout = layout.peel_transparent_wrappers(bx.cx); + let layout = layout.peel_transparent_wrappers_from_non_1zst(bx.cx); // Rust does not currently support any powerpc softfloat targets. let target = &bx.cx.tcx.sess.target; @@ -561,7 +561,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( // #[repr(C)] // struct Foo([Empty; 8], i32); // ``` - let layout = layout.peel_transparent_wrappers(bx.cx); + let layout = layout.peel_transparent_wrappers_from_non_1zst(bx.cx); // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed // in the registers. If not go to step 7. diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 02e125fd31717..486b13cafdccb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -112,7 +112,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - if layout.peel_transparent_wrappers(bx).deref().is_scalable_vector() { + // Scalable vector are never 1-ZST. FIXME: is that correct? + if layout.peel_transparent_wrappers_from_non_1zst(bx).deref().is_scalable_vector() { Self::alloca_scalable(bx, layout) } else { Self::alloca_size(bx, layout.size, layout) @@ -159,7 +160,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout: TyAndLayout<'tcx>, ) -> Self { PlaceValue::new_sized( - bx.alloca_with_ty(layout.peel_transparent_wrappers(bx)), + // FIXME why is this peeling at all? And why is it redoing the work the caller just did? + bx.alloca_with_ty(layout.peel_transparent_wrappers_from_non_1zst(bx)), layout.align.abi, ) .with_type(layout) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index b7b694922bcfa..afe3aec13d279 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -539,12 +539,13 @@ pub trait BuilderMethods<'a, 'tcx>: let tt = tt.add_indirection(); let fnc_tree = FncTree { args: vec![tt.clone(), tt], ret: TypeTree::new() }; let bytes = self.const_usize(layout.size.bytes()); - let bytes = if layout.peel_transparent_wrappers(self).ty.is_scalable_vector() { - let vscale = self.vscale(self.type_i64()); - self.mul(vscale, bytes) - } else { - bytes - }; + let bytes = + if layout.peel_transparent_wrappers_from_non_1zst(self).ty.is_scalable_vector() { + let vscale = self.vscale(self.type_i64()); + self.mul(vscale, bytes) + } else { + bytes + }; self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags, Some(fnc_tree)); } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 675e7e3c2a02a..530706b0653db 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -170,7 +170,7 @@ fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, layout: TyAndLayout<'tc // Accept (transparently wrapped) scalar 64-bit primitives. matches!( - layout.peel_transparent_wrappers(&cx).ty.kind(), + layout.peel_transparent_wrappers_from_non_1zst(&cx).ty.kind(), ty::Int(ty::IntTy::I64) | ty::Uint(ty::UintTy::U64) | ty::Float(ty::FloatTy::F64) ) } diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs index 0d29bc658b56d..146cfc3c6ee65 100644 --- a/compiler/rustc_target/src/callconv/s390x.rs +++ b/compiler/rustc_target/src/callconv/s390x.rs @@ -15,7 +15,8 @@ where // Contrary to X86, trailing padding is allowed on s390x. loop { - layout = layout.peel_transparent_wrappers(cx); + // We're only looking for scalar types that are non-ZST. + layout = layout.peel_transparent_wrappers_from_non_1zst(cx); return match layout.backend_repr { BackendRepr::Scalar(scalar) => match scalar.primitive() { diff --git a/compiler/rustc_target/src/callconv/wasm.rs b/compiler/rustc_target/src/callconv/wasm.rs index 3706caa6b6f44..237bc2960b17e 100644 --- a/compiler/rustc_target/src/callconv/wasm.rs +++ b/compiler/rustc_target/src/callconv/wasm.rs @@ -11,7 +11,8 @@ where C: HasDataLayout, { // The base case: a single scalar is a singleton scalar. - if !(layout.is_aggregate() || layout.peel_transparent_wrappers(cx).is_enum()) { + // We're only looking for scalar types that are non-ZST. + if !(layout.is_aggregate() || layout.peel_transparent_wrappers_from_non_1zst(cx).is_enum()) { let BackendRepr::Scalar(scalar) = layout.backend_repr else { return None; }; @@ -62,7 +63,9 @@ where { // An enum that is represented as an integer is not an aggregate to rust, but may still // need to be passed as one if its variants have any (even ZST) fields. - if !(val.layout.is_aggregate() || val.layout.peel_transparent_wrappers(cx).is_enum()) { + if !(val.layout.is_aggregate() + || val.layout.peel_transparent_wrappers_from_non_1zst(cx).is_enum()) + { return false; } diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 3476f41e3bc75..147d499d2c76b 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -15,7 +15,8 @@ where let outer_size = layout.layout.size(); loop { - layout = layout.peel_transparent_wrappers(cx); + // We're only looking for scalar types that are non-ZST. + layout = layout.peel_transparent_wrappers_from_non_1zst(cx); return match layout.backend_repr { BackendRepr::Scalar(scalar) => match scalar.primitive() { From 6e8947a4a5e790d360cc561167b1b84f0eaa288a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 4 Sep 2026 16:14:36 +0200 Subject: [PATCH 03/59] leave a comment for some sve hacks --- compiler/rustc_codegen_ssa/src/mir/place.rs | 6 ++++-- compiler/rustc_codegen_ssa/src/traits/builder.rs | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 486b13cafdccb..1412f64ac2179 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -112,7 +112,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - // Scalable vector are never 1-ZST. FIXME: is that correct? + // FIXME(rustc_scalable_vector/stdarch_aarch64_sve): Scalable vectors aren't actually sized, + // but we pretend they are. Here we have to hack around that. if layout.peel_transparent_wrappers_from_non_1zst(bx).deref().is_scalable_vector() { Self::alloca_scalable(bx, layout) } else { @@ -160,7 +161,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout: TyAndLayout<'tcx>, ) -> Self { PlaceValue::new_sized( - // FIXME why is this peeling at all? And why is it redoing the work the caller just did? + // FIXME why is this peeling at all? The LLVM type should be the same for the + // transparent wrapper and the inner type. bx.alloca_with_ty(layout.peel_transparent_wrappers_from_non_1zst(bx)), layout.align.abi, ) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index afe3aec13d279..473a856b05efe 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -540,6 +540,8 @@ pub trait BuilderMethods<'a, 'tcx>: let fnc_tree = FncTree { args: vec![tt.clone(), tt], ret: TypeTree::new() }; let bytes = self.const_usize(layout.size.bytes()); let bytes = + // FIXME(rustc_scalable_vector/stdarch_aarch64_sve): Scalable vectors aren't + // actually sized, but we pretend they are. Here we have to hack around that. if layout.peel_transparent_wrappers_from_non_1zst(self).ty.is_scalable_vector() { let vscale = self.vscale(self.type_i64()); self.mul(vscale, bytes) From 5e9dca942e3199372459d3d9f043aa53b31df518 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Fri, 25 Sep 2026 17:52:52 +0000 Subject: [PATCH 04/59] cache results in improper_ctypes lint --- .../rustc_lint/src/types/improper_ctypes.rs | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index e7fa0fe2960db..2d42e9fdd05da 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use std::iter; use std::ops::ControlFlow; @@ -5,10 +6,11 @@ use bitflags::bitflags; use rustc_abi::VariantIdx; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{DiagMessage, msg}; +use rustc_hashes::Hash128; use rustc_hir::def::CtorKind; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, AmbigArg}; -use rustc_lint_defs::{declare_lint, declare_lint_pass}; +use rustc_lint_defs::{declare_lint, impl_lint_pass}; use rustc_middle::ty::{ self, Adt, AdtDef, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, Unnormalized, @@ -131,7 +133,25 @@ declare_lint! { "Structs do not follow the power alignment rule under repr(C)" } -declare_lint_pass!(ImproperCTypesLint => [ +/// Remembers types we already checked and found FFI-safe, so we don't check the +/// same type again every time it shows up in another function. +/// We only remember "safe" types, never "unsafe" ones. That way we never need to +/// keep the actual type around, just a fingerprint of it. +#[derive(Default)] +pub(crate) struct ImproperCTypesLint { + /// A fingerprint of the type, not the type itself. Uses a big 128-bit + /// fingerprint (not a smaller 64-bit one) so two different types can't + /// accidentally get treated as the same one. + known_safe: RefCell>, +} + +impl<'tcx> ImproperCTypesLint { + fn cache_key(cx: &LateContext<'tcx>, ty: Ty<'tcx>, flags: RootUseFlags) -> (Hash128, u8) { + (cx.tcx.type_id_hash(ty), flags.bits()) + } +} + +impl_lint_pass!(ImproperCTypesLint => [ IMPROPER_CTYPES, IMPROPER_CTYPES_DEFINITIONS, USES_POWER_ALIGNMENT @@ -1102,8 +1122,16 @@ impl<'tcx> ImproperCTypesLint { fn check_foreign_static(&mut self, cx: &LateContext<'tcx>, id: hir::OwnerId, span: Span) { let ty = cx.tcx.type_of(id).instantiate_identity(); + let state = VisitorState::static_entry_point(); + let key = Self::cache_key(cx, ty.skip_norm_wip(), state.root_use_flags); + if self.known_safe.borrow().contains(&key) { + return; + } let mut visitor = ImproperCTypesVisitor::new(cx, ty, CItemKind::Declaration); - let ffi_res = visitor.check_type(VisitorState::static_entry_point(), ty); + let ffi_res = visitor.check_type(state, ty); + if matches!(ffi_res, FfiResult::FfiSafe) { + self.known_safe.borrow_mut().insert(key); + } self.process_ffi_result(cx, span, ffi_res, CItemKind::Declaration); } @@ -1119,19 +1147,32 @@ impl<'tcx> ImproperCTypesLint { let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { - let input_ty = Unnormalized::new_wip(*input_ty); let state = VisitorState::fn_entry_point(fn_mode, FnPos::Arg); + let key = Self::cache_key(cx, *input_ty, state.root_use_flags); + if self.known_safe.borrow().contains(&key) { + continue; + } + let input_ty = Unnormalized::new_wip(*input_ty); let mut visitor = ImproperCTypesVisitor::new(cx, input_ty, fn_mode); let ffi_res = visitor.check_type(state, input_ty); + if matches!(ffi_res, FfiResult::FfiSafe) { + self.known_safe.borrow_mut().insert(key); + } self.process_ffi_result(cx, input_hir.span, ffi_res, fn_mode); } if let hir::FnRetTy::Return(ret_hir) = decl.output { - let output_ty = Unnormalized::new_wip(sig.output()); let state = VisitorState::fn_entry_point(fn_mode, FnPos::Ret); - let mut visitor = ImproperCTypesVisitor::new(cx, output_ty, fn_mode); - let ffi_res = visitor.check_type(state, output_ty); - self.process_ffi_result(cx, ret_hir.span, ffi_res, fn_mode); + let key = Self::cache_key(cx, sig.output(), state.root_use_flags); + if !self.known_safe.borrow().contains(&key) { + let output_ty = Unnormalized::new_wip(sig.output()); + let mut visitor = ImproperCTypesVisitor::new(cx, output_ty, fn_mode); + let ffi_res = visitor.check_type(state, output_ty); + if matches!(ffi_res, FfiResult::FfiSafe) { + self.known_safe.borrow_mut().insert(key); + } + self.process_ffi_result(cx, ret_hir.span, ffi_res, fn_mode); + } } } From 30c3ff8f16ac656692ebaab7dafbbfa78d704be5 Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Thu, 1 Oct 2026 13:12:58 +0200 Subject: [PATCH 05/59] abby: ensure forall where clause lhs is alias, placeholder, or lifetime --- .../rustc_hir_analysis/src/check/wfcheck.rs | 61 +++++++++++--- compiler/rustc_hir_analysis/src/collect.rs | 80 ++++++++----------- .../test-infra-fails-properly.rs | 16 +++- .../test-infra-fails-properly.stderr | 46 ++++++++--- .../test-infra-works.rs | 8 ++ 5 files changed, 141 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index dc4b6a6fd319c..6b72f6fd90605 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2423,15 +2423,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_test_binder_forall(&self, forall: TestBinderForall<'tcx>) { self.infcx.enter_forall(forall.binder, |body| { let u = self.infcx.universe(); - let mut builder = TransitiveRelationBuilder::default(); - for &(r1, r2) in &body.region_outlives { - builder.add(r1, r2); - } - // Deliberately unelaborated: the assumptions of a `forall` are exactly the ones - // written down in the test, no extra ones hidden behind the scenes. - let assumptions = ty::region_constraint::Assumptions::new_unelaborated( + let assumptions = self.build_test_binder_assumptions( + forall.span, body.type_outlives, - builder.freeze(), + body.region_outlives, ); self.infcx.insert_placeholder_assumptions(u, assumptions); self.check_test_binder_body(body.value); @@ -2449,6 +2444,52 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { }); } + fn build_test_binder_assumptions( + &self, + span: Span, + type_outlives: Vec>, + region_outlives: Vec>, + ) -> ty::region_constraint::Assumptions> { + for clause in &type_outlives { + if !matches!( + clause.skip_binder().0.kind(), + ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) + ) { + let mut err = self.tcx().dcx().struct_span_err( + span, + "the lhs of a forall where clause must be \ + an alias, placeholder, or lifetime", + ); + err.note(format!("the bad clause is {clause}")); + err.emit(); + } + } + let ty = type_outlives.iter().map(|c| c.map_bound(ty::ClauseKind::TypeOutlives)); + let reg = + region_outlives.iter().map(|&c| ty::Binder::dummy(ty::ClauseKind::RegionOutlives(c))); + let explicit_clauses: Vec> = + ty.chain(reg).map(|c| c.upcast(self.tcx())).collect(); + for elaborated in ty::elaborate::elaborate(self.tcx(), explicit_clauses.iter().copied()) { + if !explicit_clauses.contains(&elaborated) { + let mut err = self.tcx().dcx().struct_span_err( + span, + "all implied bounds of clauses must themselves be \ + included in the where clause of a forall", + ); + err.note(format!("missing clause is {elaborated}")); + err.emit(); + } + } + + let mut builder = TransitiveRelationBuilder::default(); + for &ty::OutlivesClause(r1, r2) in ®ion_outlives { + builder.add(r1, r2); + } + // Deliberately unelaborated: the assumptions of a `forall` are exactly the ones + // written down in the test, no extra ones hidden behind the scenes. + ty::region_constraint::Assumptions::new_unelaborated(type_outlives, builder.freeze()) + } + #[instrument(level = "debug", skip(self))] fn check_test_binder_region_constraints( &self, @@ -2742,6 +2783,6 @@ pub(crate) struct WithWhereClauses<'tcx, T> { // The where clauses on the forall. These eventually will probably get stored inside // `ty::Binder` but they're here for now. - pub type_outlives: Vec>>>, - pub region_outlives: Vec<(ty::Region<'tcx>, ty::Region<'tcx>)>, + pub type_outlives: Vec>, + pub region_outlives: Vec>, } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 1cd1fc356ca7d..9bac109664c6a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -372,62 +372,50 @@ impl<'tcx> ItemCtxt<'tcx> { TestBinderExists { span: exists.span, binder } } - // FIXME: this is likely too basic, and we'll want to evolve/make this more advanced over time. - // For example, right now, if the user writes `forall<'a> where Foo<'a>: 'b`, that's not gonna - // work - that should be destructured into `where 'a: 'b`, whether by hand (and checked it was - // indeed done so, via compiler) or automatically by the test framework, unsure, but something. fn lower_test_binder_assumptions( &self, predicate: &hir::WherePredicate<'tcx>, - type_outlives: &mut Vec>>>, - region_outlives: &mut Vec<(ty::Region<'tcx>, ty::Region<'tcx>)>, + type_outlives: &mut Vec>, + region_outlives: &mut Vec>, ) { + fn outlives_bounds<'tcx>( + dcx: DiagCtxtHandle<'tcx>, + bounds: hir::GenericBounds<'tcx>, + ) -> impl Iterator { + bounds.iter().flat_map(move |bound| match *bound { + rustc_hir::GenericBound::Trait(poly_trait_ref) => { + dcx.span_err( + poly_trait_ref.span, + "trait bounds aren't supported in forall where clauses", + ); + None + } + rustc_hir::GenericBound::Outlives(lifetime) => Some(lifetime), + rustc_hir::GenericBound::Use(_, span) => { + dcx.span_err(span, "use bounds aren't supported in forall where clauses"); + None + } + }) + } match predicate.kind { hir::WherePredicateKind::BoundPredicate(p) => { let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); let ty = self.lower_ty(p.bounded_ty); - for bound in p.bounds { - match bound { - hir::GenericBound::Trait(poly_trait_ref) => { - self.dcx() - .span_err(poly_trait_ref.span, "trait bounds aren't supported yet"); - } - hir::GenericBound::Outlives(lifetime) => { - let region = self - .lowerer() - .lower_lifetime(lifetime, RegionInferReason::RegionPredicate); - let binder = ty::Binder::bind_with_vars( - ty::OutlivesClause(ty, region), - bound_vars, - ); - type_outlives.push(binder); - } - hir::GenericBound::Use(_, span) => { - self.dcx().span_err(*span, "use bounds aren't supported yet"); - } - } + for lifetime in outlives_bounds(self.dcx(), p.bounds) { + let region = + self.lowerer().lower_lifetime(lifetime, RegionInferReason::RegionPredicate); + let binder = + ty::Binder::bind_with_vars(ty::OutlivesClause(ty, region), bound_vars); + type_outlives.push(binder); } } - hir::WherePredicateKind::RegionPredicate(predicate) => { - let lhs = self - .lowerer() - .lower_lifetime(predicate.lifetime, RegionInferReason::RegionPredicate); - for bound in predicate.bounds { - match bound { - hir::GenericBound::Trait(poly_trait_ref) => { - self.dcx() - .span_err(poly_trait_ref.span, "trait bounds aren't supported yet"); - } - hir::GenericBound::Outlives(lifetime) => { - let rhs = self - .lowerer() - .lower_lifetime(lifetime, RegionInferReason::RegionPredicate); - region_outlives.push((lhs, rhs)); - } - hir::GenericBound::Use(_, span) => { - self.dcx().span_err(*span, "use bounds aren't supported yet"); - } - } + hir::WherePredicateKind::RegionPredicate(p) => { + let lhs = + self.lowerer().lower_lifetime(p.lifetime, RegionInferReason::RegionPredicate); + for lifetime in outlives_bounds(self.dcx(), p.bounds) { + let rhs = + self.lowerer().lower_lifetime(lifetime, RegionInferReason::RegionPredicate); + region_outlives.push(ty::OutlivesClause(lhs, rhs)); } } } diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs index 97629627ad556..42a334900f769 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs @@ -1,6 +1,8 @@ //@ compile-flags: -Zassumptions-on-binders #![feature(test_binder_constraints)] -#![expect(incomplete_features)] + +trait Trait<'a> {} +struct Struct<'a>(&'a u32); core::test_binder_constraints! { impl<'a, 'b> { @@ -27,8 +29,6 @@ core::test_binder_constraints! { } } -trait Trait<'a> {} - core::test_binder_constraints! { impl<'a> { dyn for<'b> Trait<'b>: 'a, @@ -47,6 +47,7 @@ core::test_binder_constraints! { impl<'a> { forall where T: 'a { //~^ ERROR only lifetime parameters can be used in this context + //~| ERROR the lhs of a forall where clause must be an alias, placeholder, or lifetime T: 'a, //~^ ERROR the lhs of a ty outlives must be a placeholder } @@ -74,4 +75,13 @@ core::test_binder_constraints! { } } +core::test_binder_constraints! { + impl<'a> { + forall<'b> where Struct<'a>: 'b { + //~^ ERROR the lhs of a forall where clause must be an alias, placeholder, or lifetime + //~| ERROR all implied bounds of clauses must themselves be included in the where clause of a forall + } + } +} + fn main() {} diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr index ab025b0e0b9d6..4513fd1fdb2c7 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr @@ -1,11 +1,11 @@ error: expected one of `!`, `(`, `+`, `::`, `:`, or `<`, found `{` - --> $DIR/test-infra-fails-properly.rs:15:20 + --> $DIR/test-infra-fails-properly.rs:17:20 | LL | forall { } | ^ expected one of `!`, `(`, `+`, `::`, `:`, or `<` error: expected one of `!`, `(`, `+`, `::`, `:`, or `<`, found `{` - --> $DIR/test-infra-fails-properly.rs:24:20 + --> $DIR/test-infra-fails-properly.rs:26:20 | LL | forall { } | ^ expected one of `!`, `(`, `+`, `::`, `:`, or `<` @@ -27,7 +27,7 @@ LL | forall where T: 'a { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: higher-ranked lifetime bound could not be satisfied - --> $DIR/test-infra-fails-properly.rs:7:9 + --> $DIR/test-infra-fails-properly.rs:9:9 | LL | 'a: 'b | ^^^^^^ @@ -39,10 +39,18 @@ LL | dyn for<'b> Trait<'b>: 'a, | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: it is a (dyn for<'b> Trait<'b> + 'static) - = note: and here it is `Debug`ged :3 dyn [Binder { value: Trait(Trait<'b>), bound_vars: [Region(BrNamed(DefId(0:11 ~ test_infra_fails_properly[2377]::{test_binder_constraints#1}::'b)))] }] + 'static + = note: and here it is `Debug`ged :3 dyn [Binder { value: Trait(Trait<'b>), bound_vars: [Region(BrNamed(DefId(0:15 ~ test_infra_fails_properly[2377]::{test_binder_constraints#1}::'b)))] }] + 'static + +error: the lhs of a forall where clause must be an alias, placeholder, or lifetime + --> $DIR/test-infra-fails-properly.rs:48:9 + | +LL | forall where T: 'a { + | ^^^^^^ + | + = note: the bad clause is {type error}: 'a error: the lhs of a ty outlives must be a placeholder - --> $DIR/test-infra-fails-properly.rs:50:13 + --> $DIR/test-infra-fails-properly.rs:51:13 | LL | T: 'a, | ^^^^^ @@ -51,33 +59,49 @@ LL | T: 'a, = note: and here it is `Debug`ged :3 {type error} error: forall expect clause failed - --> $DIR/test-infra-fails-properly.rs:63:17 + --> $DIR/test-infra-fails-properly.rs:64:17 | LL | 'b: 'c, | ^^^^^^ | note: constraint from here - --> $DIR/test-infra-fails-properly.rs:58:9 + --> $DIR/test-infra-fails-properly.rs:59:9 | LL | forall<'a> where 'b: 'a { | ^^^^^^ = note: expected: RegionOutlives( 'b/#0, 'c/#1, - $DIR/test-infra-fails-properly.rs:63:17: 63:23 (#0), + $DIR/test-infra-fails-properly.rs:64:17: 64:23 (#0), ) = note: actual: RegionOutlives( 'c/#1, 'static, - $DIR/test-infra-fails-properly.rs:58:9: 58:15 (#0), + $DIR/test-infra-fails-properly.rs:59:9: 59:15 (#0), ) error: bound type test binder constraint must be alias (it's a AliasTyOutlivesViaEnv) - --> $DIR/test-infra-fails-properly.rs:72:15 + --> $DIR/test-infra-fails-properly.rs:73:15 | LL | for<> T: 'a | ^ -error: aborting due to 9 previous errors +error: the lhs of a forall where clause must be an alias, placeholder, or lifetime + --> $DIR/test-infra-fails-properly.rs:80:9 + | +LL | forall<'b> where Struct<'a>: 'b { + | ^^^^^^ + | + = note: the bad clause is for<'b> Struct<'a>: 'b + +error: all implied bounds of clauses must themselves be included in the where clause of a forall + --> $DIR/test-infra-fails-properly.rs:80:9 + | +LL | forall<'b> where Struct<'a>: 'b { + | ^^^^^^ + | + = note: missing clause is for<'b> 'a: 'b + +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/assumptions_on_binders/test-infra-works.rs b/tests/ui/assumptions_on_binders/test-infra-works.rs index d8d64d1aac255..2979478e76007 100644 --- a/tests/ui/assumptions_on_binders/test-infra-works.rs +++ b/tests/ui/assumptions_on_binders/test-infra-works.rs @@ -82,4 +82,12 @@ core::test_binder_constraints! { } } +core::test_binder_constraints! { + impl { + forall<'a> where TParam: 'a { }, + forall<'a> where TParam::Assoc: 'a { }, + forall<'a, T> where T: 'a { }, + } +} + fn main() {} From fa3bfde261f62d8a8acb3dd0da2133ca0e92164d Mon Sep 17 00:00:00 2001 From: xonx4l Date: Thu, 1 Oct 2026 16:44:49 +0530 Subject: [PATCH 06/59] fix build errors --- Cargo.lock | 1 + compiler/rustc_lint/Cargo.toml | 1 + compiler/rustc_lint/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5e57835c9cfef..5183eb88a437f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4334,6 +4334,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_infer", diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index a672f242449e4..5fc0b333eccad 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -14,6 +14,7 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 95033707cf110..9a91e14fbdcb0 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -238,7 +238,7 @@ late_lint_methods!( ImplTraitOvercaptures: ImplTraitOvercaptures, ImplicitAutorefs: ImplicitAutorefs, ImplicitProvenanceCasts: ImplicitProvenanceCasts, - ImproperCTypesLint: ImproperCTypesLint, + ImproperCTypesLint: ImproperCTypesLint::default(), ImproperGpuKernelLint: ImproperGpuKernelLint, InteriorMutableConsts: InteriorMutableConsts, InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, From e733825c4edceedea78a8d970854ad008e04a360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 8 Dec 2025 01:06:35 +0000 Subject: [PATCH 07/59] On name resolution error in parameter list, suggest possible `const` typo --- compiler/rustc_resolve/src/late.rs | 32 +++++++++++++++++-- .../rustc_resolve/src/late/diagnostics.rs | 8 ++++- .../ui/const-generics/const-argument-typo.rs | 11 +++++++ .../const-generics/const-argument-typo.stderr | 31 ++++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 tests/ui/const-generics/const-argument-typo.rs create mode 100644 tests/ui/const-generics/const-argument-typo.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 781109d6c8658..f146a6ffeaa00 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -445,6 +445,8 @@ pub(crate) enum AliasPossibility { pub(crate) enum PathSource<'a, 'ast, 'ra> { /// Type paths `Path`. Type, + /// Type or constant in a `PathSegment` argument. + TypeParam, /// Trait paths in bounds or impls. Trait(AliasPossibility), /// Expression paths `path`, with optional parent context. @@ -480,6 +482,7 @@ impl PathSource<'_, '_, '_> { fn namespace(self) -> Namespace { match self { PathSource::Type + | PathSource::TypeParam | PathSource::Trait(_) | PathSource::Struct(_) | PathSource::DefineOpaques @@ -499,6 +502,7 @@ impl PathSource<'_, '_, '_> { fn defer_to_typeck(self) -> bool { match self { PathSource::Type + | PathSource::TypeParam | PathSource::Expr(..) | PathSource::Pat | PathSource::Struct(_) @@ -519,6 +523,7 @@ impl PathSource<'_, '_, '_> { match &self { PathSource::DefineOpaques => "type alias or associated type with opaqaue types", PathSource::Type => "type", + PathSource::TypeParam => "type or constant", PathSource::Trait(_) => "trait", PathSource::Pat => "unit struct, unit variant or constant", PathSource::Struct(_) => "struct, variant or union type", @@ -596,6 +601,28 @@ impl PathSource<'_, '_, '_> { | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } ), + PathSource::TypeParam => matches!( + res, + Res::Def( + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Trait + | DefKind::TraitAlias + | DefKind::TyAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::OpaqueTy + | DefKind::AnonConst + | DefKind::AssocConst + | DefKind::Const + | DefKind::ConstParam + | DefKind::ForeignTy, + _, + ) | Res::PrimTy(..) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } + ), PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)), PathSource::Trait(AliasPossibility::Maybe) => { matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) @@ -668,8 +695,8 @@ impl PathSource<'_, '_, '_> { match (self, has_unexpected_resolution) { (PathSource::Trait(_), true) => E0404, (PathSource::Trait(_), false) => E0405, - (PathSource::Type | PathSource::DefineOpaques, true) => E0573, - (PathSource::Type | PathSource::DefineOpaques, false) => E0425, + (PathSource::Type | PathSource::DefineOpaques | PathSource::TypeParam, true) => E0573, + (PathSource::Type | PathSource::DefineOpaques | PathSource::TypeParam, false) => E0425, (PathSource::Struct(_), true) => E0574, (PathSource::Struct(_), false) => E0422, (PathSource::Expr(..), true) @@ -2272,6 +2299,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type + | PathSource::TypeParam | PathSource::PreciseCapturingArg(..) | PathSource::ReturnTypeNotation | PathSource::Macro diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b2061cd9d9d91..cb878e17ea7cc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1412,13 +1412,19 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_typo( &mut self, err: &mut Diag<'_>, - source: PathSource<'_, 'ast, 'ra>, + mut source: PathSource<'_, 'ast, 'ra>, path: &[Segment], following_seg: Option<&Segment>, span: Span, base_error: &BaseError, suggested_candidates: FxHashSet, ) -> bool { + if self.diag_metadata.currently_processing_generic_args + && matches!(source, PathSource::Type) + { + source = PathSource::TypeParam; + } + let is_expected = &|res| source.is_expected(res); let ident_span = path.last().map_or(span, |ident| ident.ident.span); diff --git a/tests/ui/const-generics/const-argument-typo.rs b/tests/ui/const-generics/const-argument-typo.rs new file mode 100644 index 0000000000000..06ce5a7fb93a4 --- /dev/null +++ b/tests/ui/const-generics/const-argument-typo.rs @@ -0,0 +1,11 @@ +// Typo of `CONST` to `CONS`. #149660 + +const CONST: usize = 0; + +fn foo() {} + +fn main() { + foo::(); + //~^ ERROR cannot find type `CONS` in this scope + //~| ERROR unresolved item provided when a constant was expected +} diff --git a/tests/ui/const-generics/const-argument-typo.stderr b/tests/ui/const-generics/const-argument-typo.stderr new file mode 100644 index 0000000000000..053fd4c1fe8d9 --- /dev/null +++ b/tests/ui/const-generics/const-argument-typo.stderr @@ -0,0 +1,31 @@ +error[E0425]: cannot find type `CONS` in this scope + --> $DIR/const-argument-typo.rs:8:11 + | +LL | foo::(); + | ^^^^ not found in this scope + | +note: similarly named constant `CONST` defined here + --> $DIR/const-argument-typo.rs:3:1 + | +LL | const CONST: usize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: a constant with a similar name exists + | +LL | foo::(); + | + + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-argument-typo.rs:8:11 + | +LL | foo::(); + | ^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | foo::<{ CONS }>(); + | + + + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0425, E0747. +For more information about an error, try `rustc --explain E0425`. From 80f91df6bcd94b60d2ac1c1335818cc3e3164dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 8 Dec 2025 20:29:33 +0000 Subject: [PATCH 08/59] Do not emit E0747 if a resolve error was already emitted --- .../src/hir_ty_lowering/generics.rs | 6 +- .../error_reporting/infer/need_type_info.rs | 29 ++- .../assoc_const_as_type_argument.rs | 1 - .../assoc_const_as_type_argument.stderr | 16 +- .../const-arg-in-const-arg.min.stderr | 111 +++------- .../const-generics/const-arg-in-const-arg.rs | 4 - .../ui/const-generics/const-argument-typo.rs | 3 +- .../const-generics/const-argument-typo.stderr | 20 +- .../const-generics/const-generic-function.rs | 1 - .../const-generic-function.stderr | 22 +- .../early/invalid-const-arguments.rs | 8 +- .../early/invalid-const-arguments.stderr | 58 +---- tests/ui/const-generics/invalid-enum.rs | 3 - tests/ui/const-generics/invalid-enum.stderr | 41 +--- tests/ui/const-generics/paren.rs | 1 - tests/ui/const-generics/paren.stderr | 20 +- .../generics/generics-gen-args-errors.rs | 2 - .../generics/generics-gen-args-errors.stderr | 204 ++++++++---------- .../missing-items/missing-type-parameter2.rs | 2 - .../missing-type-parameter2.stderr | 37 +--- 20 files changed, 189 insertions(+), 400 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 9eda20fa0d9c4..08ddab617c385 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -68,9 +68,9 @@ fn generic_arg_mismatch_err( ) => match path.res { Res::Err => { add_braces_suggestion(arg, &mut err); - return err - .with_primary_message("unresolved item provided when a constant was expected") - .emit_err(); + err.primary_message("unresolved item provided when a constant was expected"); + // A resolve error will already have been emitted pointing at this. + return err.delay_as_bug(); } Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index d812dee1cc6b5..e4cf2a40bd3fc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -570,6 +570,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { body_from_expansion, span, ); + let delay_as_bug = match kind { + InferSourceKind::ClosureArg { kind, .. } if let PatKind::Err(_) = kind => { + // We will have already emitted an error about this pattern. + true + } + InferSourceKind::GenericArg { hir_id, argument_index, .. } + if let hir::Node::PathSegment(segment) = self.tcx.hir_node(hir_id) + && let Some(args) = segment.args + && let Some(hir::GenericArg::Type(ty)) = args.args.get(argument_index) + && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind + && let Res::Err = path.res => + { + // We have already emitted a name resolution error. + true + } + _ => false, + }; let mut err = match error_code { TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired { @@ -598,8 +615,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }), }; *err.long_ty_path() = long_ty_path; - if let InferSourceKind::ClosureArg { kind: PatKind::Err(_), .. } = kind { - // We will have already emitted an error about this pattern. + if delay_as_bug { + // We have already emitted an earlier more relevant error. err.downgrade_to_delayed_bug(); } err @@ -890,6 +907,7 @@ struct InsertableGenericArgs<'tcx> { generics_def_id: DefId, def_id: DefId, have_turbofish: bool, + hir_id: HirId, } /// A visitor which searches for the "best" spot to use in the inference error. @@ -1158,6 +1176,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { generics_def_id: def_id, def_id, have_turbofish, + hir_id: expr.hir_id, } }; return Box::new(insertable.into_iter()); @@ -1197,6 +1216,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { generics_def_id, def_id: path.res.def_id(), have_turbofish, + hir_id: path.segments.last().unwrap().hir_id, } }; @@ -1217,6 +1237,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { generics_def_id, def_id: res.def_id(), have_turbofish, + hir_id: segment.hir_id, }) }) .chain(last_segment_using_path_data) @@ -1250,6 +1271,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { generics_def_id: def_id, def_id, have_turbofish: false, + hir_id: segment.hir_id, }) }; @@ -1408,6 +1430,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { generics_def_id, def_id, have_turbofish, + hir_id, } = args; let generics = tcx.generics_of(generics_def_id); if let Some(argument_index) = generics @@ -1446,7 +1469,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { def_id, generic_args, have_turbofish, - hir_id: expr.hir_id, + hir_id, }, }); } diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.rs b/tests/ui/const-generics/assoc_const_as_type_argument.rs index 44a43fdbbfb94..2eb5705c95bf0 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.rs +++ b/tests/ui/const-generics/assoc_const_as_type_argument.rs @@ -7,7 +7,6 @@ fn bar() {} fn foo() { bar::<::ASSOC>(); //~^ ERROR: cannot find associated type `ASSOC` in trait `Trait` - //~| ERROR: unresolved item provided when a constant was expected } fn main() {} diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.stderr b/tests/ui/const-generics/assoc_const_as_type_argument.stderr index 6060031b78eb1..33a3b01b57610 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.stderr +++ b/tests/ui/const-generics/assoc_const_as_type_argument.stderr @@ -6,18 +6,6 @@ LL | bar::<::ASSOC>(); | = note: an associated constant named `Trait::ASSOC` exists in another namespace -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/assoc_const_as_type_argument.rs:8:11 - | -LL | bar::<::ASSOC>(); - | ^^^^^^^^^^^^^^^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | bar::<{ ::ASSOC }>(); - | + + - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0575, E0747. -For more information about an error, try `rustc --explain E0575`. +For more information about this error, try `rustc --explain E0575`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index 102afaa9a0da2..d5b5ad9d8dc15 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -19,7 +19,7 @@ LL | let _: [u8; bar::()]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:17:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -29,7 +29,7 @@ LL | let _: [u8; faz::<'a>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:20:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -39,7 +39,7 @@ LL | let _: [u8; baz::<'a>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:20:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -49,7 +49,7 @@ LL | let _: [u8; faz::<'b>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:23:23 + --> $DIR/const-arg-in-const-arg.rs:22:23 | LL | let _: [u8; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -59,7 +59,7 @@ LL | let _: [u8; baz::<'b>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; bar::()]; | ^ cannot perform const operation using `N` @@ -69,7 +69,7 @@ LL | let _ = [0; bar::()]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:29:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -79,7 +79,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:29:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -89,7 +89,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:32:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -99,7 +99,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:34:23 + --> $DIR/const-arg-in-const-arg.rs:32:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -109,7 +109,7 @@ LL | let _ = [0; baz::<'b>(&())]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:33:24 | LL | let _: Foo<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -119,7 +119,7 @@ LL | let _: Foo<{ foo::() }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:36:24 + --> $DIR/const-arg-in-const-arg.rs:34:24 | LL | let _: Foo<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -129,7 +129,7 @@ LL | let _: Foo<{ bar::() }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:38:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -139,7 +139,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -149,7 +149,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:41:24 + --> $DIR/const-arg-in-const-arg.rs:38:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -159,7 +159,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:43:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -169,7 +169,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:41:27 | LL | let _ = Foo::<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ foo::() }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:45:27 + --> $DIR/const-arg-in-const-arg.rs:42:27 | LL | let _ = Foo::<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -189,7 +189,7 @@ LL | let _ = Foo::<{ bar::() }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:47:27 + --> $DIR/const-arg-in-const-arg.rs:43:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -199,7 +199,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:45:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -209,7 +209,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:50:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -219,7 +219,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:52:27 + --> $DIR/const-arg-in-const-arg.rs:48:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -228,19 +228,8 @@ LL | let _ = Foo::<{ baz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:16:23 - | -LL | let _: [u8; bar::()]; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: [u8; bar::<{ N }>()]; - | + + - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:17:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ @@ -252,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:20:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ @@ -264,7 +253,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: constant expression depends on a generic parameter - --> $DIR/const-arg-in-const-arg.rs:25:17 + --> $DIR/const-arg-in-const-arg.rs:24:17 | LL | let _ = [0; foo::()]; | ^^^^^^^^^^ @@ -272,26 +261,15 @@ LL | let _ = [0; foo::()]; = note: this may fail depending on what value the parameter takes error: constant expression depends on a generic parameter - --> $DIR/const-arg-in-const-arg.rs:25:13 + --> $DIR/const-arg-in-const-arg.rs:24:13 | LL | let _ = [0; foo::()]; | ^^^^^^^^^^^^^^^ | = note: this may fail depending on what value the parameter takes -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:27:23 - | -LL | let _ = [0; bar::()]; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _ = [0; bar::<{ N }>()]; - | + + - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:29:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -303,7 +281,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:32:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -314,19 +292,8 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:36:24 - | -LL | let _: Foo<{ bar::() }>; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: Foo<{ bar::<{ N }>() }>; - | + + - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:38:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -338,7 +305,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:41:24 + --> $DIR/const-arg-in-const-arg.rs:38:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -349,19 +316,8 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:45:27 - | -LL | let _ = Foo::<{ bar::() }>; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _ = Foo::<{ bar::<{ N }>() }>; - | + + - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:47:27 + --> $DIR/const-arg-in-const-arg.rs:43:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -373,7 +329,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:50:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -384,7 +340,6 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: aborting due to 37 previous errors +error: aborting due to 33 previous errors -Some errors have detailed explanations: E0747, E0794. -For more information about an error, try `rustc --explain E0747`. +For more information about this error, try `rustc --explain E0794`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs index 0e1c6552edf1e..31dfe7969894b 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.rs +++ b/tests/ui/const-generics/const-arg-in-const-arg.rs @@ -14,7 +14,6 @@ struct Foo; fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::()]; //[min]~ ERROR generic parameters may not let _: [u8; bar::()]; //[min]~ ERROR generic parameters may not - //[min]~^ ERROR unresolved item provided when a constant was expected let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -25,7 +24,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = [0; foo::()]; //[min]~ ERROR constant expression depends on a generic parameter //[min]~^ ERROR constant expression depends on a generic parameter let _ = [0; bar::()]; //[min]~ ERROR generic parameters may not - //[min]~^ ERROR unresolved item provided when a constant was expected let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -34,7 +32,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = [0; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not let _: Foo<{ foo::() }>; //[min]~ ERROR generic parameters may not let _: Foo<{ bar::() }>; //[min]~ ERROR generic parameters may not - //[min]~^ ERROR unresolved item provided when a constant was expected let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not @@ -43,7 +40,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ foo::() }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ bar::() }>; //[min]~ ERROR generic parameters may not - //[min]~^ ERROR unresolved item provided when a constant was expected let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not diff --git a/tests/ui/const-generics/const-argument-typo.rs b/tests/ui/const-generics/const-argument-typo.rs index 06ce5a7fb93a4..089126c92e162 100644 --- a/tests/ui/const-generics/const-argument-typo.rs +++ b/tests/ui/const-generics/const-argument-typo.rs @@ -5,7 +5,6 @@ const CONST: usize = 0; fn foo() {} fn main() { - foo::(); + foo::(); //~^ ERROR cannot find type `CONS` in this scope - //~| ERROR unresolved item provided when a constant was expected } diff --git a/tests/ui/const-generics/const-argument-typo.stderr b/tests/ui/const-generics/const-argument-typo.stderr index 053fd4c1fe8d9..567124c1b1f9b 100644 --- a/tests/ui/const-generics/const-argument-typo.stderr +++ b/tests/ui/const-generics/const-argument-typo.stderr @@ -1,7 +1,7 @@ error[E0425]: cannot find type `CONS` in this scope --> $DIR/const-argument-typo.rs:8:11 | -LL | foo::(); +LL | foo::(); | ^^^^ not found in this scope | note: similarly named constant `CONST` defined here @@ -11,21 +11,9 @@ LL | const CONST: usize = 0; | ^^^^^^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists | -LL | foo::(); +LL | foo::(); | + -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-argument-typo.rs:8:11 - | -LL | foo::(); - | ^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | foo::<{ CONS }>(); - | + + - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0425, E0747. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/const-generic-function.rs b/tests/ui/const-generics/const-generic-function.rs index dcd16b4b722ea..4db564e42d1cb 100644 --- a/tests/ui/const-generics/const-generic-function.rs +++ b/tests/ui/const-generics/const-generic-function.rs @@ -14,7 +14,6 @@ const FOO: i32 = 3; fn main() { foo::(); //~ ERROR cannot find type `baz` in this scope - //~^ ERROR unresolved item provided when a constant was expected foo::(); //~ ERROR expected type, found `1` foo::(); //~ ERROR expected type, found `1` foo::(); //~ ERROR expected type, found `2` diff --git a/tests/ui/const-generics/const-generic-function.stderr b/tests/ui/const-generics/const-generic-function.stderr index 57f0af450a0f8..b7ea270f7d1c3 100644 --- a/tests/ui/const-generics/const-generic-function.stderr +++ b/tests/ui/const-generics/const-generic-function.stderr @@ -1,5 +1,5 @@ error: expected type, found `1` - --> $DIR/const-generic-function.rs:18:19 + --> $DIR/const-generic-function.rs:17:19 | LL | foo::(); | ^ expected type @@ -10,7 +10,7 @@ LL | foo::<{ bar(bar(1, 1), bar(1, 1)) }>(); | + + error: expected type, found `1` - --> $DIR/const-generic-function.rs:19:15 + --> $DIR/const-generic-function.rs:18:15 | LL | foo::(); | ^ expected type @@ -21,7 +21,7 @@ LL | foo::<{ bar(1, 1) }>(); | + + error: expected type, found `2` - --> $DIR/const-generic-function.rs:20:20 + --> $DIR/const-generic-function.rs:19:20 | LL | foo::(); | ^ expected type @@ -39,18 +39,6 @@ LL | foo::(); | = note: a function named `baz` exists in another namespace -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-generic-function.rs:16:11 - | -LL | foo::(); - | ^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | foo::<{ baz() }>(); - | + + - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0573, E0747. -For more information about an error, try `rustc --explain E0573`. +For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/const-generics/early/invalid-const-arguments.rs b/tests/ui/const-generics/early/invalid-const-arguments.rs index 82cc948129a67..e8a96457bf04d 100644 --- a/tests/ui/const-generics/early/invalid-const-arguments.rs +++ b/tests/ui/const-generics/early/invalid-const-arguments.rs @@ -3,8 +3,7 @@ struct A; trait Foo {} impl Foo for A {} -//~^ ERROR cannot find const `N` in this scope -//~| ERROR unresolved item provided when a constant was expected +//~^ ERROR cannot find const `N` struct B; impl Foo for B {} @@ -12,16 +11,13 @@ impl Foo for B {} struct C; impl Foo for C {} -//~^ ERROR cannot find const `T` in this scope -//~| ERROR unresolved item provided when a constant was expected +//~^ ERROR cannot find const `T` struct D; impl Foo for D {} //~^ ERROR cannot find const `E` in this scope -//~| ERROR unresolved item provided when a constant was expected //~| ERROR cannot find const `X` in this scope //~| ERROR cannot find const `P` in this scope struct R; impl Foo for D {} //~^ ERROR cannot find const `Q` in this scope -//~| ERROR unresolved item provided when a constant was expected diff --git a/tests/ui/const-generics/early/invalid-const-arguments.stderr b/tests/ui/const-generics/early/invalid-const-arguments.stderr index 4d8ab68fd71db..fdddebca7cd62 100644 --- a/tests/ui/const-generics/early/invalid-const-arguments.stderr +++ b/tests/ui/const-generics/early/invalid-const-arguments.stderr @@ -13,7 +13,7 @@ LL | impl Foo for A {} | +++++++++++++ error[E0425]: cannot find const `T` in this scope - --> $DIR/invalid-const-arguments.rs:14:32 + --> $DIR/invalid-const-arguments.rs:13:32 | LL | struct C; | ----------- corresponding const parameter on the type defined here @@ -26,7 +26,7 @@ LL | impl Foo for C {} | +++++++++++++ error[E0425]: cannot find const `E` in this scope - --> $DIR/invalid-const-arguments.rs:19:16 + --> $DIR/invalid-const-arguments.rs:17:16 | LL | struct D; | ----------- corresponding const parameter on the type defined here @@ -39,7 +39,7 @@ LL | impl Foo for D {} | +++++++++++++ error[E0425]: cannot find const `X` in this scope - --> $DIR/invalid-const-arguments.rs:19:19 + --> $DIR/invalid-const-arguments.rs:17:19 | LL | struct D; | ----------- corresponding const parameter on the type defined here @@ -52,7 +52,7 @@ LL | impl Foo for D {} | +++++++++++++ error[E0425]: cannot find const `P` in this scope - --> $DIR/invalid-const-arguments.rs:19:22 + --> $DIR/invalid-const-arguments.rs:17:22 | LL | struct D; | ------------ corresponding const parameter on the type defined here @@ -65,7 +65,7 @@ LL | impl Foo for D {} | ++++++++++++++ error[E0425]: cannot find const `Q` in this scope - --> $DIR/invalid-const-arguments.rs:25:46 + --> $DIR/invalid-const-arguments.rs:22:46 | LL | struct D; | ----------- corresponding const parameter on the type defined here @@ -78,19 +78,8 @@ help: you might have meant to introduce a const parameter `Q` on the impl LL | impl Foo for D {} | +++++++++++++ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-const-arguments.rs:5:16 - | -LL | impl Foo for A {} - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | impl Foo for A<{ N }> {} - | + + - error[E0747]: type provided when a constant was expected - --> $DIR/invalid-const-arguments.rs:10:19 + --> $DIR/invalid-const-arguments.rs:9:19 | LL | impl Foo for B {} | ^ @@ -101,40 +90,7 @@ LL - impl Foo for B {} LL + impl Foo for B {} | -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-const-arguments.rs:14:32 - | -LL | impl Foo for C {} - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | impl Foo for C {} - | + + - -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-const-arguments.rs:19:16 - | -LL | impl Foo for D {} - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | impl Foo for D<{ E }, X, P> {} - | + + - -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-const-arguments.rs:25:46 - | -LL | impl Foo for D {} - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | impl Foo for D {} - | + + - -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0425, E0747. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/invalid-enum.rs b/tests/ui/const-generics/invalid-enum.rs index 09d06e0df78df..6af1c9293feb8 100644 --- a/tests/ui/const-generics/invalid-enum.rs +++ b/tests/ui/const-generics/invalid-enum.rs @@ -23,15 +23,12 @@ impl Example { pub fn main() { test_1::(); //~^ ERROR: expected type, found variant - //~| ERROR: unresolved item provided when a constant was expected test_2::<_, CompileFlag::A>(0); //~^ ERROR: expected type, found variant - //~| ERROR: unresolved item provided when a constant was expected let _: Example = Example { x: 0 }; //~^ ERROR: expected type, found variant - //~| ERROR: unresolved item provided when a constant was expected let _: Example = Example { x: 0 }; //~^ ERROR: type provided when a constant was expected diff --git a/tests/ui/const-generics/invalid-enum.stderr b/tests/ui/const-generics/invalid-enum.stderr index 20ac3dd48f225..55976a931446b 100644 --- a/tests/ui/const-generics/invalid-enum.stderr +++ b/tests/ui/const-generics/invalid-enum.stderr @@ -11,7 +11,7 @@ LL + test_1::(); | error[E0573]: expected type, found variant `CompileFlag::A` - --> $DIR/invalid-enum.rs:28:17 + --> $DIR/invalid-enum.rs:27:17 | LL | test_2::<_, CompileFlag::A>(0); | ^^^^^^^^^^^^^^ not a type @@ -23,7 +23,7 @@ LL + test_2::<_, CompileFlag>(0); | error[E0573]: expected type, found variant `CompileFlag::A` - --> $DIR/invalid-enum.rs:32:20 + --> $DIR/invalid-enum.rs:30:20 | LL | let _: Example = Example { x: 0 }; | ^^^^^^^^^^^^^^ not a type @@ -34,41 +34,8 @@ LL - let _: Example = Example { x: 0 }; LL + let _: Example = Example { x: 0 }; | -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:24:14 - | -LL | test_1::(); - | ^^^^^^^^^^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | test_1::<{ CompileFlag::A }>(); - | + + - -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:28:17 - | -LL | test_2::<_, CompileFlag::A>(0); - | ^^^^^^^^^^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | test_2::<_, { CompileFlag::A }>(0); - | + + - -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:32:20 - | -LL | let _: Example = Example { x: 0 }; - | ^^^^^^^^^^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 }; - | + + - error[E0747]: type provided when a constant was expected - --> $DIR/invalid-enum.rs:36:20 + --> $DIR/invalid-enum.rs:33:20 | LL | let _: Example = Example { x: 0 }; | ^^^^^^^^^^^^^^^^^^^ @@ -78,7 +45,7 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 }; | + + -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0573, E0747. For more information about an error, try `rustc --explain E0573`. diff --git a/tests/ui/const-generics/paren.rs b/tests/ui/const-generics/paren.rs index cf07ff8c035d7..1627666bfc19a 100644 --- a/tests/ui/const-generics/paren.rs +++ b/tests/ui/const-generics/paren.rs @@ -19,7 +19,6 @@ fn f() { let _: Thing<{ (_) }> = Thing::<5>; //~ ERROR in expressions, `_` can only be used on the left-hand side of an assignment let _: Thing = Thing; let _: Thing<(N)> = Thing; //~ ERROR cannot find type `N` in this scope - //~| ERROR unresolved item provided when a constant was expected let _: Thing<{ N }> = Thing; let _: Thing<{ (N) }> = Thing; //~ ERROR generic parameters may not be used in const operations let _: Thing<{ { N } }> = Thing; //~ ERROR generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/paren.stderr b/tests/ui/const-generics/paren.stderr index a0ee4a0683e37..d4958cd831424 100644 --- a/tests/ui/const-generics/paren.stderr +++ b/tests/ui/const-generics/paren.stderr @@ -29,7 +29,7 @@ LL | let _: [u32; { { N } }] = [5; _]; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/paren.rs:24:21 + --> $DIR/paren.rs:23:21 | LL | let _: Thing<{ (N) }> = Thing; | ^ cannot perform const operation using `N` @@ -39,7 +39,7 @@ LL | let _: Thing<{ (N) }> = Thing; = help: alternatively, you can use `#![feature(gca_const_items)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations - --> $DIR/paren.rs:25:22 + --> $DIR/paren.rs:24:22 | LL | let _: Thing<{ { N } }> = Thing; | ^ cannot perform const operation using `N` @@ -80,18 +80,6 @@ error: in expressions, `_` can only be used on the left-hand side of an assignme LL | let _: Thing<{ (_) }> = Thing::<5>; | ^ `_` not allowed here -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/paren.rs:21:19 - | -LL | let _: Thing<(N)> = Thing; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: Thing<({ N })> = Thing; - | + + - -error: aborting due to 11 previous errors +error: aborting due to 10 previous errors -Some errors have detailed explanations: E0573, E0747. -For more information about an error, try `rustc --explain E0573`. +For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.rs b/tests/ui/delegation/generics/generics-gen-args-errors.rs index e71f6df3c11c4..137252f3433fb 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.rs +++ b/tests/ui/delegation/generics/generics-gen-args-errors.rs @@ -28,13 +28,11 @@ mod test_1 { //~^ ERROR: cannot find type `asd` in this scope //~| ERROR: cannot find type `asd` in this scope //~| ERROR: cannot find type `asd` in this scope - //~| ERROR: unresolved item provided when a constant was expected reuse foo:: as xd; //~^ ERROR can't use generic parameters from outer item //~| ERROR can't use generic parameters from outer item //~| ERROR can't use generic parameters from outer item - //~| ERROR: unresolved item provided when a constant was expected //~| ERROR: function takes 2 lifetime arguments but 0 lifetime arguments were supplied //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature } diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.stderr b/tests/ui/delegation/generics/generics-gen-args-errors.stderr index 600b30f19ba6f..f677cf261a1fc 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.stderr +++ b/tests/ui/delegation/generics/generics-gen-args-errors.stderr @@ -1,5 +1,5 @@ error[E0401]: can't use generic parameters from outer item - --> $DIR/generics-gen-args-errors.rs:33:21 + --> $DIR/generics-gen-args-errors.rs:32:21 | LL | fn check() { | - type parameter from outer item @@ -12,7 +12,7 @@ LL | reuse foo:: as xd; = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0401]: can't use generic parameters from outer item - --> $DIR/generics-gen-args-errors.rs:33:24 + --> $DIR/generics-gen-args-errors.rs:32:24 | LL | fn check() { | - type parameter from outer item @@ -25,7 +25,7 @@ LL | reuse foo:: as xd; = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0401]: can't use generic parameters from outer item - --> $DIR/generics-gen-args-errors.rs:33:27 + --> $DIR/generics-gen-args-errors.rs:32:27 | LL | fn check() { | - type parameter from outer item @@ -38,7 +38,7 @@ LL | reuse foo:: as xd; = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0261]: use of undeclared lifetime name `'asdasd` - --> $DIR/generics-gen-args-errors.rs:53:29 + --> $DIR/generics-gen-args-errors.rs:51:29 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | ^^^^^^^ undeclared lifetime @@ -49,7 +49,7 @@ LL | reuse foo'asdasd, ::<'static, _, 'asdasd, 'static, 'static, 'static, _> | ++++++++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generics-gen-args-errors.rs:75:50 + --> $DIR/generics-gen-args-errors.rs:73:50 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^ undeclared lifetime @@ -105,79 +105,79 @@ LL | fn check() { | +++++ error[E0425]: cannot find type `asdasd` in this scope - --> $DIR/generics-gen-args-errors.rs:59:39 + --> $DIR/generics-gen-args-errors.rs:57:39 | LL | reuse foo:: as bar4; | ^^^^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:69:22 + --> $DIR/generics-gen-args-errors.rs:67:22 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:75:27 + --> $DIR/generics-gen-args-errors.rs:73:27 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:92:19 + --> $DIR/generics-gen-args-errors.rs:90:19 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:92:24 + --> $DIR/generics-gen-args-errors.rs:90:24 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:92:29 + --> $DIR/generics-gen-args-errors.rs:90:29 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:92:34 + --> $DIR/generics-gen-args-errors.rs:90:34 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:92:39 + --> $DIR/generics-gen-args-errors.rs:90:39 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asdasa` in this scope - --> $DIR/generics-gen-args-errors.rs:92:44 + --> $DIR/generics-gen-args-errors.rs:90:44 | LL | reuse Trait::::foo as bar1; | ^^^^^^ not found in this scope error[E0425]: cannot find type `DDDD` in this scope - --> $DIR/generics-gen-args-errors.rs:122:34 + --> $DIR/generics-gen-args-errors.rs:120:34 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^ not found in this scope error: wrong infer used: expected '_, found: _ - --> $DIR/generics-gen-args-errors.rs:53:26 + --> $DIR/generics-gen-args-errors.rs:51:26 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | ^ error: wrong infer used: expected '_, found: _ - --> $DIR/generics-gen-args-errors.rs:131:33 + --> $DIR/generics-gen-args-errors.rs:129:33 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:33:15 + --> $DIR/generics-gen-args-errors.rs:32:15 | LL | reuse foo:: as xd; | ^^^ expected 2 lifetime arguments @@ -193,19 +193,19 @@ LL | reuse foo::<'a, 'b, A, B, C> as xd; | +++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:33:15 + --> $DIR/generics-gen-args-errors.rs:32:15 | LL | reuse foo:: as xd; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:48:11 + --> $DIR/generics-gen-args-errors.rs:46:11 | LL | reuse foo:: as bar2; | ^^^ expected 2 lifetime arguments | note: function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- @@ -215,7 +215,7 @@ LL | reuse foo::<'a, 'b, String, String> as bar2; | +++++++ error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:48:11 + --> $DIR/generics-gen-args-errors.rs:46:11 | LL | reuse foo:: as bar2; | ^^^ ------ ------ supplied 2 generic arguments @@ -223,7 +223,7 @@ LL | reuse foo:: as bar2; | expected 3 generic arguments | note: function defined here, with 3 generic parameters: `T`, `U`, `N` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- @@ -233,13 +233,13 @@ LL | reuse foo:: as bar2; | +++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:48:11 + --> $DIR/generics-gen-args-errors.rs:46:11 | LL | reuse foo:: as bar2; | ^^^ error[E0107]: function takes 2 lifetime arguments but 6 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:53:11 + --> $DIR/generics-gen-args-errors.rs:51:11 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | ^^^------------------------------------------------- help: remove the lifetime arguments @@ -247,19 +247,19 @@ LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | expected 2 lifetime arguments | note: function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied - --> $DIR/generics-gen-args-errors.rs:53:11 + --> $DIR/generics-gen-args-errors.rs:51:11 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | ^^^ expected 3 generic arguments - supplied 1 generic argument | note: function defined here, with 3 generic parameters: `T`, `U`, `N` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- @@ -269,7 +269,7 @@ LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, U, N> as | ++++++ error[E0107]: function takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:59:11 + --> $DIR/generics-gen-args-errors.rs:57:11 | LL | reuse foo:: as bar4; | ^^^ ------ supplied 1 lifetime argument @@ -277,7 +277,7 @@ LL | reuse foo:: as bar4; | expected 2 lifetime arguments | note: function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- @@ -287,19 +287,19 @@ LL | reuse foo:: as bar4; | +++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:59:11 + --> $DIR/generics-gen-args-errors.rs:57:11 | LL | reuse foo:: as bar4; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:64:11 + --> $DIR/generics-gen-args-errors.rs:62:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^ expected 2 lifetime arguments | note: function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- @@ -309,7 +309,7 @@ LL | reuse foo::<'a, 'b, 1, 2, _, 4, 5, _> as bar5; | +++++++ error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:64:11 + --> $DIR/generics-gen-args-errors.rs:62:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^------------------- help: remove the unnecessary generic arguments @@ -317,25 +317,25 @@ LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | expected 3 generic arguments | note: function defined here, with 3 generic parameters: `T`, `U`, `N` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:64:11 + --> $DIR/generics-gen-args-errors.rs:62:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:69:11 + --> $DIR/generics-gen-args-errors.rs:67:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ expected 2 lifetime arguments | note: function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- @@ -345,7 +345,7 @@ LL | reuse foo::<'a, 'b, 1, 2,asd,String, { let x = 0; }> as bar6; | +++++++ error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:69:11 + --> $DIR/generics-gen-args-errors.rs:67:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ ----------------------- help: remove the unnecessary generic arguments @@ -353,37 +353,37 @@ LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | expected 3 generic arguments | note: function defined here, with 3 generic parameters: `T`, `U`, `N` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:69:11 + --> $DIR/generics-gen-args-errors.rs:67:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:75:11 + --> $DIR/generics-gen-args-errors.rs:73:11 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^ error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:75:17 + --> $DIR/generics-gen-args-errors.rs:73:17 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^^^^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:81:11 + --> $DIR/generics-gen-args-errors.rs:79:11 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^^ expected 2 lifetime arguments | note: function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/generics-gen-args-errors.rs:44:8 + --> $DIR/generics-gen-args-errors.rs:42:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- @@ -393,19 +393,19 @@ LL | reuse foo::<'a, 'b, {}, {}, {}> as bar8; | +++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:81:11 + --> $DIR/generics-gen-args-errors.rs:79:11 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^^ error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:92:11 + --> $DIR/generics-gen-args-errors.rs:90:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -415,7 +415,7 @@ LL | reuse Trait::<'b, 'c, 'a, asd, asd, asd, asd, asd, asdasa>::foo as bar1 | +++++++++++ error[E0107]: trait takes 2 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:92:11 + --> $DIR/generics-gen-args-errors.rs:90:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ ----------------------- help: remove the unnecessary generic arguments @@ -423,19 +423,19 @@ LL | reuse Trait::::foo as bar1; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:92:11 + --> $DIR/generics-gen-args-errors.rs:90:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:103:11 + --> $DIR/generics-gen-args-errors.rs:101:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ ------- ------- supplied 2 lifetime arguments @@ -443,7 +443,7 @@ LL | reuse Trait::<'static, 'static>::foo as bar2; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -453,25 +453,25 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar2; | +++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:103:11 + --> $DIR/generics-gen-args-errors.rs:101:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:103:11 + --> $DIR/generics-gen-args-errors.rs:101:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ not allowed in type signatures error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:107:11 + --> $DIR/generics-gen-args-errors.rs:105:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -481,7 +481,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, 3, 4, 5>::foo as bar3; | +++++++++++ error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:107:11 + --> $DIR/generics-gen-args-errors.rs:105:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ --------- help: remove the unnecessary generic arguments @@ -489,25 +489,25 @@ LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:107:11 + --> $DIR/generics-gen-args-errors.rs:105:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:112:11 + --> $DIR/generics-gen-args-errors.rs:110:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -517,7 +517,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, true>::foo as bar4; | +++++++++++ error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:112:11 + --> $DIR/generics-gen-args-errors.rs:110:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ ------ help: remove the unnecessary generic argument @@ -525,19 +525,19 @@ LL | reuse Trait::<1, 2, true>::foo as bar4; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:112:11 + --> $DIR/generics-gen-args-errors.rs:110:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:117:11 + --> $DIR/generics-gen-args-errors.rs:115:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ ------- supplied 1 lifetime argument @@ -545,7 +545,7 @@ LL | reuse Trait::<'static>::foo as bar5; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -555,19 +555,19 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar5; | ++++++++++++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:117:11 + --> $DIR/generics-gen-args-errors.rs:115:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:117:11 + --> $DIR/generics-gen-args-errors.rs:115:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ not allowed in type signatures error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:122:11 + --> $DIR/generics-gen-args-errors.rs:120:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ - supplied 1 lifetime argument @@ -575,7 +575,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -585,7 +585,7 @@ LL | reuse Trait::<1, 'static, 'static, 2, 'static, DDDD>::foo::<1, 2, 3, 4, | ++++++++++++++++++ error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:122:11 + --> $DIR/generics-gen-args-errors.rs:120:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ --------------- help: remove the unnecessary generic argument @@ -593,25 +593,25 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:122:11 + --> $DIR/generics-gen-args-errors.rs:120:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:122:41 + --> $DIR/generics-gen-args-errors.rs:120:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ expected 1 lifetime argument | note: method defined here, with 1 lifetime parameter: `'d` - --> $DIR/generics-gen-args-errors.rs:89:12 + --> $DIR/generics-gen-args-errors.rs:87:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- @@ -621,7 +621,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<'d, 1, 2, 3, 4, 5, 6> as bar6 | +++ error[E0107]: method takes 2 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:122:41 + --> $DIR/generics-gen-args-errors.rs:120:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ ------------ help: remove the unnecessary generic arguments @@ -629,19 +629,19 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 2 generic arguments | note: method defined here, with 2 generic parameters: `U`, `M` - --> $DIR/generics-gen-args-errors.rs:89:12 + --> $DIR/generics-gen-args-errors.rs:87:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:122:41 + --> $DIR/generics-gen-args-errors.rs:120:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:131:11 + --> $DIR/generics-gen-args-errors.rs:129:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^^^ ----- ----- supplied 2 lifetime arguments @@ -649,7 +649,7 @@ LL | reuse Trait::::foo::<1, 2, 3, _, | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -659,7 +659,7 @@ LL | reuse Trait::::foo::<1, 2, 3 | ++++ error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:131:11 + --> $DIR/generics-gen-args-errors.rs:129:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^^^ ------------------------- help: remove the unnecessary generic arguments @@ -667,25 +667,25 @@ LL | reuse Trait::::foo::<1, 2, 3, _, | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:88:11 + --> $DIR/generics-gen-args-errors.rs:86:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:131:11 + --> $DIR/generics-gen-args-errors.rs:129:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^^^ error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:131:59 + --> $DIR/generics-gen-args-errors.rs:129:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ expected 1 lifetime argument | note: method defined here, with 1 lifetime parameter: `'d` - --> $DIR/generics-gen-args-errors.rs:89:12 + --> $DIR/generics-gen-args-errors.rs:87:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- @@ -695,7 +695,7 @@ LL | reuse Trait::::foo::<'a, 1, 2, 3 | +++ error[E0107]: method takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:131:59 + --> $DIR/generics-gen-args-errors.rs:129:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ --------- help: remove the unnecessary generic arguments @@ -703,13 +703,13 @@ LL | reuse Trait::::foo::<1, 2, 3, _, | expected 2 generic arguments | note: method defined here, with 2 generic parameters: `U`, `M` - --> $DIR/generics-gen-args-errors.rs:89:12 + --> $DIR/generics-gen-args-errors.rs:87:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:131:59 + --> $DIR/generics-gen-args-errors.rs:129:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ @@ -762,35 +762,13 @@ note: function defined here, with 3 generic parameters: `T`, `U`, `N` LL | reuse foo as bar; | --- ^^^ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/generics-gen-args-errors.rs:27:25 - | -LL | bar::(); - | ^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | bar::(); - | + + - -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/generics-gen-args-errors.rs:33:27 - | -LL | reuse foo:: as xd; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | reuse foo:: as xd; - | + + - error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:81:17 + --> $DIR/generics-gen-args-errors.rs:79:17 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^ -error: aborting due to 74 previous errors +error: aborting due to 72 previous errors Some errors have detailed explanations: E0107, E0121, E0261, E0401, E0423, E0425, E0747. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.rs b/tests/ui/missing/missing-items/missing-type-parameter2.rs index c52f3157454a3..d7359f3ca70d6 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.rs +++ b/tests/ui/missing/missing-items/missing-type-parameter2.rs @@ -2,11 +2,9 @@ struct X(); impl X {} //~^ ERROR cannot find const `N` in this scope -//~| ERROR unresolved item provided when a constant was expected impl X {} //~^ ERROR cannot find const `N` in this scope //~| ERROR defaults for generic parameters are not allowed here -//~| ERROR unresolved item provided when a constant was expected fn foo(_: T) where T: Send {} //~^ ERROR cannot find type `T` in this scope diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.stderr b/tests/ui/missing/missing-items/missing-type-parameter2.stderr index efafb3a008535..e65b6bb976004 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.stderr +++ b/tests/ui/missing/missing-items/missing-type-parameter2.stderr @@ -13,7 +13,7 @@ LL | impl X {} | +++++++++++++ error[E0425]: cannot find const `N` in this scope - --> $DIR/missing-type-parameter2.rs:6:28 + --> $DIR/missing-type-parameter2.rs:5:28 | LL | struct X(); | ----------- corresponding const parameter on the type defined here @@ -27,7 +27,7 @@ LL | impl X {} | +++++++++++++ error[E0425]: cannot find type `T` in this scope - --> $DIR/missing-type-parameter2.rs:11:20 + --> $DIR/missing-type-parameter2.rs:9:20 | LL | fn foo(_: T) where T: Send {} | ^ not found in this scope @@ -48,7 +48,7 @@ LL | fn foo(_: T) where T: Send {} | +++ error[E0425]: cannot find type `T` in this scope - --> $DIR/missing-type-parameter2.rs:11:11 + --> $DIR/missing-type-parameter2.rs:9:11 | LL | fn foo(_: T) where T: Send {} | ^ not found in this scope @@ -69,7 +69,7 @@ LL | fn foo(_: T) where T: Send {} | +++ error[E0425]: cannot find type `A` in this scope - --> $DIR/missing-type-parameter2.rs:15:24 + --> $DIR/missing-type-parameter2.rs:13:24 | LL | fn bar(_: A) {} | ^ not found in this scope @@ -89,35 +89,12 @@ help: you might be missing a type parameter LL | fn bar(_: A) {} | +++ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/missing-type-parameter2.rs:3:8 - | -LL | impl X {} - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | impl X<{ N }> {} - | + + - error: defaults for generic parameters are not allowed here - --> $DIR/missing-type-parameter2.rs:6:9 + --> $DIR/missing-type-parameter2.rs:5:9 | LL | impl X {} | ^^^^^^^^^^^^^^^ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/missing-type-parameter2.rs:6:28 - | -LL | impl X {} - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | impl X<{ N }> {} - | + + - -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0425, E0747. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. From 8652467a1f08e47b493da6da5438a4e557c07a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jul 2026 16:27:32 +0000 Subject: [PATCH 09/59] review comment: move change of path source to smart_resolve_report_errors --- .../rustc_resolve/src/late/diagnostics.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index cb878e17ea7cc..ddde9982c0cae 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -666,11 +666,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { path: &[Segment], following_seg: Option<&Segment>, span: Span, - source: PathSource<'_, 'ast, 'ra>, + mut source: PathSource<'_, 'ast, 'ra>, res: Option, qself: Option<&QSelf>, ) -> (Diag<'tcx>, Vec) { - debug!(?res, ?source); let cross_namespace_res = res.filter(|res| !res.matches_ns(source.namespace())); let could_be_expr = res.is_some_and(|res| self.could_be_expr(res, span)); let base_error = self.make_base_error( @@ -685,6 +684,14 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone()); err.code(code); + if self.diag_metadata.currently_processing_generic_args + && let PathSource::Type = source + && let [segment] = path + && !segment.has_generic_args + { + source = PathSource::TypeParam; + } + if let Some(res) = cross_namespace_res { err.note(format!( "{} {} named `{}` exists in another namespace", @@ -1412,19 +1419,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_typo( &mut self, err: &mut Diag<'_>, - mut source: PathSource<'_, 'ast, 'ra>, + source: PathSource<'_, 'ast, 'ra>, path: &[Segment], following_seg: Option<&Segment>, span: Span, base_error: &BaseError, suggested_candidates: FxHashSet, ) -> bool { - if self.diag_metadata.currently_processing_generic_args - && matches!(source, PathSource::Type) - { - source = PathSource::TypeParam; - } - let is_expected = &|res| source.is_expected(res); let ident_span = path.last().map_or(span, |ident| ident.ident.span); From 7a1ec8e665a9691187de2964f11216883bfdc84d Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 4 Oct 2026 22:07:36 -0400 Subject: [PATCH 10/59] check is_indirect_first_projection when replacing in RefProp --- compiler/rustc_mir_transform/src/ref_prop.rs | 2 +- ...d_field_reborrow.ReferencePropagation.diff | 30 +++++++++++++++++ tests/mir-opt/reference_prop.rs | 32 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/mir-opt/reference_prop.maybe_dead_field_reborrow.ReferencePropagation.diff diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 731060bd2c2b8..4bc47bc8890eb 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -335,7 +335,7 @@ fn compute_replacement<'tcx>( // // This also allows to detect cases where `target.local` is not replaceable, // and mark it as such. - if let &[PlaceElem::Deref] = &target.projection[..] { + if target.is_indirect_first_projection() { assert!(perform_opt); self.allowed_replacements.insert((target.local, loc)); place.local = target.local; diff --git a/tests/mir-opt/reference_prop.maybe_dead_field_reborrow.ReferencePropagation.diff b/tests/mir-opt/reference_prop.maybe_dead_field_reborrow.ReferencePropagation.diff new file mode 100644 index 0000000000000..6b3928451a2ed --- /dev/null +++ b/tests/mir-opt/reference_prop.maybe_dead_field_reborrow.ReferencePropagation.diff @@ -0,0 +1,30 @@ +- // MIR for `maybe_dead_field_reborrow` before ReferencePropagation ++ // MIR for `maybe_dead_field_reborrow` after ReferencePropagation + + fn maybe_dead_field_reborrow(_1: bool) -> i32 { + let mut _0: i32; + let mut _2: (i32, i32); + let mut _3: &mut (i32, i32); + let mut _4: &mut i32; + + bb0: { + StorageLive(_2); + _2 = (const 0_i32, const 0_i32); + _3 = &mut _2; + ((*_3).0: i32) = const 1_i32; +- _4 = &mut ((*_3).0: i32); + switchInt(copy _1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + StorageDead(_2); + goto -> bb2; + } + + bb2: { +- _0 = copy (*_4); ++ _0 = copy ((*_3).0: i32); + return; + } + } + diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs index c4b63b6313c23..8220689baf1a4 100644 --- a/tests/mir-opt/reference_prop.rs +++ b/tests/mir-opt/reference_prop.rs @@ -776,6 +776,36 @@ fn maybe_dead(m: bool) { } } +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn maybe_dead_field_reborrow(m: bool) -> i32 { + // CHECK-LABEL: fn maybe_dead_field_reborrow( + // CHECK: [[r:_.*]] = &mut {{_.*}}; + // CHECK: ((*[[r]]).0: i32) = const 1_i32; + + use std::intrinsics::mir::*; + mir! { + let x: (i32, i32); + let r: &mut (i32, i32); + let r2: &mut i32; + { + StorageLive(x); + x = (0, 0); + r = &mut x; + (*r).0 = 1; + r2 = &mut (*r).0; + match m { true => bb1, _ => bb2 } + } + bb1 = { + StorageDead(x); + Goto(bb2) + } + bb2 = { + RET = *r2; + Return() + } + } +} + fn mut_raw_then_mut_shr() -> (i32, i32) { // CHECK-LABEL: fn mut_raw_then_mut_shr( // CHECK-NOT: (*{{_.*}}) @@ -875,6 +905,7 @@ fn main() { multiple_storage(); dominate_storage(); maybe_dead(true); + maybe_dead_field_reborrow(true); mut_raw_then_mut_shr(); unique_with_copies(); debuginfo(); @@ -889,6 +920,7 @@ fn main() { // EMIT_MIR reference_prop.multiple_storage.ReferencePropagation.diff // EMIT_MIR reference_prop.dominate_storage.ReferencePropagation.diff // EMIT_MIR reference_prop.maybe_dead.ReferencePropagation.diff +// EMIT_MIR reference_prop.maybe_dead_field_reborrow.ReferencePropagation.diff // EMIT_MIR reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff // EMIT_MIR reference_prop.unique_with_copies.ReferencePropagation.diff // EMIT_MIR reference_prop.debuginfo.ReferencePropagation.diff From 66c7ec68ddf67d63d729c6f7df5679b7458dccd8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 5 Oct 2026 18:15:41 +1100 Subject: [PATCH 11/59] Avoid `as_c_char_ptr` in debuginfo --- .../src/debuginfo/metadata.rs | 17 ++++++----- .../src/debuginfo/metadata/enums/mod.rs | 4 +-- .../src/debuginfo/metadata/enums/native.rs | 8 ++--- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 12 ++++---- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 30 +++++++++---------- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index a3bcce34566cb..e14cdeb1505d0 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -32,7 +32,7 @@ use super::CodegenUnitDebugContext; use super::namespace::mangled_name_of_instance; use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name}; use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, create_DIArray, wide_pointer_kind}; use crate::debuginfo::{DIBuilderExt, dwarf_const}; @@ -651,14 +651,14 @@ fn create_file<'ll>( unsafe { llvm::LLVMRustDIBuilderCreateFile( builder, - file_name.as_c_char_ptr(), + file_name.as_ptr(), file_name.len(), - directory.as_c_char_ptr(), + directory.as_ptr(), directory.len(), hash_kind, - hash_value.as_c_char_ptr(), + hash_value.as_ptr(), hash_value.len(), - source.map_or(ptr::null(), |x| x.as_c_char_ptr()), + source.map_or(ptr::null(), |x| x.as_ptr()), source.map_or(0, |x| x.len()), ) } @@ -949,20 +949,21 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( llvm::ChecksumKind::None, None, ); + let flags = c""; let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( debug_context.builder.as_ref(), dwarf_const::DW_LANG_Rust, compile_unit_file, - producer.as_c_char_ptr(), + producer.as_ptr(), producer.len(), tcx.sess.opts.optimize != config::OptLevel::No, - c"".as_ptr(), + flags.as_ptr(), 0, // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead // put the path supplied to `MCSplitDwarfFile` into the debug info of the final // output(s). - split_name.as_c_char_ptr(), + split_name.as_ptr(), split_name.len(), kind, 0, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 37f114fc5b09e..c2aa981582aaf 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -13,7 +13,7 @@ use rustc_span::{Span, Symbol, bug}; use super::type_map::{DINodeCreationResult, UniqueTypeId}; use super::{SmallVec, size_and_align_of}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::type_map::{self, Stub}; use crate::debuginfo::metadata::{ UNKNOWN_LINE_NUMBER, build_field_di_node, build_generic_type_param_di_nodes, @@ -141,7 +141,7 @@ fn build_enumeration_type_di_node<'ll, 'tcx>( llvm::LLVMRustDIBuilderCreateEnumerationType( DIB(cx), containing_scope, - type_name.as_c_char_ptr(), + type_name.as_ptr(), type_name.len(), file_metadata, line_number, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index c0ecb14d21926..c9cac61a8bbe1 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_span::bug; use smallvec::smallvec; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId}; use crate::debuginfo::metadata::{ DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, create_member_type, @@ -284,7 +284,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( llvm::LLVMRustDIBuilderCreateVariantPart( DIB(cx), enum_type_di_node, - variant_part_name.as_c_char_ptr(), + variant_part_name.as_ptr(), variant_part_name.len(), file_metadata, line_number, @@ -293,7 +293,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( DIFlags::FlagZero, tag_member_di_node, create_DIArray(DIB(cx), &[]), - variant_part_unique_type_id_str.as_c_char_ptr(), + variant_part_unique_type_id_str.as_ptr(), variant_part_unique_type_id_str.len(), ) }, @@ -444,7 +444,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>( llvm::LLVMRustDIBuilderCreateVariantMemberType( DIB(cx), variant_part_di_node, - variant_member_info.variant_name.as_c_char_ptr(), + variant_member_info.variant_name.as_ptr(), variant_member_info.variant_name.len(), file_di_node, line_number, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 29448f147d103..99a54f1d74a62 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -34,7 +34,7 @@ use self::metadata::{ use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; use crate::builder::Builder; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::di_builder::DIBuilderBox; use crate::llvm::debuginfo::{ DIArray, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, @@ -197,9 +197,9 @@ impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { llvm::LLVMRustDIBuilderCreateMethod( DIB(self), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), - linkage_name.as_c_char_ptr(), + linkage_name.as_ptr(), linkage_name.len(), file_metadata, loc.line, @@ -214,9 +214,9 @@ impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { llvm::LLVMRustDIBuilderCreateFunction( DIB(self), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), - linkage_name.as_c_char_ptr(), + linkage_name.as_ptr(), linkage_name.len(), file_metadata, loc.line, @@ -716,7 +716,7 @@ impl<'ll> CodegenCx<'ll, '_> { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(self), None, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), actual_type_metadata, ) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 4c7d60a0cbf67..1d2a902243c1b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2207,12 +2207,12 @@ unsafe extern "C" { Builder: &DIBuilder<'a>, Lang: c_uint, File: &'a DIFile, - Producer: *const c_char, + Producer: *const c_uchar, // See "PTR_LEN_STR". ProducerLen: size_t, isOptimized: bool, Flags: *const c_char, RuntimeVer: c_uint, - SplitName: *const c_char, + SplitName: *const c_uchar, // See "PTR_LEN_STR". SplitNameLen: size_t, kind: DebugEmissionKind, DWOId: u64, @@ -2224,14 +2224,14 @@ unsafe extern "C" { /// _requires_ a checksum, but we sometimes don't provide one. pub(crate) fn LLVMRustDIBuilderCreateFile<'a>( Builder: &DIBuilder<'a>, - Filename: *const c_char, + Filename: *const c_uchar, // See "PTR_LEN_STR". FilenameLen: size_t, - Directory: *const c_char, + Directory: *const c_uchar, // See "PTR_LEN_STR". DirectoryLen: size_t, CSKind: ChecksumKind, - Checksum: *const c_char, + Checksum: *const c_uchar, // See "PTR_LEN_STR". ChecksumLen: size_t, - Source: *const c_char, + Source: *const c_uchar, // See "PTR_LEN_STR". SourceLen: size_t, ) -> &'a DIFile; @@ -2240,9 +2240,9 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateFunction<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, - LinkageName: *const c_char, + LinkageName: *const c_uchar, // See "PTR_LEN_STR". LinkageNameLen: size_t, File: &'a DIFile, LineNo: c_uint, @@ -2259,9 +2259,9 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateMethod<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, - LinkageName: *const c_char, + LinkageName: *const c_uchar, // See "PTR_LEN_STR". LinkageNameLen: size_t, File: &'a DIFile, LineNo: c_uint, @@ -2275,7 +2275,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateVariantMemberType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, File: &'a DIFile, LineNumber: c_uint, @@ -2291,7 +2291,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateEnumerationType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, File: &'a DIFile, LineNumber: c_uint, @@ -2306,7 +2306,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateVariantPart<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, File: &'a DIFile, LineNo: c_uint, @@ -2315,7 +2315,7 @@ unsafe extern "C" { Flags: DIFlags, Discriminator: Option<&'a DIDerivedType>, Elements: &'a DIArray, - UniqueId: *const c_char, + UniqueId: *const c_uchar, // See "PTR_LEN_STR". UniqueIdLen: size_t, ) -> &'a DIDerivedType; @@ -2323,7 +2323,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateTemplateTypeParameter<'a>( Builder: &DIBuilder<'a>, Scope: Option<&'a DIScope>, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, Ty: &'a DIType, ) -> &'a DITemplateTypeParameter; From 891c24d7e2355fe73253226e8de81b8ea39aca80 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 5 Oct 2026 18:02:45 +1100 Subject: [PATCH 12/59] Avoid `as_c_char_ptr` in `declare.rs` --- compiler/rustc_codegen_llvm/src/declare.rs | 15 ++++----------- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 8 ++++---- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 23f9fc93a4ba4..78bc5aba450aa 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -25,7 +25,6 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::attributes; -use crate::common::AsCCharPtr; use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx}; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, FromGeneric, Type, Value, Visibility}; @@ -43,8 +42,7 @@ pub(crate) fn declare_simple_fn<'ll>( ty: &'ll Type, ) -> &'ll Value { debug!("declare_simple_fn(name={:?}, ty={:?})", name, ty); - let llfn = - unsafe { llvm::LLVMGetOrInsertFunction(cx.llmod, name.as_c_char_ptr(), name.len(), ty) }; + let llfn = unsafe { llvm::LLVMGetOrInsertFunction(cx.llmod, name.as_ptr(), name.len(), ty) }; llvm::SetFunctionCallConv(llfn, callconv); llvm::set_unnamed_address(llfn, unnamed); @@ -96,12 +94,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { debug!("declare_global(name={:?})", name); unsafe { - llvm::LLVMRustGetOrInsertGlobal( - (**self).borrow().llmod, - name.as_c_char_ptr(), - name.len(), - ty, - ) + llvm::LLVMRustGetOrInsertGlobal((**self).borrow().llmod, name.as_ptr(), name.len(), ty) } } @@ -119,7 +112,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { unsafe { llvm::LLVMRustGetOrInsertGlobalInAddrspace( (**self).borrow().llmod, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), ty, addr_space.0, @@ -261,7 +254,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { /// Gets declared value by name. pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { debug!("get_declared_value(name={:?})", name); - unsafe { llvm::LLVMRustGetNamedValue(self.llmod(), name.as_c_char_ptr(), name.len()) } + unsafe { llvm::LLVMRustGetNamedValue(self.llmod(), name.as_ptr(), name.len()) } } /// Gets defined or externally defined (AvailableExternally linkage) value by diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 1d2a902243c1b..4349c9666040d 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1127,7 +1127,7 @@ unsafe extern "C" { pub(crate) fn LLVMDeleteFunction(Fn: &Value); pub(crate) fn LLVMGetOrInsertFunction<'a>( M: &'a Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, FunctionTy: &'a Type, ) -> &'a Value; @@ -1992,20 +1992,20 @@ unsafe extern "C" { // Operations on global variables pub(crate) fn LLVMRustGetOrInsertGlobal<'a>( M: &'a Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, T: &'a Type, ) -> &'a Value; pub(crate) fn LLVMRustGetOrInsertGlobalInAddrspace<'a>( M: &'a Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, T: &'a Type, AddressSpace: c_uint, ) -> &'a Value; pub(crate) fn LLVMRustGetNamedValue( M: &Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, ) -> Option<&Value>; From ae54544c1134174fb308b49424f817a7bc9c7ed8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 5 Oct 2026 18:09:09 +1100 Subject: [PATCH 13/59] Avoid `as_c_char_ptr` in `write.rs` --- compiler/rustc_codegen_llvm/src/back/write.rs | 13 +++++-------- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 6 +++--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a95f259545982..5bbe1c887a939 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -33,7 +33,6 @@ use crate::back::profiling::{ }; use crate::builder::SBuilder; use crate::builder::gpu_offload::scalar_width; -use crate::common::AsCCharPtr; use crate::context::SimpleCx; use crate::diagnostics::{ CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, ParseTargetMachineConfig, @@ -548,9 +547,7 @@ pub(crate) unsafe fn llvm_optimize( } else { None }; - let passes_after_enzyme_ptr = - passes_after_enzyme.map_or(std::ptr::null(), |s| s.as_c_char_ptr()); - let passes_after_enzyme_len = passes_after_enzyme.map_or(0, |s| s.len()); + let merge_functions; let unroll_loops; let vectorize_slp; @@ -788,11 +785,11 @@ pub(crate) unsafe fn llvm_optimize( llvm_selfprofiler, selfprofile_before_pass_callback, selfprofile_after_pass_callback, - passes_after_enzyme_ptr, - passes_after_enzyme_len, - extra_passes.as_c_char_ptr(), + passes_after_enzyme.map(|s| s.as_ptr()).unwrap_or(std::ptr::null()), + passes_after_enzyme.map(|s| s.len()).unwrap_or(0), + extra_passes.as_ptr(), extra_passes.len(), - llvm_plugins.as_c_char_ptr(), + llvm_plugins.as_ptr(), llvm_plugins.len(), ) }; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 4349c9666040d..f9718834fb846 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2462,11 +2462,11 @@ unsafe extern "C" { llvm_selfprofiler: *mut c_void, begin_callback: SelfProfileBeforePassCallback, end_callback: SelfProfileAfterPassCallback, - PostEnzymePasses: *const c_char, + PostEnzymePasses: *const c_uchar, // See "PTR_LEN_STR". PostEnzymePassesLen: size_t, - ExtraPasses: *const c_char, + ExtraPasses: *const c_uchar, // See "PTR_LEN_STR". ExtraPassesLen: size_t, - LLVMPlugins: *const c_char, + LLVMPlugins: *const c_uchar, // See "PTR_LEN_STR". LLVMPluginsLen: size_t, ) -> LLVMRustResult; pub(crate) fn LLVMRustPrintModule( From 0f7320cc2385da083cad3636bb39572cee2b4e7f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 5 Oct 2026 11:05:13 +0200 Subject: [PATCH 14/59] Use target_family = "wasm" instead of target_arch = "wasm32" This slightly improves support for the WASM64 architecture. --- .../0028-sysroot_tests-Disable-long-running-tests.patch | 2 +- library/core/src/os/mod.rs | 4 ++-- library/coretests/benches/lib.rs | 4 ++-- library/coretests/tests/num/flt2dec/random.rs | 2 +- library/coretests/tests/slice.rs | 2 +- library/std/benches/time.rs | 4 ++-- library/std/src/net/tcp.rs | 6 +++--- library/std/src/os/fd/owned.rs | 6 +++--- library/std/src/os/fd/raw.rs | 2 +- library/std/src/os/mod.rs | 2 +- library/std/src/os/net/mod.rs | 2 +- library/std/src/os/unix/io/mod.rs | 2 +- library/std/tests/time.rs | 2 +- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch index 853acab2773b5..e503acf8fee8c 100644 --- a/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch +++ b/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch @@ -14,7 +14,7 @@ index 8402833..84592e0 100644 @@ -1619,7 +1619,7 @@ fn brute_force_rotate_test_1() { #[test] - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] -#[cfg_attr(miri, ignore)] // Miri is too slow +#[ignore] // Miri is too slow fn select_nth_unstable() { diff --git a/library/core/src/os/mod.rs b/library/core/src/os/mod.rs index 5ac2b637941ae..8d177dd3947c9 100644 --- a/library/core/src/os/mod.rs +++ b/library/core/src/os/mod.rs @@ -6,7 +6,7 @@ #[cfg(all( doc, any( - all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_family = "wasm", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") ) ))] @@ -17,7 +17,7 @@ pub mod darwin {} #[cfg(not(all( doc, any( - all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_family = "wasm", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") ) )))] diff --git a/library/coretests/benches/lib.rs b/library/coretests/benches/lib.rs index e8dc815a7dd0f..4815c3e44e1a1 100644 --- a/library/coretests/benches/lib.rs +++ b/library/coretests/benches/lib.rs @@ -1,5 +1,5 @@ -// wasm32 does not support benches (no time). -#![cfg(not(target_arch = "wasm32"))] +// wasm*-unknown-unknown does not support benches (no time). +#![cfg(all(target_family = "wasm", target_os = "unknown"))] // This is marked as `test = true` and hence picked up by `./x miri`, but that would be too slow. #![cfg(not(miri))] #![feature(flt2dec)] diff --git a/library/coretests/tests/num/flt2dec/random.rs b/library/coretests/tests/num/flt2dec/random.rs index e47aa6d37a804..b90386aee617c 100644 --- a/library/coretests/tests/num/flt2dec/random.rs +++ b/library/coretests/tests/num/flt2dec/random.rs @@ -1,4 +1,4 @@ -#![cfg(not(target_arch = "wasm32"))] +#![cfg(not(all(target_family = "wasm", target_os = "unknown")))] use core::num::imp::flt2dec; use std::mem::MaybeUninit; diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index e570bff645af7..f7149abaf3f16 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -1679,7 +1679,7 @@ fn brute_force_rotate_test_1() { } #[test] -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] #[cfg_attr(miri, ignore)] // Miri is too slow fn select_nth_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; diff --git a/library/std/benches/time.rs b/library/std/benches/time.rs index dfd886738f984..48d83672362b7 100644 --- a/library/std/benches/time.rs +++ b/library/std/benches/time.rs @@ -1,10 +1,10 @@ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use test::{Bencher, black_box}; macro_rules! bench_instant_threaded { ($bench_name:ident, $thread_count:expr) => { #[bench] - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] fn $bench_name(b: &mut Bencher) -> std::thread::Result<()> { use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 00f802e5d9155..e5c2522a837fb 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -913,9 +913,9 @@ impl TcpListener { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - // On WASM, `TcpStream` is uninhabited (as it's unsupported) and so - // the `a` variable here is technically unused. - #[cfg_attr(target_arch = "wasm32", allow(unused_variables))] + // On wasm*-unknown-unknown, `TcpStream` is uninhabited (as it's + // unsupported) and so the `a` variable here is technically unused. + #[cfg_attr(all(target_family = "wasm", target_os = "unknown"), allow(unused_variables))] self.0.accept().map(|(a, b)| (TcpStream(a), b)) } diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 87a8e20bad0d3..6c6f9b552c926 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -13,7 +13,7 @@ use crate::fs; use crate::marker::PhantomData; use crate::mem::ManuallyDrop; #[cfg(not(any( - all(target_arch = "wasm32", not(target_os = "emscripten")), + all(target_family = "wasm", not(target_os = "emscripten")), target_env = "sgx", target_os = "hermit", target_os = "trusty", @@ -105,7 +105,7 @@ impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. #[cfg(not(any( - all(target_arch = "wasm32", not(target_os = "emscripten")), + all(target_family = "wasm", not(target_os = "emscripten")), target_os = "hermit", target_os = "trusty", target_os = "motor" @@ -133,7 +133,7 @@ impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. #[cfg(any( - all(target_arch = "wasm32", not(target_os = "emscripten")), + all(target_family = "wasm", not(target_os = "emscripten")), target_os = "hermit", target_os = "trusty" ))] diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index a8d981520efd2..4d7b6a3e5fb53 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -17,7 +17,7 @@ use crate::io; use crate::os::hermit::io::OwnedFd; #[cfg(all(not(target_os = "hermit"), not(target_os = "motor")))] use crate::os::raw; -#[cfg(all(doc, not(any(target_arch = "wasm32", target_env = "sgx", target_os = "l4re"))))] +#[cfg(all(doc, not(any(target_family = "wasm", target_env = "sgx", target_os = "l4re"))))] use crate::os::unix::io::AsFd; #[cfg(unix)] use crate::os::unix::io::OwnedFd; diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 8068f92bcc93c..f95c6ac8dd76d 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -16,7 +16,7 @@ pub mod raw; #[cfg(doc)] cfg_select! { any( - all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_family = "wasm", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") ) => { #[unstable(issue = "none", feature = "std_internals")] diff --git a/library/std/src/os/net/mod.rs b/library/std/src/os/net/mod.rs index 47e69b3a260dc..cbde585c8d79f 100644 --- a/library/std/src/os/net/mod.rs +++ b/library/std/src/os/net/mod.rs @@ -5,7 +5,7 @@ #[cfg(not(all( doc, any( - all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_family = "wasm", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") ) )))] diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 4afb8ffa71017..099bdd35439a1 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -216,7 +216,7 @@ fn replace_stdio_fd(this: BorrowedFd<'_>, other: OwnedFd) -> io::Result<()> { .map(|_| ()) } not(any( - all(target_arch = "wasm32", not(target_os = "emscripten")), + all(target_family = "wasm", not(target_os = "emscripten")), target_os = "hermit", target_os = "trusty", target_os = "motor" diff --git a/library/std/tests/time.rs b/library/std/tests/time.rs index 6d8b4cbfd094f..4d47b068ab87a 100644 --- a/library/std/tests/time.rs +++ b/library/std/tests/time.rs @@ -29,7 +29,7 @@ fn instant_monotonic() { } #[test] -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] fn instant_monotonic_concurrent() -> std::thread::Result<()> { let threads: Vec<_> = (0..8) .map(|_| { From 54bdb68955ecabe72cd5e13cb527c19967fab9eb Mon Sep 17 00:00:00 2001 From: Jamesbarford Date: Mon, 5 Oct 2026 13:40:10 +0000 Subject: [PATCH 15/59] Add `has_reliable_f16b` for Arm --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a582e897eef9c..ea91756b9068a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -399,7 +399,7 @@ fn update_target_reliable_float_cfg(target: &Target, cfg: &mut TargetConfig) { // This is similar to , however // does not work until LLVM 23 on Windows. (Arch::Arm64EC, _) => major >= 23, - (Arch::AArch64, _) => true, + (Arch::AArch64 | Arch::Arm, _) => true, // FIXME(f16b) until // is resolved the below do not have a reliable `f16b`, on a widening // path a call to `__truncsfbf2` is emitted. Or when using architectural From 9837aeb52e90b63fa147ba59db07dd0bf957baf5 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 19:01:29 +0200 Subject: [PATCH 16/59] Update books --- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index 5791ca9f5d671..46fc44214afcd 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 5791ca9f5d671328af7a8fe87b42ca90c7211d28 +Subproject commit 46fc44214afcd159be175c8ee62887cad04f615d diff --git a/src/doc/reference b/src/doc/reference index 4245282b97496..a286e1ecb8ce1 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 4245282b97496585e73862b966d639cbb553bd6c +Subproject commit a286e1ecb8ce193d50056e4bb042eea9b23876ef diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index af5ef7024e885..dcc14f912bf87 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit af5ef7024e88587aa3be244422f6365e86c50e85 +Subproject commit dcc14f912bf8790792a2df082eddc82ab2539229 From e779bd7ed52b8f8efb827b7958a167a658f1fc45 Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Tue, 3 Feb 2026 10:42:33 -0500 Subject: [PATCH 17/59] oneshot `is_ready` Signed-off-by: Connor Tsui --- library/std/src/sync/oneshot.rs | 37 ++++++++++++++++++++++++++++--- library/std/tests/sync/oneshot.rs | 20 +++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/library/std/src/sync/oneshot.rs b/library/std/src/sync/oneshot.rs index b2c9ba34c0ff6..c905b7363e2a5 100644 --- a/library/std/src/sync/oneshot.rs +++ b/library/std/src/sync/oneshot.rs @@ -176,9 +176,8 @@ pub struct Receiver { inner: mpmc::Receiver, } -// SAFETY: Since the only methods in which synchronization must occur take full ownership of the -// [`Receiver`], it is perfectly safe to share a `&Receiver` between threads (as it is unable to -// receive any values without ownership). +// SAFETY: Receiving a value requires ownership of the receiver. Shared references only inspect +// channel state, so they cannot access a value of a non-`Send` type from another thread. #[unstable(feature = "oneshot_channel", issue = "143674")] unsafe impl Sync for Receiver {} @@ -212,8 +211,40 @@ impl Receiver { // Fallible methods. + /// Returns `Ok(true)` if the sender has sent a value over the channel. + /// + /// Returns `Ok(false)` if no value has been sent, but the corresponding [`Sender`] still + /// exists (has not been dropped yet). + /// + /// Returns a [`RecvError`] if the corresponding [`Sender`] has been dropped before a value + /// has been sent. + /// + /// If this method returns `Ok(true)`, then any of the `recv` methods are guaranteed to return + /// the value successfully without blocking. + /// + /// # Warnings + /// + /// A return value of `Ok(false)` does not guarantee that a later receive operation will block. + /// The sender may send a value or be dropped immediately after this method returns. + /// + /// Polling this method in a loop just to wait for a value wastes CPU time. Use + /// [`recv`](Self::recv) or [`recv_timeout`](Self::recv_timeout) instead. + #[unstable(feature = "oneshot_channel", issue = "143674")] + pub fn is_ready(&self) -> Result { + // Sending consumes and drops the sender after writing the value, so the channel is ready + // only when it is both disconnected and nonempty. + if !self.inner.is_disconnected() { + return Ok(false); + } + + if self.inner.is_empty() { Err(RecvError) } else { Ok(true) } + } + /// Attempts to return a pending value on this receiver without blocking. /// + /// To check whether a value is available without consuming the receiver, use + /// [`is_ready`](Self::is_ready). + /// /// # Examples /// /// ``` diff --git a/library/std/tests/sync/oneshot.rs b/library/std/tests/sync/oneshot.rs index 6eaacfbc6497d..0197369869d80 100644 --- a/library/std/tests/sync/oneshot.rs +++ b/library/std/tests/sync/oneshot.rs @@ -6,6 +6,26 @@ use std::sync::oneshot::{RecvTimeoutError, TryRecvError}; use std::time::{Duration, Instant}; use std::{mem, thread}; +#[test] +fn is_ready_after_send() { + let (sender, receiver) = oneshot::channel(); + assert_eq!(receiver.is_ready(), Ok(false)); + + sender.send(String::from("hello")).unwrap(); + + assert_eq!(receiver.is_ready(), Ok(true)); + assert_eq!(receiver.try_recv().unwrap(), "hello"); +} + +#[test] +fn is_ready_after_sender_drop() { + let (sender, receiver) = oneshot::channel::<()>(); + drop(sender); + + assert_eq!(receiver.is_ready(), Err(RecvError)); + assert_eq!(receiver.recv(), Err(RecvError)); +} + #[test] fn send_before_try_recv() { let (sender, receiver) = oneshot::channel(); From 54a6d2e4c750c76885dc444ec5eb97a30e85a695 Mon Sep 17 00:00:00 2001 From: xonx4l Date: Mon, 5 Oct 2026 23:29:44 +0530 Subject: [PATCH 18/59] factor out as check_ffi_type method --- .../rustc_lint/src/types/improper_ctypes.rs | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 2d42e9fdd05da..04b381261e428 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -149,6 +149,29 @@ impl<'tcx> ImproperCTypesLint { fn cache_key(cx: &LateContext<'tcx>, ty: Ty<'tcx>, flags: RootUseFlags) -> (Hash128, u8) { (cx.tcx.type_id_hash(ty), flags.bits()) } + + fn check_ffi_type( + &self, + cx: &LateContext<'tcx>, + ty: Ty<'tcx>, + state: VisitorState, + span: Span, + mode: CItemKind, + check: impl FnOnce() -> FfiResult<'tcx>, + ) { + let key = Self::cache_key(cx, ty, state.root_use_flags); + if self.known_safe.borrow().contains(&key) { + return; + } + + let ffi_res = check(); + + if matches!(ffi_res, FfiResult::FfiSafe) { + self.known_safe.borrow_mut().insert(key); + } + + self.process_ffi_result(cx, span, ffi_res, mode); + } } impl_lint_pass!(ImproperCTypesLint => [ @@ -1123,16 +1146,10 @@ impl<'tcx> ImproperCTypesLint { fn check_foreign_static(&mut self, cx: &LateContext<'tcx>, id: hir::OwnerId, span: Span) { let ty = cx.tcx.type_of(id).instantiate_identity(); let state = VisitorState::static_entry_point(); - let key = Self::cache_key(cx, ty.skip_norm_wip(), state.root_use_flags); - if self.known_safe.borrow().contains(&key) { - return; - } - let mut visitor = ImproperCTypesVisitor::new(cx, ty, CItemKind::Declaration); - let ffi_res = visitor.check_type(state, ty); - if matches!(ffi_res, FfiResult::FfiSafe) { - self.known_safe.borrow_mut().insert(key); - } - self.process_ffi_result(cx, span, ffi_res, CItemKind::Declaration); + self.check_ffi_type(cx, ty.skip_norm_wip(), state, span, CItemKind::Declaration, || { + let mut visitor = ImproperCTypesVisitor::new(cx, ty, CItemKind::Declaration); + visitor.check_type(state, ty) + }); } /// Check if a function's argument types and result type are "ffi-safe". @@ -1148,31 +1165,20 @@ impl<'tcx> ImproperCTypesLint { for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { let state = VisitorState::fn_entry_point(fn_mode, FnPos::Arg); - let key = Self::cache_key(cx, *input_ty, state.root_use_flags); - if self.known_safe.borrow().contains(&key) { - continue; - } - let input_ty = Unnormalized::new_wip(*input_ty); - let mut visitor = ImproperCTypesVisitor::new(cx, input_ty, fn_mode); - let ffi_res = visitor.check_type(state, input_ty); - if matches!(ffi_res, FfiResult::FfiSafe) { - self.known_safe.borrow_mut().insert(key); - } - self.process_ffi_result(cx, input_hir.span, ffi_res, fn_mode); + self.check_ffi_type(cx, *input_ty, state, input_hir.span, fn_mode, || { + let input_ty = Unnormalized::new_wip(*input_ty); + let mut visitor = ImproperCTypesVisitor::new(cx, input_ty, fn_mode); + visitor.check_type(state, input_ty) + }); } if let hir::FnRetTy::Return(ret_hir) = decl.output { let state = VisitorState::fn_entry_point(fn_mode, FnPos::Ret); - let key = Self::cache_key(cx, sig.output(), state.root_use_flags); - if !self.known_safe.borrow().contains(&key) { + self.check_ffi_type(cx, sig.output(), state, ret_hir.span, fn_mode, || { let output_ty = Unnormalized::new_wip(sig.output()); let mut visitor = ImproperCTypesVisitor::new(cx, output_ty, fn_mode); - let ffi_res = visitor.check_type(state, output_ty); - if matches!(ffi_res, FfiResult::FfiSafe) { - self.known_safe.borrow_mut().insert(key); - } - self.process_ffi_result(cx, ret_hir.span, ffi_res, fn_mode); - } + visitor.check_type(state, output_ty) + }); } } From 9de9ceb55138da485f465e7d5f6d23b73fda9528 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 4 Oct 2026 22:04:59 +0200 Subject: [PATCH 19/59] Move more tests around in `rustdoc-html` --- tests/rustdoc-html/README.md | 5 +++++ .../decl-line-wrapping-empty-arg-list.decl.html | 0 .../{ => display}/decl-line-wrapping-empty-arg-list.rs | 0 .../{ => display}/decl-trailing-whitespace.declaration.html | 0 tests/rustdoc-html/{ => display}/decl-trailing-whitespace.rs | 0 .../extremely_long_typename.extremely_long_typename.html | 0 tests/rustdoc-html/{ => display}/extremely_long_typename.rs | 0 .../{ => display}/item-desc-list-at-start.item-table.html | 0 tests/rustdoc-html/{ => display}/item-desc-list-at-start.rs | 0 tests/rustdoc-html/{ => display}/where.SWhere_Echo_impl.html | 0 .../{ => display}/where.SWhere_Simd_item-decl.html | 0 .../{ => display}/where.SWhere_TraitWhere_item-decl.html | 0 tests/rustdoc-html/{ => display}/where.alpha_trait_decl.html | 0 tests/rustdoc-html/{ => display}/where.bravo_trait_decl.html | 0 tests/rustdoc-html/{ => display}/where.charlie_fn_decl.html | 0 .../{ => display}/where.golf_type_alias_decl.html | 0 tests/rustdoc-html/{ => display}/where.rs | 0 .../{ => display}/whitespace-after-where-clause.enum.html | 0 .../{ => display}/whitespace-after-where-clause.enum2.html | 0 .../{ => display}/whitespace-after-where-clause.rs | 0 .../{ => display}/whitespace-after-where-clause.struct.html | 0 .../{ => display}/whitespace-after-where-clause.struct2.html | 0 .../{ => display}/whitespace-after-where-clause.trait.html | 0 .../{ => display}/whitespace-after-where-clause.trait2.html | 0 .../{ => display}/whitespace-after-where-clause.union.html | 0 .../{ => display}/whitespace-after-where-clause.union2.html | 0 tests/rustdoc-html/{ => extern}/auxiliary/rustdoc-ffi.rs | 0 tests/rustdoc-html/{ => extern}/ffi.rs | 0 tests/rustdoc-html/{ => extern}/foreigntype.rs | 0 tests/rustdoc-html/{ => hidden}/doc-hidden-crate.rs | 0 tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs | 2 ++ .../rustdoc-html/{ => reexport}/auxiliary/reexp-stripped.rs | 0 .../duplicate-reexports-section-150211.rs | 0 tests/rustdoc-html/{ => reexport}/hidden-methods.rs | 0 tests/rustdoc-html/{ => reexport}/redirect.rs | 0 tests/{rustdoc-html => rustdoc-ui/lints}/cap-lints.rs | 4 +++- 36 files changed, 10 insertions(+), 1 deletion(-) rename tests/rustdoc-html/{ => display}/decl-line-wrapping-empty-arg-list.decl.html (100%) rename tests/rustdoc-html/{ => display}/decl-line-wrapping-empty-arg-list.rs (100%) rename tests/rustdoc-html/{ => display}/decl-trailing-whitespace.declaration.html (100%) rename tests/rustdoc-html/{ => display}/decl-trailing-whitespace.rs (100%) rename tests/rustdoc-html/{ => display}/extremely_long_typename.extremely_long_typename.html (100%) rename tests/rustdoc-html/{ => display}/extremely_long_typename.rs (100%) rename tests/rustdoc-html/{ => display}/item-desc-list-at-start.item-table.html (100%) rename tests/rustdoc-html/{ => display}/item-desc-list-at-start.rs (100%) rename tests/rustdoc-html/{ => display}/where.SWhere_Echo_impl.html (100%) rename tests/rustdoc-html/{ => display}/where.SWhere_Simd_item-decl.html (100%) rename tests/rustdoc-html/{ => display}/where.SWhere_TraitWhere_item-decl.html (100%) rename tests/rustdoc-html/{ => display}/where.alpha_trait_decl.html (100%) rename tests/rustdoc-html/{ => display}/where.bravo_trait_decl.html (100%) rename tests/rustdoc-html/{ => display}/where.charlie_fn_decl.html (100%) rename tests/rustdoc-html/{ => display}/where.golf_type_alias_decl.html (100%) rename tests/rustdoc-html/{ => display}/where.rs (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.enum.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.enum2.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.rs (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.struct.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.struct2.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.trait.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.trait2.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.union.html (100%) rename tests/rustdoc-html/{ => display}/whitespace-after-where-clause.union2.html (100%) rename tests/rustdoc-html/{ => extern}/auxiliary/rustdoc-ffi.rs (100%) rename tests/rustdoc-html/{ => extern}/ffi.rs (100%) rename tests/rustdoc-html/{ => extern}/foreigntype.rs (100%) rename tests/rustdoc-html/{ => hidden}/doc-hidden-crate.rs (100%) create mode 100644 tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs rename tests/rustdoc-html/{ => reexport}/auxiliary/reexp-stripped.rs (100%) rename tests/rustdoc-html/{extern => reexport}/duplicate-reexports-section-150211.rs (100%) rename tests/rustdoc-html/{ => reexport}/hidden-methods.rs (100%) rename tests/rustdoc-html/{ => reexport}/redirect.rs (100%) rename tests/{rustdoc-html => rustdoc-ui/lints}/cap-lints.rs (84%) diff --git a/tests/rustdoc-html/README.md b/tests/rustdoc-html/README.md index 4acb1d54bbb89..055c03b1eed35 100644 --- a/tests/rustdoc-html/README.md +++ b/tests/rustdoc-html/README.md @@ -48,6 +48,11 @@ conflicts, in particular for simpler crate names). Contains tests to check the display of items implementing the `Deref` and/or `DerefMut` traits. +## `tests/rustdoc-html/display` + +Contains tests checking how items are displayed in the docs. Ensuring that methods with a lot +of arguments or with a lot of generics are correctly split between multiple lines for example. + ## `tests/rustdoc-html/doc-cfg` Contains tests to check the rustdoc `doc_cfg` feature. diff --git a/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html b/tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.decl.html similarity index 100% rename from tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html rename to tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.decl.html diff --git a/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs b/tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.rs similarity index 100% rename from tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs rename to tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.rs diff --git a/tests/rustdoc-html/decl-trailing-whitespace.declaration.html b/tests/rustdoc-html/display/decl-trailing-whitespace.declaration.html similarity index 100% rename from tests/rustdoc-html/decl-trailing-whitespace.declaration.html rename to tests/rustdoc-html/display/decl-trailing-whitespace.declaration.html diff --git a/tests/rustdoc-html/decl-trailing-whitespace.rs b/tests/rustdoc-html/display/decl-trailing-whitespace.rs similarity index 100% rename from tests/rustdoc-html/decl-trailing-whitespace.rs rename to tests/rustdoc-html/display/decl-trailing-whitespace.rs diff --git a/tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc-html/display/extremely_long_typename.extremely_long_typename.html similarity index 100% rename from tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html rename to tests/rustdoc-html/display/extremely_long_typename.extremely_long_typename.html diff --git a/tests/rustdoc-html/extremely_long_typename.rs b/tests/rustdoc-html/display/extremely_long_typename.rs similarity index 100% rename from tests/rustdoc-html/extremely_long_typename.rs rename to tests/rustdoc-html/display/extremely_long_typename.rs diff --git a/tests/rustdoc-html/item-desc-list-at-start.item-table.html b/tests/rustdoc-html/display/item-desc-list-at-start.item-table.html similarity index 100% rename from tests/rustdoc-html/item-desc-list-at-start.item-table.html rename to tests/rustdoc-html/display/item-desc-list-at-start.item-table.html diff --git a/tests/rustdoc-html/item-desc-list-at-start.rs b/tests/rustdoc-html/display/item-desc-list-at-start.rs similarity index 100% rename from tests/rustdoc-html/item-desc-list-at-start.rs rename to tests/rustdoc-html/display/item-desc-list-at-start.rs diff --git a/tests/rustdoc-html/where.SWhere_Echo_impl.html b/tests/rustdoc-html/display/where.SWhere_Echo_impl.html similarity index 100% rename from tests/rustdoc-html/where.SWhere_Echo_impl.html rename to tests/rustdoc-html/display/where.SWhere_Echo_impl.html diff --git a/tests/rustdoc-html/where.SWhere_Simd_item-decl.html b/tests/rustdoc-html/display/where.SWhere_Simd_item-decl.html similarity index 100% rename from tests/rustdoc-html/where.SWhere_Simd_item-decl.html rename to tests/rustdoc-html/display/where.SWhere_Simd_item-decl.html diff --git a/tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html b/tests/rustdoc-html/display/where.SWhere_TraitWhere_item-decl.html similarity index 100% rename from tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html rename to tests/rustdoc-html/display/where.SWhere_TraitWhere_item-decl.html diff --git a/tests/rustdoc-html/where.alpha_trait_decl.html b/tests/rustdoc-html/display/where.alpha_trait_decl.html similarity index 100% rename from tests/rustdoc-html/where.alpha_trait_decl.html rename to tests/rustdoc-html/display/where.alpha_trait_decl.html diff --git a/tests/rustdoc-html/where.bravo_trait_decl.html b/tests/rustdoc-html/display/where.bravo_trait_decl.html similarity index 100% rename from tests/rustdoc-html/where.bravo_trait_decl.html rename to tests/rustdoc-html/display/where.bravo_trait_decl.html diff --git a/tests/rustdoc-html/where.charlie_fn_decl.html b/tests/rustdoc-html/display/where.charlie_fn_decl.html similarity index 100% rename from tests/rustdoc-html/where.charlie_fn_decl.html rename to tests/rustdoc-html/display/where.charlie_fn_decl.html diff --git a/tests/rustdoc-html/where.golf_type_alias_decl.html b/tests/rustdoc-html/display/where.golf_type_alias_decl.html similarity index 100% rename from tests/rustdoc-html/where.golf_type_alias_decl.html rename to tests/rustdoc-html/display/where.golf_type_alias_decl.html diff --git a/tests/rustdoc-html/where.rs b/tests/rustdoc-html/display/where.rs similarity index 100% rename from tests/rustdoc-html/where.rs rename to tests/rustdoc-html/display/where.rs diff --git a/tests/rustdoc-html/whitespace-after-where-clause.enum.html b/tests/rustdoc-html/display/whitespace-after-where-clause.enum.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.enum.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.enum.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.enum2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.enum2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.enum2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.enum2.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.rs b/tests/rustdoc-html/display/whitespace-after-where-clause.rs similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.rs rename to tests/rustdoc-html/display/whitespace-after-where-clause.rs diff --git a/tests/rustdoc-html/whitespace-after-where-clause.struct.html b/tests/rustdoc-html/display/whitespace-after-where-clause.struct.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.struct.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.struct.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.struct2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.struct2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.struct2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.struct2.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.trait.html b/tests/rustdoc-html/display/whitespace-after-where-clause.trait.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.trait.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.trait.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.trait2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.trait2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.trait2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.trait2.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.union.html b/tests/rustdoc-html/display/whitespace-after-where-clause.union.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.union.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.union.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.union2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.union2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.union2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.union2.html diff --git a/tests/rustdoc-html/auxiliary/rustdoc-ffi.rs b/tests/rustdoc-html/extern/auxiliary/rustdoc-ffi.rs similarity index 100% rename from tests/rustdoc-html/auxiliary/rustdoc-ffi.rs rename to tests/rustdoc-html/extern/auxiliary/rustdoc-ffi.rs diff --git a/tests/rustdoc-html/ffi.rs b/tests/rustdoc-html/extern/ffi.rs similarity index 100% rename from tests/rustdoc-html/ffi.rs rename to tests/rustdoc-html/extern/ffi.rs diff --git a/tests/rustdoc-html/foreigntype.rs b/tests/rustdoc-html/extern/foreigntype.rs similarity index 100% rename from tests/rustdoc-html/foreigntype.rs rename to tests/rustdoc-html/extern/foreigntype.rs diff --git a/tests/rustdoc-html/doc-hidden-crate.rs b/tests/rustdoc-html/hidden/doc-hidden-crate.rs similarity index 100% rename from tests/rustdoc-html/doc-hidden-crate.rs rename to tests/rustdoc-html/hidden/doc-hidden-crate.rs diff --git a/tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs b/tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs new file mode 100644 index 0000000000000..8c89c8d6c76c5 --- /dev/null +++ b/tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs @@ -0,0 +1,2 @@ +#![crate_name = "inner"] +pub struct SomeStruct; diff --git a/tests/rustdoc-html/auxiliary/reexp-stripped.rs b/tests/rustdoc-html/reexport/auxiliary/reexp-stripped.rs similarity index 100% rename from tests/rustdoc-html/auxiliary/reexp-stripped.rs rename to tests/rustdoc-html/reexport/auxiliary/reexp-stripped.rs diff --git a/tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs b/tests/rustdoc-html/reexport/duplicate-reexports-section-150211.rs similarity index 100% rename from tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs rename to tests/rustdoc-html/reexport/duplicate-reexports-section-150211.rs diff --git a/tests/rustdoc-html/hidden-methods.rs b/tests/rustdoc-html/reexport/hidden-methods.rs similarity index 100% rename from tests/rustdoc-html/hidden-methods.rs rename to tests/rustdoc-html/reexport/hidden-methods.rs diff --git a/tests/rustdoc-html/redirect.rs b/tests/rustdoc-html/reexport/redirect.rs similarity index 100% rename from tests/rustdoc-html/redirect.rs rename to tests/rustdoc-html/reexport/redirect.rs diff --git a/tests/rustdoc-html/cap-lints.rs b/tests/rustdoc-ui/lints/cap-lints.rs similarity index 84% rename from tests/rustdoc-html/cap-lints.rs rename to tests/rustdoc-ui/lints/cap-lints.rs index 30f9be0424c6a..692a63f2f7332 100644 --- a/tests/rustdoc-html/cap-lints.rs +++ b/tests/rustdoc-ui/lints/cap-lints.rs @@ -1,9 +1,11 @@ // This should fail a normal compile due to non_camel_case_types, // It should pass a doc-compile as it only needs to type-check and // therefore should not concern itself with the lints. + +//@ check-pass + #[deny(warnings)] -//@ has cap_lints/struct.Foo.html //* 'Foo' pub struct Foo { field: i32, } From 78aa1c866b14f20c334fd3b18818b775779c0a7a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 4 Oct 2026 22:11:50 +0200 Subject: [PATCH 20/59] Replace some `!has` checks in `rustdoc-html` test --- tests/rustdoc-html/reexport/hidden-methods.rs | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/rustdoc-html/reexport/hidden-methods.rs b/tests/rustdoc-html/reexport/hidden-methods.rs index ed9c1ee1aac29..4be81da1cf775 100644 --- a/tests/rustdoc-html/reexport/hidden-methods.rs +++ b/tests/rustdoc-html/reexport/hidden-methods.rs @@ -17,13 +17,24 @@ pub mod hidden { } //@ has foo/struct.Foo.html -//@ !hasraw - 'Methods' -//@ !has - '//code' 'impl Foo' -//@ !hasraw - 'this_should_be_hidden' +// Only `not_hidden` should be present. +//@ count - '//*[@id="implementations-list"]//*[@class="method"]' 1 +//@ has - '//*[@id="implementations-list"]//*[@class="method"]' 'pub fn not_hidden' +//@ count - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 1 +//@ has - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 'not_hidden' pub use hidden::Foo; +impl Foo { + pub fn not_hidden() {} +} + //@ has foo/struct.Bar.html -//@ !hasraw - 'Methods' -//@ !has - '//code' 'impl Bar' -//@ !hasraw - 'this_should_be_hidden' +//@ count - '//*[@id="implementations-list"]//*[@class="method"]' 1 +//@ has - '//*[@id="implementations-list"]//*[@class="method"]' 'pub fn not_hidden' +//@ count - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 1 +//@ has - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 'not_hidden' pub use hidden::Bar; + +impl Bar { + pub fn not_hidden() {} +} From 60afb4191406c16a0094ddc78b062a4e00a390d0 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 5 Oct 2026 17:48:59 -0700 Subject: [PATCH 21/59] ci: update to PowerShell 7.6.6 --- src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile b/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile index e7191aa31c47b..3552f4bc30e53 100644 --- a/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile +++ b/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile @@ -34,9 +34,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Install powershell (universal package) so we can test x.ps1 on Linux -# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep. -RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ - dpkg --ignore-depends=libicu72 -i powershell.deb && \ +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.6.6/powershell_7.6.6-1.deb_amd64.deb" > powershell.deb && \ + dpkg -i powershell.deb && \ rm -f powershell.deb COPY scripts/sccache.sh /scripts/ From f57e16de8b4f5c79fe2c31a5c770b5debfade633 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Mon, 21 Sep 2026 01:52:44 -0500 Subject: [PATCH 22/59] add `required_python_version` to jobs --- src/ci/citool/src/jobs.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index e371105ebdb01..b94f12a37cc77 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -31,6 +31,10 @@ pub struct Job { pub doc_url: Option, /// Whether the job is executed on AWS CodeBuild. pub codebuild: Option, + /// Which Python version (if any) is required. On Windows, this is typically required to run + /// LLDB. + #[serde(default)] + pub required_python_version: Option, } impl Job { @@ -167,6 +171,7 @@ fn validate_job_database(db: &JobDatabase) -> anyhow::Result<()> { free_disk, doc_url, codebuild, + required_python_version, // Carve-out configs allowed to be different. env: _, @@ -179,6 +184,7 @@ fn validate_job_database(db: &JobDatabase) -> anyhow::Result<()> { && *free_disk == auto_job.free_disk && *doc_url == auto_job.doc_url && *codebuild == auto_job.codebuild + && *required_python_version == auto_job.required_python_version { Ok(()) } else { @@ -244,6 +250,8 @@ struct GithubActionsJob { doc_url: Option, #[serde(skip_serializing_if = "Option::is_none")] codebuild: Option, + #[serde(skip_serializing_if = "Option::is_none")] + required_python_version: Option, } /// Replace GitHub context variables with environment variables in job configs. @@ -375,6 +383,7 @@ fn calculate_jobs( free_disk: job.free_disk, doc_url: job.doc_url, codebuild: job.codebuild, + required_python_version: job.required_python_version, } }) .collect(); From 9109556143d8a781d31621c927a6391746ef2039 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Tue, 6 Oct 2026 00:54:19 -0500 Subject: [PATCH 23/59] run LLDB debuginfo tests on Windows CI --- .github/workflows/ci.yml | 9 +++++++++ src/ci/github-actions/jobs.yml | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0f896724ae56..0c5c5fe46d394 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,6 +190,15 @@ jobs: - name: install ninja run: src/ci/scripts/install-ninja.sh + - name: install required Python version + # LLDB on Windows requires the same Python version it was built against to be the first + # discoverable Python in $env:PATH. Only install if we're actually running Windows tests + # that use LLDB + if: ${{ startsWith(matrix.os, 'windows') && matrix.required_python_version}} + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ matrix.required_python_version }} + - name: enable ipv6 on Docker # Don't run on codebuild because systemctl is not available if: ${{ !matrix.codebuild }} diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 57432451b9798..05e17c335aaf0 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -670,9 +670,12 @@ auto: # x86_64-msvc is split into two jobs to run tests in parallel. - name: test-x86_64-msvc-1 + # required to run LLDB 22 + required_python_version: '3.11' env: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler SCRIPT: make ci-msvc-py + LLDB_PATH: ./citools/clang-rust/bin/lldb.exe <<: *job-windows - name: test-x86_64-msvc-2 From e1a95eb0a930ec95cdd1802a677ed8ffbf226b90 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 6 Oct 2026 07:27:13 +0000 Subject: [PATCH 24/59] use the type name instead of `Self` in constructor paths again --- .../src/deriving/clone.rs | 9 +-- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 11 +-- .../rustc_builtin_macros/src/deriving/eq.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 2 +- .../src/deriving/generic/mod.rs | 77 +++++++++++++++---- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 2 +- .../derives/attr-macro-changes-type-kind.rs | 15 ++++ tests/ui/derives/auxiliary/struct-to-enum.rs | 18 +++++ tests/ui/derives/deriving-all-codegen.stdout | 56 ++++++++------ tests/ui/stats/macro-stats.stderr | 4 +- 13 files changed, 145 insertions(+), 57 deletions(-) create mode 100644 tests/ui/derives/attr-macro-changes-type-kind.rs create mode 100644 tests/ui/derives/auxiliary/struct-to-enum.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 370c0ceeda909..5c2c3052d1d51 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -147,7 +147,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -169,18 +169,17 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo cx.expr_call_global(field.span, fn_path.clone(), args) }; - let self_ident = Ident::new(kw::SelfUpper, trait_span); let ctor_path; let all_fields; let vdata; - match substr { + match substr.fields { Struct(vdata_, af) => { - ctor_path = cx.path(trait_span, vec![self_ident]); + ctor_path = cx.path(trait_span, vec![substr.type_ident]); all_fields = af; vdata = vdata_; } EnumMatching(.., variant, af) => { - ctor_path = cx.path(trait_span, vec![self_ident, variant.ident]); + ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]); all_fields = af; vdata = &variant.data; } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 2f3d2058773d8..d8355d733a7f3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -68,7 +68,7 @@ fn show_substructure( return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new()))); } - let (ident, vdata, fields) = match substr { + let (ident, vdata, fields) = match substr.fields { Struct(vdata, fields) => (type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 28526bdef6b9d..268153c1cbb31 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -37,9 +37,9 @@ pub(crate) fn expand_deriving_default( attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { - match substr { + match substr.fields { StaticStruct(variant_data) => { - default_struct_substructure(cx, trait_span, variant_data) + default_struct_substructure(cx, trait_span, variant_data, substr.type_ident) } StaticEnum(enum_def) => { default_enum_substructure(cx, trait_span, enum_def, item.span) @@ -67,15 +67,16 @@ fn default_struct_substructure( cx: &ExtCtxt<'_>, trait_span: Span, variant_data: &VariantData, + type_ident: Ident, ) -> BlockOrExpr { let expr = match variant_data { - VariantData::Unit(_) => cx.expr_ident(trait_span, Ident::new(kw::SelfUpper, trait_span)), + VariantData::Unit(_) => cx.expr_ident(trait_span, type_ident), VariantData::Tuple(fields, _) => { let exprs = fields .iter() .map(|field| default_call(cx, field.span.with_ctxt(trait_span.ctxt()))) .collect(); - cx.expr_call_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), exprs) + cx.expr_call_ident(trait_span, type_ident, exprs) } VariantData::Struct { fields, .. } => { let default_fields = fields @@ -95,7 +96,7 @@ fn default_struct_substructure( cx.field_imm(span, field.ident.unwrap(), value) }) .collect(); - cx.expr_struct_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), default_fields) + cx.expr_struct_ident(trait_span, type_ident, default_fields) } }; BlockOrExpr::new_expr(expr) diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index da38045994c7f..27be8a8cb6dff 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -72,7 +72,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<' } }; - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index df95ccd99f3e6..edd1cf75488fc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -88,7 +88,7 @@ pub(crate) fn expand_deriving_from( }; let self_kw = Ident::new(kw::SelfUpper, span); - let expr: Box = match substructure { + let expr: Box = match substructure.fields { StaticStruct(variant) => match variant { // Self { field: value } VariantData::Struct { .. } => cx.expr_struct_ident( diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 8b15920511aca..fbbadce3a8816 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -177,7 +177,7 @@ use std::ops::Not; use std::vec; -pub(crate) use Substructure::*; +pub(crate) use SubstructureFields::*; pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; @@ -281,8 +281,16 @@ pub(crate) struct FieldInfo { pub maybe_scalar: bool, } +pub(crate) struct Substructure<'a> { + pub fields: SubstructureFields<'a>, + // FIXME: this is currently required to avoid issues with attribute macros after derives, + // such as https://github.com/rust-lang/rust/issues/163800. + // Ideally we would just use `Self` instead. + pub type_ident: Ident, +} + /// A summary of the possible sets of fields. -pub(crate) enum Substructure<'a> { +pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), @@ -474,9 +482,15 @@ impl<'a> TraitDef<'a> { let fields = struct_def.fields().iter(); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticStruct(struct_def)) + method_def.call_substructure_method( + cx, + span, + StaticStruct(struct_def), + *ident, + ) } else { - method_def.expand_struct_method_body(cx, span, struct_def, is_packed) + method_def + .expand_struct_method_body(cx, span, struct_def, is_packed, *ident) }; method_def.create_method(cx, span, body) @@ -494,9 +508,9 @@ impl<'a> TraitDef<'a> { let fields = enum_def.variants.iter().flat_map(|variant| variant.data.fields()); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticEnum(enum_def)) + method_def.call_substructure_method(cx, span, StaticEnum(enum_def), *ident) } else { - method_def.expand_enum_method_body(cx, span, enum_def) + method_def.expand_enum_method_body(cx, span, enum_def, *ident) }; method_def.create_method(cx, span, body) @@ -778,9 +792,10 @@ impl<'a> MethodDef<'a> { &self, cx: &ExtCtxt<'_>, span: Span, - substructure: Substructure<'_>, + fields: SubstructureFields<'_>, + type_ident: Ident, ) -> BlockOrExpr { - (self.combine_substructure)(cx, span, substructure) + (self.combine_substructure)(cx, span, Substructure { fields, type_ident }) } fn is_static(&self) -> bool { @@ -906,12 +921,13 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, + type_ident: Ident, ) -> BlockOrExpr { let selflike_args = self.get_selflike_args(cx, span); let selflike_fields = create_struct_field_access_fields(span, cx, &selflike_args, struct_def, is_packed); - self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields)) + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), type_ident) } /// ``` @@ -954,6 +970,7 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, + type_ident: Ident, ) -> BlockOrExpr { let variants = &enum_def.variants; @@ -989,17 +1006,32 @@ impl<'a> MethodDef<'a> { // If the type is fieldless and the trait uses the discriminant and // there are multiple variants, we need just an operation on // the discriminant(s). - return self.call_substructure_method(cx, span, EnumDiscr(None)); + return self.call_substructure_method( + cx, + span, + EnumDiscr(None), + type_ident, + ); } FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => { - return self.call_substructure_method(cx, span, AllFieldlessEnum(enum_def)); + return self.call_substructure_method( + cx, + span, + AllFieldlessEnum(enum_def), + type_ident, + ); } FieldlessVariantsStrategy::Default => (), } } else if let [variant] = variants.as_slice() { // If there is a single variant, we don't need an operation on // the discriminant(s). Just use the most degenerate result. - return self.call_substructure_method(cx, span, EnumMatching(variant, Vec::new())); + return self.call_substructure_method( + cx, + span, + EnumMatching(variant, Vec::new()), + type_ident, + ); } } @@ -1039,8 +1071,9 @@ impl<'a> MethodDef<'a> { // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. let substructure = EnumMatching(variant, fields); - let arm_expr = - self.call_substructure_method(cx, span, substructure).into_expr(cx, span); + let arm_expr = self + .call_substructure_method(cx, span, substructure, type_ident) + .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) }) @@ -1052,8 +1085,13 @@ impl<'a> MethodDef<'a> { Some(v) if unify_fieldless_variants => { // We need a default case that handles all the fieldless variants. Some( - self.call_substructure_method(cx, span, EnumMatching(v, Vec::new())) - .into_expr(cx, span), + self.call_substructure_method( + cx, + span, + EnumMatching(v, Vec::new()), + type_ident, + ) + .into_expr(cx, span), ) } _ if variants.len() > 1 && selflike_args.len() > 1 => { @@ -1090,7 +1128,12 @@ impl<'a> MethodDef<'a> { // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method(cx, span, EnumDiscr(Some(get_match_expr(selflike_args)))) + self.call_substructure_method( + cx, + span, + EnumDiscr(Some(get_match_expr(selflike_args))), + type_ident, + ) } else { BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 3e0722988155c..db0e8efc99f3c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -65,7 +65,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> cx.stmt_expr(expr) }; - let (stmts, match_expr) = match substr { + let (stmts, match_expr) = match substr.fields { Struct(_, fields) | EnumMatching(.., fields) => { let stmts = fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 377a32dcca4f0..180800aa72025 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -119,7 +119,7 @@ fn get_substructure_equality_expr( span: Span, substructure: Substructure<'_>, ) -> BlockOrExpr { - BlockOrExpr::new_expr(match substructure { + BlockOrExpr::new_expr(match substructure.fields { EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field: &FieldInfo| { let rhs = field diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 8c3e2ee58f8e2..4ce695a16200f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -202,7 +202,7 @@ pub(crate) fn cmp_body( } }; - match substructure { + match substructure.fields { EnumMatching(.., all_fields) | Struct(_, all_fields) => { let op = |old, field: FieldInfo| { // The basic case: a field expression for one or more selflike args. E.g. diff --git a/tests/ui/derives/attr-macro-changes-type-kind.rs b/tests/ui/derives/attr-macro-changes-type-kind.rs new file mode 100644 index 0000000000000..98e05af3b33b6 --- /dev/null +++ b/tests/ui/derives/attr-macro-changes-type-kind.rs @@ -0,0 +1,15 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/163800, +//! where the generated code always referred to `Self`, which was invalid +//! when an attribute macro rewrites the type to an enum. + +//@ check-pass +//@ proc-macro: struct-to-enum.rs + +extern crate struct_to_enum; +use struct_to_enum::*; + +#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[struct_to_enum::phantom] +struct Spooky; + +fn main() {} diff --git a/tests/ui/derives/auxiliary/struct-to-enum.rs b/tests/ui/derives/auxiliary/struct-to-enum.rs new file mode 100644 index 0000000000000..458d8453d5076 --- /dev/null +++ b/tests/ui/derives/auxiliary/struct-to-enum.rs @@ -0,0 +1,18 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn phantom(_: TokenStream, _: TokenStream) -> TokenStream { + " +mod __value_Spooky { + pub use super::Spooky::Spooky; +} +pub enum Spooky { + __Phantom(std::marker::PhantomData), + Spooky, +} +pub use self::__value_Spooky::*; + " + .parse() + .unwrap() +} diff --git a/tests/ui/derives/deriving-all-codegen.stdout b/tests/ui/derives/deriving-all-codegen.stdout index 05412aca82360..163658d2106dd 100644 --- a/tests/ui/derives/deriving-all-codegen.stdout +++ b/tests/ui/derives/deriving-all-codegen.stdout @@ -46,7 +46,7 @@ impl ::core::fmt::Debug for Empty { #[automatically_derived] impl ::core::default::Default for Empty { #[inline] - fn default() -> Self { Self } + fn default() -> Self { Empty } } #[automatically_derived] impl ::core::hash::Hash for Empty { @@ -109,7 +109,7 @@ impl ::core::fmt::Debug for Point { impl ::core::default::Default for Point { #[inline] fn default() -> Self { - Self { + Point { x: ::core::default::Default::default(), y: ::core::default::Default::default(), } @@ -193,7 +193,7 @@ impl ::core::fmt::Debug for PackedPoint { impl ::core::default::Default for PackedPoint { #[inline] fn default() -> Self { - Self { + PackedPoint { x: ::core::default::Default::default(), y: ::core::default::Default::default(), } @@ -270,7 +270,9 @@ impl ::core::fmt::Debug for TupleSingleField { #[automatically_derived] impl ::core::default::Default for TupleSingleField { #[inline] - fn default() -> Self { Self(::core::default::Default::default()) } + fn default() -> Self { + TupleSingleField(::core::default::Default::default()) + } } #[automatically_derived] impl ::core::convert::From for TupleSingleField { @@ -343,7 +345,9 @@ impl ::core::fmt::Debug for SingleField { #[automatically_derived] impl ::core::default::Default for SingleField { #[inline] - fn default() -> Self { Self { foo: ::core::default::Default::default() } } + fn default() -> Self { + SingleField { foo: ::core::default::Default::default() } + } } #[automatically_derived] impl ::core::convert::From for SingleField { @@ -431,7 +435,7 @@ impl ::core::fmt::Debug for Big { impl ::core::default::Default for Big { #[inline] fn default() -> Self { - Self { + Big { b1: ::core::default::Default::default(), b2: ::core::default::Default::default(), b3: ::core::default::Default::default(), @@ -622,7 +626,7 @@ struct NonCopy(u32); #[automatically_derived] impl ::core::clone::Clone for NonCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { NonCopy(::core::clone::Clone::clone(&self.0)) } } // A packed struct that doesn't impl `Copy`, which means it gets the non-trivial @@ -632,7 +636,9 @@ struct PackedNonCopy(u32); #[automatically_derived] impl ::core::clone::Clone for PackedNonCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&{ self.0 })) } + fn clone(&self) -> Self { + PackedNonCopy(::core::clone::Clone::clone(&{ self.0 })) + } } // A struct that impls `Copy` manually, which means it gets the non-trivial @@ -641,7 +647,9 @@ struct ManualCopy(u32); #[automatically_derived] impl ::core::clone::Clone for ManualCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { + ManualCopy(::core::clone::Clone::clone(&self.0)) + } } impl Copy for ManualCopy {} @@ -652,7 +660,9 @@ struct PackedManualCopy(u32); #[automatically_derived] impl ::core::clone::Clone for PackedManualCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&{ self.0 })) } + fn clone(&self) -> Self { + PackedManualCopy(::core::clone::Clone::clone(&{ self.0 })) + } } impl Copy for PackedManualCopy {} @@ -725,7 +735,7 @@ impl ::core::clone::Clone for Generic where T::A: ::core::clone::Clone { #[inline] fn clone(&self) -> Self { - Self { + Generic { t: ::core::clone::Clone::clone(&self.t), ta: ::core::clone::Clone::clone(&self.ta), u: ::core::clone::Clone::clone(&self.u), @@ -751,7 +761,7 @@ impl T::A: ::core::default::Default { #[inline] fn default() -> Self { - Self { + Generic { t: ::core::default::Default::default(), ta: ::core::default::Default::default(), u: ::core::default::Default::default(), @@ -844,7 +854,7 @@ impl Self { - Self(::core::clone::Clone::clone(&{ self.0 }), + PackedGeneric(::core::clone::Clone::clone(&{ self.0 }), ::core::clone::Clone::clone(&{ self.1 }), ::core::clone::Clone::clone(&{ self.2 })) } @@ -871,7 +881,7 @@ impl T::A: ::core::default::Default { #[inline] fn default() -> Self { - Self(::core::default::Default::default(), + PackedGeneric(::core::default::Default::default(), ::core::default::Default::default(), ::core::default::Default::default()) } @@ -1019,7 +1029,7 @@ impl ::core::clone::Clone for Enum1 { fn clone(&self) -> Self { match self { Self::Single { x: __self_0 } => - Self::Single { x: ::core::clone::Clone::clone(__self_0) }, + Enum1::Single { x: ::core::clone::Clone::clone(__self_0) }, } } } @@ -1093,7 +1103,7 @@ enum Fieldless1 { #[automatically_derived] impl ::core::clone::Clone for Fieldless1 { #[inline] - fn clone(&self) -> Self { Self::A } + fn clone(&self) -> Self { Fieldless1::A } } #[automatically_derived] impl ::core::fmt::Debug for Fieldless1 { @@ -1408,11 +1418,11 @@ impl ::core::clone::Clone for Fielded { fn clone(&self) -> Self { match self { Self::X(__self_0) => - Self::X(::core::clone::Clone::clone(__self_0)), + Fielded::X(::core::clone::Clone::clone(__self_0)), Self::Y(__self_0) => - Self::Y(::core::clone::Clone::clone(__self_0)), + Fielded::Y(::core::clone::Clone::clone(__self_0)), Self::Z(__self_0) => - Self::Z(::core::clone::Clone::clone(__self_0)), + Fielded::Z(::core::clone::Clone::clone(__self_0)), } } } @@ -1511,9 +1521,9 @@ impl ::core::clone::Clone fn clone(&self) -> Self { match self { Self::One(__self_0) => - Self::One(::core::clone::Clone::clone(__self_0)), + EnumGeneric::One(::core::clone::Clone::clone(__self_0)), Self::Two(__self_0) => - Self::Two(::core::clone::Clone::clone(__self_0)), + EnumGeneric::Two(::core::clone::Clone::clone(__self_0)), } } } @@ -1712,7 +1722,9 @@ impl ::core::marker::Copy for FooCloneAndCopy { } #[automatically_derived] impl ::core::clone::Clone for FooCloneAndCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { + FooCloneAndCopy(::core::clone::Clone::clone(&self.0)) + } } struct FooPartialOrdOrd(i32); diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index efc3785878c39..e549d315e7fdb 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -2,11 +2,11 @@ macro-stats ==================================================================== macro-stats MACRO EXPANSION STATS: macro_stats macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes macro-stats ----------------------------------------------------------------------------------- -macro-stats #[derive(Clone)] 8 67 8.4 1_909 238.6 +macro-stats #[derive(Clone)] 8 67 8.4 1_895 236.9 macro-stats #[derive(Hash)] 2 17 8.5 536 268.0 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 505 505.0 -macro-stats #[derive(Default)] 2 16 8.0 409 204.5 +macro-stats #[derive(Default)] 2 16 8.0 407 203.5 macro-stats #[derive(Eq)] 1 11 11.0 312 312.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 269 269.0 From aec15eebbab119e3fcc06cdf252de74c742f5775 Mon Sep 17 00:00:00 2001 From: jyn Date: Tue, 6 Oct 2026 09:55:57 +0200 Subject: [PATCH 25/59] Remove CLAUDE.md Claude Code loads AGENTS.md since 2.1.277, released September 18. See https://code.claude.com/docs/en/changelog#2-1-277. --- CLAUDE.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 43c994c2d3617..0000000000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md From 2553cca6ed507337710e2bb4ac59ef79066eb9a6 Mon Sep 17 00:00:00 2001 From: b1yd <2156864690@qq.com> Date: Tue, 6 Oct 2026 16:31:21 +0800 Subject: [PATCH 26/59] add if-installed:auto:spellcheck to pre-push script --- src/etc/pre-push.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh index fb2007db9f12c..6304fabbbf6f5 100755 --- a/src/etc/pre-push.sh +++ b/src/etc/pre-push.sh @@ -35,7 +35,7 @@ echo "Running pre-push script $ROOT_DIR/x test tidy" cd "$ROOT_DIR" ./x test tidy \ --set build.locked-deps=true \ - --extra-checks auto:py,auto:cpp,auto:js + --extra-checks auto:py,auto:cpp,auto:js,if-installed:auto:spellcheck if [ $? -ne 0 ]; then echo "You may use \`git push --no-verify\` to skip this check." exit 1 From b71426dd949836796c29261c625c11cd383d741d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 6 Oct 2026 12:38:42 +0200 Subject: [PATCH 27/59] Add regression test for duplicated rustdoc search results between std and core --- tests/rustdoc-js-std/core-std-duplicates.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/rustdoc-js-std/core-std-duplicates.js diff --git a/tests/rustdoc-js-std/core-std-duplicates.js b/tests/rustdoc-js-std/core-std-duplicates.js new file mode 100644 index 0000000000000..4647ec6408746 --- /dev/null +++ b/tests/rustdoc-js-std/core-std-duplicates.js @@ -0,0 +1,21 @@ +// This test ensures that search results are not duplicated between `std` and `core`. +// Regression test for . + +// exact-check + +const EXPECTED = [ + { + 'query': 'primitive:char', + 'others': [ + { 'path': 'std', 'name': 'char' }, + ], + }, + { + 'query': 'char->u32', + 'others': [ + { 'path': 'std::u32', 'name': 'from' }, + { 'path': 'std::char', 'name': 'to_u32' }, + { 'path': 'std::char', 'name': 'to_digit' }, + ], + }, +]; From 87ec21a3e7f9ad0d40c6073475977eafd92c3ad8 Mon Sep 17 00:00:00 2001 From: Max Dexheimer Date: Mon, 5 Oct 2026 15:09:28 +0200 Subject: [PATCH 28/59] Adjust the adjustment to wasi TLS to no longer adjust --- library/std/src/sys/thread_local/mod.rs | 8 ++++---- src/doc/rustc/src/platform-support/wasm32-wasip1.md | 4 ++-- tests/run-make/wasm-panic-small/rmake.rs | 6 +++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 809ef5cfe9c60..f86d25e38efb5 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -35,7 +35,7 @@ cfg_select! { any( - all(target_family = "wasm", not(target_feature = "atomics"), not(target_env = "p3")), + all(target_family = "wasm", not(target_feature = "atomics"), not(target_os = "wasi")), target_os = "uefi", target_os = "zkvm", target_os = "trusty", @@ -66,7 +66,7 @@ cfg_select! { /// single callback that runs all of the destructors in the list. #[cfg(all( target_thread_local, - not(all(target_family = "wasm", not(target_feature = "atomics"), not(target_env = "p3"))) + not(all(target_family = "wasm", not(target_feature = "atomics"), not(target_os = "wasi"))) ))] pub(crate) mod destructors { cfg_select! { @@ -106,7 +106,7 @@ pub(crate) mod guard { pub(crate) use windows::enable; } any( - all(target_family = "wasm", not(target_env = "p3")), + all(target_family = "wasm", not(target_os = "wasi")), target_os = "uefi", target_os = "zkvm", target_os = "trusty", @@ -154,7 +154,7 @@ pub(crate) mod key { all(not(target_vendor = "apple"), not(target_family = "wasm"), target_family = "unix"), all(not(target_thread_local), target_vendor = "apple"), target_os = "teeos", - all(target_os = "wasi", target_env = "p3"), + target_os = "wasi", ) => { mod racy; mod unix; diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 16499659291a0..3cc0f5a96c597 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -73,13 +73,13 @@ be used instead. ## Building the target in rustc To build this target first acquire a copy of [`wasi-sdk`]. At this time version -33 is the minimum needed. +34 is the minimum needed. Next configure the `WASI_SDK_PATH` environment variable to point to where this is installed. For example: ```text -export WASI_SDK_PATH=/path/to/wasi-sdk-33.0 +export WASI_SDK_PATH=/path/to/wasi-sdk-34.0 ``` Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld` diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index f6504830a5263..64c17571437c5 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -24,5 +24,9 @@ fn test(cfg: &str) { let bytes = rfs::read("foo.wasm"); println!("{}", bytes.len()); - assert!(bytes.len() < 45_000, "bytes len was: {}", bytes.len()); + assert!( + bytes.len() < 50_000, + "wasm binary was larger than expected. size in bytes: {}", + bytes.len() + ); } From 3bc8827f723573b413ff0e5eabec215d979f8093 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 15:27:32 +0200 Subject: [PATCH 29/59] continue next-solver crashes triage --- tests/crashes/126680.rs | 25 --------------- tests/crashes/140850.rs | 7 ---- ...n-closure-capture-ice-119786-1.next.stderr | 0 .../in-closure-capture-ice-119786-1.rs | 0 .../in-closure-capture-ice-119786-2.rs | 0 .../in-closure-capture-ice-119786-3.rs | 0 ...atible-closure-captures-field-of-opaque.rs | 0 .../switch-int-terminator-126680.next.stderr | 21 ++++++++++++ .../switch-int-terminator-126680.rs | 32 +++++++++++++++++++ .../switch-int-terminator-140850.rs | 21 ++++++++++++ 10 files changed, 74 insertions(+), 32 deletions(-) delete mode 100644 tests/crashes/126680.rs delete mode 100644 tests/crashes/140850.rs rename tests/ui/impl-trait/{closures => normalize-hir-typeck}/in-closure-capture-ice-119786-1.next.stderr (100%) rename tests/ui/impl-trait/{closures => normalize-hir-typeck}/in-closure-capture-ice-119786-1.rs (100%) rename tests/ui/impl-trait/{closures => normalize-hir-typeck}/in-closure-capture-ice-119786-2.rs (100%) rename tests/ui/impl-trait/{closures => normalize-hir-typeck}/in-closure-capture-ice-119786-3.rs (100%) rename tests/ui/impl-trait/{closures => normalize-hir-typeck}/incompatible-closure-captures-field-of-opaque.rs (100%) create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.next.stderr create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.rs create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs diff --git a/tests/crashes/126680.rs b/tests/crashes/126680.rs deleted file mode 100644 index dcb6ccad6b422..0000000000000 --- a/tests/crashes/126680.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ known-bug: rust-lang/rust#126680 -//@ compile-flags: -Zvalidate-mir -#![feature(type_alias_impl_trait)] -type Bar = impl std::fmt::Display; - -use std::path::Path; - -struct A { - pub func: fn(check: Bar, b: Option<&Path>), -} - -#[define_opaque(Bar)] -fn foo() -> A { - A { - func: |check, b| { - if check { - () - } else if let Some(_) = b.and_then(|p| p.parent()) { - () - } - }, - } -} - -fn main() {} diff --git a/tests/crashes/140850.rs b/tests/crashes/140850.rs deleted file mode 100644 index fd26097deda00..0000000000000 --- a/tests/crashes/140850.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #140850 -//@ compile-flags: -Zvalidate-mir -fn A() -> impl { - while A() {} - loop {} -} -fn main() {} diff --git a/tests/ui/impl-trait/closures/in-closure-capture-ice-119786-1.next.stderr b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-1.next.stderr similarity index 100% rename from tests/ui/impl-trait/closures/in-closure-capture-ice-119786-1.next.stderr rename to tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-1.next.stderr diff --git a/tests/ui/impl-trait/closures/in-closure-capture-ice-119786-1.rs b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-1.rs similarity index 100% rename from tests/ui/impl-trait/closures/in-closure-capture-ice-119786-1.rs rename to tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-1.rs diff --git a/tests/ui/impl-trait/closures/in-closure-capture-ice-119786-2.rs b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-2.rs similarity index 100% rename from tests/ui/impl-trait/closures/in-closure-capture-ice-119786-2.rs rename to tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-2.rs diff --git a/tests/ui/impl-trait/closures/in-closure-capture-ice-119786-3.rs b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-3.rs similarity index 100% rename from tests/ui/impl-trait/closures/in-closure-capture-ice-119786-3.rs rename to tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-119786-3.rs diff --git a/tests/ui/impl-trait/closures/incompatible-closure-captures-field-of-opaque.rs b/tests/ui/impl-trait/normalize-hir-typeck/incompatible-closure-captures-field-of-opaque.rs similarity index 100% rename from tests/ui/impl-trait/closures/incompatible-closure-captures-field-of-opaque.rs rename to tests/ui/impl-trait/normalize-hir-typeck/incompatible-closure-captures-field-of-opaque.rs diff --git a/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.next.stderr b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.next.stderr new file mode 100644 index 0000000000000..47550ef9db818 --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.next.stderr @@ -0,0 +1,21 @@ +error[E0391]: cycle detected when computing type of `Bar::{opaque#0}` + --> $DIR/switch-int-terminator-126680.rs:17:12 + | +LL | type Bar = impl Sized; + | ^^^^^^^^^^ + | + = note: ...which requires computing type of opaque `Bar::{opaque#0}`... +note: ...which requires borrow-checking `foo`... + --> $DIR/switch-int-terminator-126680.rs:26:1 + | +LL | fn foo() -> Struct { + | ^^^^^^^^^^^^^^^^^^ + = note: ...which requires promoting constants in MIR for `foo`... + = note: ...which requires normalizing `fn(Bar)`... + = note: ...which again requires computing type of `Bar::{opaque#0}`, completing the cycle + = note: cycle used when checking that `Bar::{opaque#0}` is well-formed + = note: for more information, see and + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.rs b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.rs new file mode 100644 index 0000000000000..bb8e34ff35140 --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-126680.rs @@ -0,0 +1,32 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] known-bug: trait-system-refactor-initiative#303 +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #126680 +//@ compile-flags: -Zvalidate-mir +//@ edition:2021 + +// This ICE'd with the old solver as MIR build resulted in an opaque type +// as the argument to a `SwitchInt` terminator. Fixed by normalizing opaque +// types in their defining scope. Regression test for #126680. This should +// compile. + +#![feature(type_alias_impl_trait)] +type Bar = impl Sized; + +use std::path::Path; + +struct Struct { + pub func: fn(check: Bar), +} + +#[define_opaque(Bar)] +fn foo() -> Struct { + Struct { + func: |check| if check { () } else { () }, + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs new file mode 100644 index 0000000000000..513e4e382a4d9 --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs @@ -0,0 +1,21 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #140850 +//@[next] check-pass +//@ compile-flags: -Zvalidate-mir +//@ edition:2021 + +// This ICE'd with the old solver as MIR build resulted in an opaque type +// as the argument to a `SwitchInt` terminator. Fixed by normalizing opaque +// types in their defining scope. Regression test for #140850. + +fn foo() -> impl Sized { + if false { + while foo() {} + } + loop {} +} +fn main() {} From 5c5254e6e79f5498c82df2462a161f2951594905 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 15:45:48 +0200 Subject: [PATCH 30/59] cont tests/crashes migration --- tests/crashes/125553.rs | 15 ----------- .../in-closure-capture-ice-125553.rs | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) delete mode 100644 tests/crashes/125553.rs create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs diff --git a/tests/crashes/125553.rs b/tests/crashes/125553.rs deleted file mode 100644 index 142c06775bb87..0000000000000 --- a/tests/crashes/125553.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: rust-lang/rust#125553 -//@ edition:2021 - -#[derive(Copy, Clone)] -struct Foo((u32, u32)); - -fn main() { - type T = impl Copy(Copy, Clone) - let foo: T = Foo((1u32, 1u32)); - let x = move || { - let derive = move || { - let Foo((a, b)) = foo; - }; - }; -} diff --git a/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs new file mode 100644 index 0000000000000..052b82a4056eb --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs @@ -0,0 +1,26 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #125553 +//@[next] check-pass +//@ edition:2021 + +#![feature(type_alias_impl_trait)] + +#[derive(Copy, Clone)] +struct Foo(i32); + +// This ICEd during MIR building with the old solver. It's fixed by normalizing +// opaque types with the new solver. + +fn main() { + type T = impl Copy; + let foo: T = Foo(1); + let x = move || { + let derive = move || { + let Foo(a) = foo; + }; + }; +} From ee6d48c3516e92567dd808b0efeed0b474a98aa4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 15:48:59 +0200 Subject: [PATCH 31/59] remove duplicate test --- tests/crashes/123157.rs | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 tests/crashes/123157.rs diff --git a/tests/crashes/123157.rs b/tests/crashes/123157.rs deleted file mode 100644 index d6cc55ba0524e..0000000000000 --- a/tests/crashes/123157.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #123157 -//@ edition:2021 -#![feature(type_alias_impl_trait)] - -#[derive(Copy, Clone)] -struct Foo((u32, u32)); - -fn main() { - type T = impl Copy; - let foo: T = Foo((1u32, 2u32)); - let x = move || { - let x = move || { - let Foo((a, b)) = foo; - }; - }; -} From d84ec36d7226784bd3cf2962dac72c2eb695640f Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:00:02 +0200 Subject: [PATCH 32/59] more things which no longer ICE --- tests/crashes/131886.rs | 15 ----------- .../trait-upcasting-131886.next.stderr | 20 +++++++++++++++ .../trait-upcasting-131886.rs | 25 +++++++++++++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) delete mode 100644 tests/crashes/131886.rs create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.next.stderr create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.rs diff --git a/tests/crashes/131886.rs b/tests/crashes/131886.rs deleted file mode 100644 index 16cb815f1c223..0000000000000 --- a/tests/crashes/131886.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #131886 -//@ compile-flags: -Zvalidate-mir -#![feature(type_alias_impl_trait)] - -type Tait = impl Sized; - -trait Foo<'a>: Bar<'a, 'a, Tait> {} -trait Bar<'a, 'b, T> {} - -#[define_opaque(Tait)] -fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) { - let _ = x as &dyn Bar<'_, '_, ()>; -} - -fn main() {} diff --git a/tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.next.stderr b/tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.next.stderr new file mode 100644 index 0000000000000..e46f78337a6f3 --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.next.stderr @@ -0,0 +1,20 @@ +error[E0391]: cycle detected when computing type of `Tait::{opaque#0}` + --> $DIR/trait-upcasting-131886.rs:15:13 + | +LL | type Tait = impl Sized; + | ^^^^^^^^^^ + | + = note: ...which requires computing type of opaque `Tait::{opaque#0}`... +note: ...which requires borrow-checking `test_correct3`... + --> $DIR/trait-upcasting-131886.rs:21:1 + | +LL | fn test_correct3(x: &dyn Foo) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires promoting constants in MIR for `test_correct3`... + = note: ...which again requires computing type of `Tait::{opaque#0}`, completing the cycle + = note: cycle used when checking that `Tait::{opaque#0}` is well-formed + = note: for more information, see and + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.rs b/tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.rs new file mode 100644 index 0000000000000..3f506a7f5f65e --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/trait-upcasting-131886.rs @@ -0,0 +1,25 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] known-bug: trait-system-refactor-initiative#303 +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #131886 +//@ compile-flags: -Zvalidate-mir +#![feature(type_alias_impl_trait)] + +// This ICEd in MIR validation with the old solver. It's fixed by normalizing +// opaque types with the new solver. This should compile, but currently fails +// with a query cycle error. + +type Tait = impl Sized; + +trait Foo: Bar {} +trait Bar {} + +#[define_opaque(Tait)] +fn test_correct3(x: &dyn Foo) { + _ = x as &dyn Bar<()>; +} + +fn main() {} From b7763ca1e0a2f5cc0e69faacb7b37463370b3eed Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:05:20 +0200 Subject: [PATCH 33/59] more next-solver crashes migration --- tests/crashes/135617.rs | 13 ---------- ...normalize-fully-concrete-const.next.stderr | 9 +++++++ .../cant-normalize-fully-concrete-const.rs | 24 +++++++++++++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) delete mode 100644 tests/crashes/135617.rs create mode 100644 tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.next.stderr create mode 100644 tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs diff --git a/tests/crashes/135617.rs b/tests/crashes/135617.rs deleted file mode 100644 index ac524b823a089..0000000000000 --- a/tests/crashes/135617.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #135617 -trait Project { - const ASSOC: usize; -} - -fn foo() -where - for<'a> (): Project, -{ - [(); <() as Project>::ASSOC]; -} - -pub fn main() {} diff --git a/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.next.stderr b/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.next.stderr new file mode 100644 index 0000000000000..ba1b523146c51 --- /dev/null +++ b/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/cant-normalize-fully-concrete-const.rs:20:6 + | +LL | [(); <() as Project>::ASSOC]; + | ^^ cannot infer the value of the constant `_` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs b/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs new file mode 100644 index 0000000000000..3ca4976b19195 --- /dev/null +++ b/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs @@ -0,0 +1,24 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #135617 + +// The bound `for<'a> (): Project` prevents us from normalizing the +// array length. This caused and ICE with the new solver. The actual +// behavior doesn't really matter here as long as it doesn't ICE. + +trait Project { + const ASSOC: usize; +} + +fn foo() +where + for<'a> (): Project, +{ + [(); <() as Project>::ASSOC]; + //[next]~^ ERROR: type annotations needed +} + +pub fn main() {} From e79214f82e6e69b83c97b61cbee6b99e9b5cd96c Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:23:11 +0200 Subject: [PATCH 34/59] more crashes tests --- .../old-solver-hr-alias-norm-not-idempotent.rs} | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) rename tests/{crashes/129372.rs => ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent.rs} (63%) diff --git a/tests/crashes/129372.rs b/tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent.rs similarity index 63% rename from tests/crashes/129372.rs rename to tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent.rs index 824e6fbfc4dd0..ae407a91a0da7 100644 --- a/tests/crashes/129372.rs +++ b/tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent.rs @@ -1,7 +1,19 @@ -//@ known-bug: #129372 +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] build-pass +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] build-fail +//@[old] known-bug: #129372 //@ compile-flags: -Cdebuginfo=2 -Copt-level=0 //@ ignore-backends: gcc +// Regression test for #129372. With the old solver normalizing +// the output of `v.method()` ended up not fully normalizing some +// higher-ranked associated type. This then resulted in some mismatch +// later on. Fixed by the new trait solver. + pub struct Wrapper(T); struct Struct; From be29dc2296b4b96b617751a6329ed34d86170e91 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:29:45 +0200 Subject: [PATCH 35/59] more tests :3 --- tests/crashes/134838.rs | 14 ----------- .../field-access-on-type-ascription-134838.rs | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) delete mode 100644 tests/crashes/134838.rs create mode 100644 tests/ui/impl-trait/normalize-hir-typeck/field-access-on-type-ascription-134838.rs diff --git a/tests/crashes/134838.rs b/tests/crashes/134838.rs deleted file mode 100644 index ac8af09b31bbd..0000000000000 --- a/tests/crashes/134838.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #134838 -#![feature(type_ascription)] -#![allow(dead_code)] - -struct Ty(()); - -fn mk() -> impl Sized { - if false { - let _ = type_ascribe!(mk(), Ty).0; - } - Ty(()) -} - -fn main() {} diff --git a/tests/ui/impl-trait/normalize-hir-typeck/field-access-on-type-ascription-134838.rs b/tests/ui/impl-trait/normalize-hir-typeck/field-access-on-type-ascription-134838.rs new file mode 100644 index 0000000000000..ad8036bf5103d --- /dev/null +++ b/tests/ui/impl-trait/normalize-hir-typeck/field-access-on-type-ascription-134838.rs @@ -0,0 +1,24 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #134838 +#![feature(type_ascription)] +#![allow(dead_code)] + +// Regression test for #134838. This ICEd during MIR borrowck with the +// old solver. Fixed by eagerly normalizing opaque types with the new +// solver. + +struct Ty(()); + +fn mk() -> impl Sized { + if false { + let _ = type_ascribe!(mk(), Ty).0; + } + Ty(()) +} + +fn main() {} From 88cd166aaebafa2f2eb83cfb1373dab327573bd9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:37:57 +0200 Subject: [PATCH 36/59] one more crashes test --- ...old-solver-hr-alias-norm-not-idempotent-129372.rs} | 0 ...old-solver-hr-alias-norm-not-idempotent-131373.rs} | 11 ++++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) rename tests/ui/traits/next-solver/normalize/{old-solver-hr-alias-norm-not-idempotent.rs => old-solver-hr-alias-norm-not-idempotent-129372.rs} (100%) rename tests/{crashes/131373.rs => ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent-131373.rs} (61%) diff --git a/tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent.rs b/tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent-129372.rs similarity index 100% rename from tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent.rs rename to tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent-129372.rs diff --git a/tests/crashes/131373.rs b/tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent-131373.rs similarity index 61% rename from tests/crashes/131373.rs rename to tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent-131373.rs index 661fecd7620b8..b2d0010289909 100644 --- a/tests/crashes/131373.rs +++ b/tests/ui/traits/next-solver/normalize/old-solver-hr-alias-norm-not-idempotent-131373.rs @@ -1,4 +1,13 @@ -//@ known-bug: #131373 +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] build-pass +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #131373 + +// Regression test for #131373. The old solver didn't fully normalize +// aliases with escaping bound vars, resulting in an ICE in MIR borrowck. trait LockReference: 'static { type Ref<'a>; From 24adadcc9500ba6f51af67108d1abbb1477f93a1 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:52:35 +0200 Subject: [PATCH 37/59] remove duplicate test --- tests/crashes/136666.rs | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 tests/crashes/136666.rs diff --git a/tests/crashes/136666.rs b/tests/crashes/136666.rs deleted file mode 100644 index 5cfed65fdf91a..0000000000000 --- a/tests/crashes/136666.rs +++ /dev/null @@ -1,36 +0,0 @@ -//@ known-bug: #136666 -// Needed so that rust can infer that the A in what() is &() -trait IsRef {} -struct Dummy; -impl<'a> IsRef<&'a ()> for Dummy {} - -trait WithLifetime { - type Output<'a>; -} -impl<'t> WithLifetime for &'t () { - type Output<'a> = &'a (); -} - -// Needed to prevent the two Foo impls from overlapping -struct Wrap(A); - -trait Unimplemented {} - -trait Foo {} -impl Foo for T where T: Unimplemented {} -impl Foo for Wrap -where - Dummy: IsRef, - for<'a> A: WithLifetime = A>, -{ -} - -fn what() -where - Wrap: Foo, -{ -} - -fn main() { - what(); -} From 9bf73a1322d2bbc79d55434ced46c08e3b4d4348 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 16:57:58 +0200 Subject: [PATCH 38/59] more crashes tests --- tests/crashes/127033.rs | 18 ----------- ...ing-use-return-hir-typeck-ty-ice-127033.rs | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 18 deletions(-) delete mode 100644 tests/crashes/127033.rs create mode 100644 tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs diff --git a/tests/crashes/127033.rs b/tests/crashes/127033.rs deleted file mode 100644 index 52b880e4859b8..0000000000000 --- a/tests/crashes/127033.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #127033 -//@ edition: 2021 - -pub trait RaftLogStorage { - fn save_vote(vote: ()) -> impl std::future::Future + Send; -} - -struct X; -impl RaftLogStorage for X { - fn save_vote(vote: ()) -> impl std::future::Future { - loop {} - async { - vote - } - } -} - -fn main() {} diff --git a/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs b/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs new file mode 100644 index 0000000000000..4b99ff285b525 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs @@ -0,0 +1,32 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #127033 +//@ edition: 2021 + +// Regression test for #127033. In the old solver this test only constrained +// the RPIT in dead code, causing MIR typeck to not define it at all. +// +// This then caused us to use the type inferred by HIR typeck, later resulting in +// ICE when leaking `'erased` to parts of the compiler which didn't expect it. +// +// cc trait-system-refactor-initiative#170 + +pub trait RaftLogStorage { + fn save_vote(vote: ()) -> impl std::future::Future + Send; +} + +struct X; +impl RaftLogStorage for X { + fn save_vote(vote: ()) -> impl std::future::Future { + loop {} + async { + vote + } + } +} + +fn main() {} From c9304053b4e1722ee7c470300dc3d2762744c115 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 17:09:26 +0200 Subject: [PATCH 39/59] remove duplicate crashes test --- tests/crashes/130797.rs | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 tests/crashes/130797.rs diff --git a/tests/crashes/130797.rs b/tests/crashes/130797.rs deleted file mode 100644 index e9c877d92a6e9..0000000000000 --- a/tests/crashes/130797.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #130797 - -trait Transform { - type Output<'a>; -} -trait Propagate {} -trait AddChild { - fn add_child(&self) {} -} - -pub struct Node(T); -impl AddChild Propagate>>> for Node where T: Transform {} - -fn make_graph_root() { - Node(Dummy).add_child() -} - -struct Dummy; -impl Transform for Dummy { - type Output<'a> = (); -} - -pub fn main() {} From 7400ef05edeec5b99da881ac70f021c914cb32e8 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 17:44:13 +0200 Subject: [PATCH 40/59] continue crashes triage --- tests/crashes/135122.rs | 24 ----------- ...results-in-unconstrained-infer.next.stderr | 41 +++++++++++++++++++ .../success-results-in-unconstrained-infer.rs | 38 +++++++++++++++++ 3 files changed, 79 insertions(+), 24 deletions(-) delete mode 100644 tests/crashes/135122.rs create mode 100644 tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.next.stderr create mode 100644 tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.rs diff --git a/tests/crashes/135122.rs b/tests/crashes/135122.rs deleted file mode 100644 index 77d943f23b47e..0000000000000 --- a/tests/crashes/135122.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #135122 -trait Add { - type Output; - fn add(_: (), _: Self::Output) {} -} - -trait IsSame { - type Assoc; -} - -trait Data { - type Elem; -} - -impl IsSame for f32 where f32: IsSame {} - -impl Add for i64 -where - f32: IsSame, - i8: Data, -{ - type Output = >::Assoc; - fn add(_: Data, _: Self::Output) {} -} diff --git a/tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.next.stderr b/tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.next.stderr new file mode 100644 index 0000000000000..ab3183f129bc1 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.next.stderr @@ -0,0 +1,41 @@ +error[E0425]: cannot find type `Missing` in this scope + --> $DIR/success-results-in-unconstrained-infer.rs:35:15 + | +LL | fn add(_: Missing, _: Self::Output) {} + | ^^^^^^^ not found in this scope + +error[E0046]: not all trait items implemented, missing: `Assoc` + --> $DIR/success-results-in-unconstrained-infer.rs:25:1 + | +LL | type Assoc; + | ---------- `Assoc` from trait +... +LL | impl IsSame for f32 where f32: IsSame {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation + +error[E0207]: the type parameter `B` is not constrained by the impl trait, self type, or predicates + --> $DIR/success-results-in-unconstrained-infer.rs:25:6 + | +LL | impl IsSame for f32 where f32: IsSame {} + | ^ unconstrained type parameter + +error[E0277]: the trait bound `i8: Data` is not satisfied + --> $DIR/success-results-in-unconstrained-infer.rs:31:5 + | +LL | i8: Data, + | ^^^^^^^^^^^^^^^^^^ the trait `Data` is not implemented for `i8` + | +help: this trait has no implementations, consider adding one + --> $DIR/success-results-in-unconstrained-infer.rs:21:1 + | +LL | trait Data { + | ^^^^^^^^^^ +help: add `#![feature(trivial_bounds)]` to the crate attributes to enable + | +LL + #![feature(trivial_bounds)] + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0046, E0207, E0277, E0425. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.rs b/tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.rs new file mode 100644 index 0000000000000..c0bac5c19fb5c --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/success-results-in-unconstrained-infer.rs @@ -0,0 +1,38 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #135122 + +// A regression test for #135122. The old solver normalized `::Output` to +// an inference variable without having any stalled or failed obligation. This caused +// us to then compute the implied bounds for that inference variable, causing an ICE. + +trait Add { + type Output; + fn add(_: (), _: Self::Output) {} +} + +trait IsSame { + type Assoc; +} + +trait Data { + type Elem; +} + +impl IsSame for f32 where f32: IsSame {} +//[next]~^ ERROR: not all trait items implemented, missing: `Assoc` +//[next]~| ERROR: the type parameter `B` is not constrained by the impl trait, self type, or predicates +impl Add for i64 +where + f32: IsSame, + i8: Data, + //[next]~^ ERROR: the trait bound `i8: Data` is not satisfied +{ + type Output = >::Assoc; + fn add(_: Missing, _: Self::Output) {} + //[next]~^ ERROR: cannot find type `Missing` in this scope +} +fn main() {} From c98419234ad87bf48df513db5fc427b68a8a6656 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 23:22:24 +0200 Subject: [PATCH 41/59] crashes issue triage --- .../old-solver-projection-cache-bug-135718.rs} | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) rename tests/{crashes/135718.rs => ui/traits/next-solver/normalize/old-solver-projection-cache-bug-135718.rs} (66%) diff --git a/tests/crashes/135718.rs b/tests/ui/traits/next-solver/normalize/old-solver-projection-cache-bug-135718.rs similarity index 66% rename from tests/crashes/135718.rs rename to tests/ui/traits/next-solver/normalize/old-solver-projection-cache-bug-135718.rs index c0e628f4c46c3..839579b81c81b 100644 --- a/tests/crashes/135718.rs +++ b/tests/ui/traits/next-solver/normalize/old-solver-projection-cache-bug-135718.rs @@ -1,4 +1,13 @@ -//@ known-bug: #135718 +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass +//@[old] build-fail +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug:: #135718 + +// A regression test for a caching bug with the old trait solver. struct Equal; From 5975e497d22b8e2e2cad9c933750de8560bdf91a Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 23:34:59 +0200 Subject: [PATCH 42/59] add crashes test --- tests/crashes/139381.rs | 13 ---------- ...ect-skip-binder-for-item-bound.next.stderr | 25 +++++++++++++++++++ .../incorrect-skip-binder-for-item-bound.rs | 24 ++++++++++++++++++ 3 files changed, 49 insertions(+), 13 deletions(-) delete mode 100644 tests/crashes/139381.rs create mode 100644 tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.next.stderr create mode 100644 tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.rs diff --git a/tests/crashes/139381.rs b/tests/crashes/139381.rs deleted file mode 100644 index 6757b584e82a1..0000000000000 --- a/tests/crashes/139381.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #139381 -//@ needs-rustc-debug-assertions -trait A<'a> { - type Assoc: ?Sized; -} - -impl<'a> A<'a> for () { - type Assoc = &'a (); -} - -fn hello() -> impl for<'a> A<'a, Assoc: Into + 'static + Copy> { - () -} diff --git a/tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.next.stderr b/tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.next.stderr new file mode 100644 index 0000000000000..edb3f36cd7560 --- /dev/null +++ b/tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.next.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `for<'a> u8: From<&'a ()>` is not satisfied + --> $DIR/incorrect-skip-binder-for-item-bound.rs:19:15 + | +LL | fn hello() -> impl for<'a> A<'a, Assoc: Into + 'static + Copy> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> From<&'a ()>` is not implemented for `u8` + | +help: `u8` implements trait `From` + --> $SRC_DIR/core/src/convert/num.rs:LL:COL + | + = note: `From` + ::: $SRC_DIR/core/src/convert/num.rs:LL:COL + | + = note: in this macro invocation + --> $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL + | + = note: `From` + ::: $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL + | + = note: in this macro invocation + = note: required for `&'a ()` to implement `for<'a> Into` + = note: this error originates in the macro `impl_from_bool` which comes from the expansion of the macro `into_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.rs b/tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.rs new file mode 100644 index 0000000000000..65a7d9442311e --- /dev/null +++ b/tests/ui/impl-trait/diagnostics/incorrect-skip-binder-for-item-bound.rs @@ -0,0 +1,24 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #139381 +//@ needs-rustc-debug-assertions + +// An ICE caused by an incorrect `skip_binder()` in diagnostics code, see #139381. + +trait A<'a> { + type Assoc: ?Sized; +} + +impl<'a> A<'a> for () { + type Assoc = &'a (); +} + +fn hello() -> impl for<'a> A<'a, Assoc: Into + 'static + Copy> { + //[next]~^ ERROR: the trait bound `for<'a> u8: From<&'a ()>` is not satisfied + () +} + +fn main() {} From d0acaae5ae9c68937a0b0751d1eba941ff4d9c50 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Oct 2026 23:58:50 +0200 Subject: [PATCH 43/59] more crashes tests --- tests/crashes/138707.rs | 37 ------------ ...complete-guidance-normalize-impl-header.rs | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+), 37 deletions(-) delete mode 100644 tests/crashes/138707.rs create mode 100644 tests/ui/traits/next-solver/assembly/incomplete-guidance-normalize-impl-header.rs diff --git a/tests/crashes/138707.rs b/tests/crashes/138707.rs deleted file mode 100644 index 4d9a82500ec45..0000000000000 --- a/tests/crashes/138707.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ known-bug: #138707 -//@edition:2024 -//@compile-flags: --crate-type lib -use core::marker::PhantomData; - -struct LeftReflector { - _phantom: PhantomData, -} - -struct DefaultAllocator {} - -trait Allocator { - type Buffer; -} - -struct U2 {} - -impl Allocator for DefaultAllocator { - type Buffer = [u8; 2]; -} - -impl From for LeftReflector<>::Buffer> -where - DefaultAllocator: Allocator, -{ - fn from(_: R) -> Self { - todo!() - } -} - -fn ice(a: U2) -where - DefaultAllocator: Allocator, -{ - // ICE - let _ = LeftReflector::from(a); -} diff --git a/tests/ui/traits/next-solver/assembly/incomplete-guidance-normalize-impl-header.rs b/tests/ui/traits/next-solver/assembly/incomplete-guidance-normalize-impl-header.rs new file mode 100644 index 0000000000000..c2d0dd6854fab --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/incomplete-guidance-normalize-impl-header.rs @@ -0,0 +1,57 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #138707 +//@edition:2024 +//@compile-flags: --crate-type lib + +// When using the `From` impl we eagerly normalize +// `>::Buffer` before +// ever equating the impl header with the goal. Because +// of the `DefaultAllocator: Allocator`, this keeps the +// alias as rigid without actually constraining `?r` to `D` +// in the old solver. +// +// This then passes HIR typeck as constraining the `?s` of +// `LeftReflector` to an alias is fine and that alias gets +// later normalized to `()`. However, now keeping the alias in +// the impl header as rigid results in a failure when relating +// the impl header with `LeftReflector<()>` from the goal. +// +// This only passes with the new solver as we currently don't +// explicitly normalize the impl header before equating it with +// the goal, instead replacing non-rigid aliases with inference +// variables on demand. We may end up breaking this test if we +// start to eagerly normalize within the new trait solver. + +struct LeftReflector(S); +struct DefaultAllocator {} + +trait Allocator { + type Buffer; +} + +impl Allocator<()> for DefaultAllocator { + type Buffer = (); +} + + +impl From for LeftReflector<>::Buffer> +where + DefaultAllocator: Allocator, +{ + fn from(_: R) -> Self { + todo!() + } +} + +fn ice(a: ()) +where + DefaultAllocator: Allocator, +{ + // ICE + let _ = LeftReflector::from(a); +} From dcde4eeabc9a1d4e6ea18b004408af0895636ffa Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 09:40:01 +0200 Subject: [PATCH 44/59] more crashes triage --- tests/crashes/140303.rs | 22 ---------- ...ound-holds-for-ty-error-140303.next.stderr | 10 +++++ .../trait-bound-holds-for-ty-error-140303.rs | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+), 22 deletions(-) delete mode 100644 tests/crashes/140303.rs create mode 100644 tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.next.stderr create mode 100644 tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.rs diff --git a/tests/crashes/140303.rs b/tests/crashes/140303.rs deleted file mode 100644 index 43a20b5e58ed4..0000000000000 --- a/tests/crashes/140303.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #140303 -//@compile-flags: -Zvalidate-mir -use std::future::Future; -async fn a() -> impl Sized { - b(c) -} -async fn c(); // kaboom -fn b(e: d) -> impl Sized -where - d: f, -{ - || -> ::h { panic!() } -} -trait f { - type h; -} -impl f for d -where - d: Fn() -> g, - g: Future, -{ -} diff --git a/tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.next.stderr b/tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.next.stderr new file mode 100644 index 0000000000000..2af1d6ddb4c97 --- /dev/null +++ b/tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.next.stderr @@ -0,0 +1,10 @@ +error: free function without a body + --> $DIR/trait-bound-holds-for-ty-error-140303.rs:28:1 + | +LL | async fn c(); // kaboom + | ^^^^^^^^^^^^- + | | + | help: provide a definition for the function: `{ }` + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.rs b/tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.rs new file mode 100644 index 0000000000000..dfc6349187f40 --- /dev/null +++ b/tests/ui/traits/error-reporting/trait-bound-holds-for-ty-error-140303.rs @@ -0,0 +1,44 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #140303 +//@ compile-flags: -Zvalidate-mir --emit=link +//@ edition: 2018 + +// This only ICEd with `--emit=link` while only erroring when compiled +// with `--emit=metadata`. This is necessary to compute +// `mir_drops_elaborated_and_const_checked` even though there were +// earlier errors. +// +// This ICEd during MIR validation with the old solver when normalizing +// the return type of `b(c)`. `fn c` returns `impl Future` which normalizes +// to `{type error}`. The old solver is able to prove `impl Future: Future`, +// but `{type error}: Future` results in ambiguity. +// +// The new solver instead considers `{type error}: Future` to hold. + +use std::future::Future; +struct Wrapper(T); +fn a() { + let _ = Wrapper(b(c)); +} + +async fn c(); // kaboom +//[next]~^ ERROR: free function without a body +fn b(e: T) -> impl Sized { + fn mk() -> T { todo!() } + mk::<::Assoc>() +} +trait Trait { + type Assoc; +} +impl Trait for T +where + T: Fn() -> R, + R: Future, +{ + type Assoc = (); +} +fn main() {} From 905891eddfb94143a04ad1f78fed32c4fc8315ff Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 09:59:53 +0200 Subject: [PATCH 45/59] remove duplicate test --- tests/crashes/130524.rs | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 tests/crashes/130524.rs diff --git a/tests/crashes/130524.rs b/tests/crashes/130524.rs deleted file mode 100644 index 14d2269de5980..0000000000000 --- a/tests/crashes/130524.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #130524 - -trait Transform { - type Output<'a>; -} - -trait Propagate {} - -fn new_node(_c: Vec Propagate<::Output<'a>>>>) -> T { - todo!() -} - -impl Propagate for T {} -struct Noop; - -impl Transform for Noop { - type Output<'a> = (); -} - -fn main() { - let _node: Noop = new_node(vec![Box::new(Noop)]); -} From 9be63df84ffab21c006ef666887a2b849f2994a4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 10:07:10 +0200 Subject: [PATCH 46/59] more crashes tests --- tests/crashes/147719.rs | 16 ---------- ...k-check-on-ambig-async-closure.next.stderr | 31 +++++++++++++++++++ ...-only-leak-check-on-ambig-async-closure.rs | 28 +++++++++++++++++ 3 files changed, 59 insertions(+), 16 deletions(-) delete mode 100644 tests/crashes/147719.rs create mode 100644 tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.next.stderr create mode 100644 tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.rs diff --git a/tests/crashes/147719.rs b/tests/crashes/147719.rs deleted file mode 100644 index d9595b8ead565..0000000000000 --- a/tests/crashes/147719.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #147719 -//@ edition: 2024 -trait NodeImpl {} -struct Wrap(F, P); -impl Wrap { - fn new(_: F) -> Self { - loop {} - } -} -trait Arg {} -impl NodeImpl for Wrap where A: Arg {} -impl NodeImpl for Wrap where F: Fn(&(), A) -> Fut {} -fn trigger_ice() { - let _: &dyn NodeImpl = &Wrap::<_, (i128,)>::new(async |_: &(), i128| 0); -} -fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.next.stderr b/tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.next.stderr new file mode 100644 index 0000000000000..6fda59572171b --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.next.stderr @@ -0,0 +1,31 @@ +error[E0277]: the trait bound `Wrap<{async closure@$DIR/old-solver-only-leak-check-on-ambig-async-closure.rs:26:20: 26:34}>: NodeImpl` is not satisfied + --> $DIR/old-solver-only-leak-check-on-ambig-async-closure.rs:26:15 + | +LL | node_impl(Wrap(async |_: &()| ())); + | --------- ^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | +help: the trait `NodeImpl` is not implemented for `Wrap<{async closure@$DIR/old-solver-only-leak-check-on-ambig-async-closure.rs:26:20: 26:34}>` + --> $DIR/old-solver-only-leak-check-on-ambig-async-closure.rs:14:1 + | +LL | struct Wrap(F); + | ^^^^^^^^^^^^^^ +help: the trait `NodeImpl` is conditionally implemented for `Wrap` + --> $DIR/old-solver-only-leak-check-on-ambig-async-closure.rs:18:1 + | +LL | / impl NodeImpl for Wrap +LL | | where +LL | | F: Fn(&()) -> Fut, + | |___________________---^ + | | + | unsatisfied requirement introduced here: `for<'a> <_ as FnOnce<(&'a (),)>>::Output == _` +note: required by a bound in `node_impl` + --> $DIR/old-solver-only-leak-check-on-ambig-async-closure.rs:24:17 + | +LL | fn node_impl(_: T) {} + | ^^^^^^^^ required by this bound in `node_impl` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.rs b/tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.rs new file mode 100644 index 0000000000000..e30d7bcc23ef7 --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/old-solver-only-leak-check-on-ambig-async-closure.rs @@ -0,0 +1,28 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #147719 +//@ edition: 2024 + +// A variant of `old-solver-only-leak-check-on-ambig.rs` which +// relies on us deferring the inference of async closure upvars. +// `Fut` is higher ranked as it ends up capturing the function +// argument. + +struct Wrap(F); +trait NotImplemented {} +trait NodeImpl {} +impl NodeImpl for T {} +impl NodeImpl for Wrap +where + F: Fn(&()) -> Fut, +{ +} + +fn node_impl(_: T) {} +fn main() { + node_impl(Wrap(async |_: &()| ())); + //[next]~^ ERROR: the trait bound +} From 7b5a60033d6734dae409f4cceb2e6715222bb49d Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 10:12:34 +0200 Subject: [PATCH 47/59] yeet duplicate test --- tests/crashes/148094.rs | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 tests/crashes/148094.rs diff --git a/tests/crashes/148094.rs b/tests/crashes/148094.rs deleted file mode 100644 index 7c08240a198c5..0000000000000 --- a/tests/crashes/148094.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #148094 -//@ compile-flags: -Zvalidate-mir -#![feature(type_alias_impl_trait)] -type Tait = impl Sized; -trait Foo: Bar {} -trait Bar {} -#[define_opaque(Tait)] -fn test_correct3(x: &dyn Foo) -> &dyn Bar<()> { - x -} -fn main() {} From 9883d34bc0cbea1171f6aaf8f4ceeeca51ecd094 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 10:14:59 +0200 Subject: [PATCH 48/59] yeet duplicate test --- tests/crashes/139120.rs | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 tests/crashes/139120.rs diff --git a/tests/crashes/139120.rs b/tests/crashes/139120.rs deleted file mode 100644 index f946f010c44ef..0000000000000 --- a/tests/crashes/139120.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ known-bug: #139120 - - - -pub trait Foo { - type Bar<'a>; -} - -pub struct FooImpl {} - -impl Foo for FooImpl { - type Bar<'a> = (); -} - -pub trait FooFn { - fn bar(&self); -} - -impl FooFn for fn(T, T::Bar<'_>) { - fn bar(&self) {} -} - -fn foo(f: fn(T, T::Bar<'_>)) { - let _: &dyn FooFn = &f; -} - -fn main() { - foo(|_: FooImpl, _| {}); -} From 743fe790d281bde4a44a7ec7a5effba28ee207ab Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 10:38:12 +0200 Subject: [PATCH 49/59] add regression test --- tests/crashes/146965.rs | 29 -------------- .../mir-inlining-ice-146965.rs | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 29 deletions(-) delete mode 100644 tests/crashes/146965.rs create mode 100644 tests/ui/traits/next-solver/normalization-shadowing/mir-inlining-ice-146965.rs diff --git a/tests/crashes/146965.rs b/tests/crashes/146965.rs deleted file mode 100644 index d663ccb358178..0000000000000 --- a/tests/crashes/146965.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ known-bug: #146965 -//@ compile-flags: --crate-type lib -C opt-level=3 - -fn conjure() -> T { - panic!() -} - -pub trait Ring { - type Element; -} -impl Ring for T { - type Element = u16; -} - -// Removing the : Ring bound makes it not ICE -fn map_coeff(f: impl Fn(::Element)) { - let c = conjure::<::Element>(); - f(c); -} - -// Adding a : Ring bound makes it not ICE -fn gcd() { - map_coeff::(|_: u16| {}); -} - -// Removing the : Ring bound makes it not ICE -pub fn bivariate_factorization() { - gcd::(); -} diff --git a/tests/ui/traits/next-solver/normalization-shadowing/mir-inlining-ice-146965.rs b/tests/ui/traits/next-solver/normalization-shadowing/mir-inlining-ice-146965.rs new file mode 100644 index 0000000000000..dc688786888e4 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/mir-inlining-ice-146965.rs @@ -0,0 +1,39 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] build-pass +//@[old] build-fail +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #146965 +//@ compile-flags: --crate-type lib -C opt-level=3 + +// A regression test for #146965. When considering to inline `fn no_bound` +// into `fn optimize_me` we check `no_bound::{closure}: FnOnce(::Element)`. +// +// In `fn no_bound` we can normalize `::Element` to `u16` while the +// `T: Ring` bound in `fn optimize_me` means the associated type stays rigid +// again. This then causes us to fail to prove this where-bound. +// +// This is the case with both solvers, the new solver accepts it gracefully, while +// the old solver ICEd in `fn codegen_select_candidate`. + +pub trait Ring { + type Element; +} +impl Ring for T { + type Element = u16; +} + +fn and_rigid_again(f: impl FnOnce(::Element)) { + fn mk() -> T { todo!() } + f(mk()); +} + +fn no_bound() { + and_rigid_again::(|_: u16| {}); +} + +pub fn optimize_me() { + no_bound::(); +} From 60e0ae0beaff04f683bd38aca952bbe1e166f061 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 10:49:56 +0200 Subject: [PATCH 50/59] more crashes tests --- tests/crashes/149015.rs | 10 --- ...l-to-normalize-own-self-ty-ice.next.stderr | 65 +++++++++++++++++++ .../use-impl-to-normalize-own-self-ty-ice.rs | 24 +++++++ 3 files changed, 89 insertions(+), 10 deletions(-) delete mode 100644 tests/crashes/149015.rs create mode 100644 tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.next.stderr create mode 100644 tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.rs diff --git a/tests/crashes/149015.rs b/tests/crashes/149015.rs deleted file mode 100644 index c262dc7d47fe3..0000000000000 --- a/tests/crashes/149015.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #149015 -trait Trait1 { - type Assoc; -} - -trait Trait2 {} - -impl Trait1 for ::Assoc { - type Assoc = (); -} diff --git a/tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.next.stderr b/tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.next.stderr new file mode 100644 index 0000000000000..d327a843ab611 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.next.stderr @@ -0,0 +1,65 @@ +error[E0277]: the trait bound `&'static (): Trait` is not satisfied + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:16 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `&'static ()` + | +help: the trait `Trait` is implemented for `<&'static () as Trait>::Assoc` + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:1 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `&'static (): Trait` is not satisfied + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:6 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^ the trait `Trait` is not implemented for `&'static ()` + | +help: the trait `Trait` is implemented for `<&'static () as Trait>::Assoc` + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:1 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `&'static (): Trait` is not satisfied + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:20:18 + | +LL | type Assoc = (); + | ^^ the trait `Trait` is not implemented for `&'static ()` + | +help: the trait `Trait` is implemented for `<&'static () as Trait>::Assoc` + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:1 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `&'static (): Trait` is not satisfied + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:16 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `&'static ()` + | +help: the trait `Trait` is implemented for `<&'static () as Trait>::Assoc` + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:1 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the trait bound `&'static (): Trait` is not satisfied + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:16 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `&'static ()` + | +help: the trait `Trait` is implemented for `<&'static () as Trait>::Assoc` + --> $DIR/use-impl-to-normalize-own-self-ty-ice.rs:15:1 + | +LL | impl Trait for <&'static () as Trait>::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.rs b/tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.rs new file mode 100644 index 0000000000000..4cd1a1b795e34 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/use-impl-to-normalize-own-self-ty-ice.rs @@ -0,0 +1,24 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #149015 + +// A regression test for #149015. This ICEd in `fn rematch_impl` due to +// buggy cycle handling in the old solver. + +trait Trait { + type Assoc; +} + +impl Trait for <&'static () as Trait>::Assoc { +//[next]~^ ERROR: the trait bound `&'static (): Trait` is not satisfied +//[next]~| ERROR: the trait bound `&'static (): Trait` is not satisfied +//[next]~| ERROR: the trait bound `&'static (): Trait` is not satisfied +//[next]~| ERROR: the trait bound `&'static (): Trait` is not satisfied + type Assoc = (); + //[next]~^ ERROR: the trait bound `&'static (): Trait` is not satisfied +} + +fn main() {} From 9e42fc772e7c7caabcb657cc7b218185e2889979 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 11:09:28 +0200 Subject: [PATCH 51/59] add crashes test --- tests/crashes/148095.rs | 11 -- ...-old-solver-caching-ice-148095.next.stderr | 126 ++++++++++++++++++ ...incorrect-old-solver-caching-ice-148095.rs | 33 +++++ 3 files changed, 159 insertions(+), 11 deletions(-) delete mode 100644 tests/crashes/148095.rs create mode 100644 tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.next.stderr create mode 100644 tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.rs diff --git a/tests/crashes/148095.rs b/tests/crashes/148095.rs deleted file mode 100644 index 43be99254164f..0000000000000 --- a/tests/crashes/148095.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #148095 -use std::ops::Mul; - -struct Quantity(S); -impl Mul>::Output>> for f32 -where - Quantity: -{ - type Output = (); - fn mul(self, _: Quantity<>::Output>) {} -} diff --git a/tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.next.stderr b/tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.next.stderr new file mode 100644 index 0000000000000..c285c42d380e8 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.next.stderr @@ -0,0 +1,126 @@ +error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:25:6 + | +LL | impl Mul>::Output>> for f32 + | ^ unconstrained type parameter + +error[E0277]: cannot multiply `f32` by `S` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:25:13 + | +LL | impl Mul>::Output>> for f32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * S` + | + = help: the trait `Mul` is not implemented for `f32` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error[E0277]: cannot multiply `f32` by `S` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:30:5 + | +LL | fn mul(self, _: Quantity<>::Output>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * S` + | + = help: the trait `Mul` is not implemented for `f32` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error[E0276]: impl has stricter requirements than trait + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:30:5 + | +LL | fn mul(self, _: Quantity<>::Output>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `Quantity<>::Output> well-formed` + +error[E0277]: cannot multiply `f32` by `S` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:25:13 + | +LL | impl Mul>::Output>> for f32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * S` + | + = help: the trait `Mul` is not implemented for `f32` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error[E0277]: cannot multiply `f32` by `S` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:30:30 + | +LL | fn mul(self, _: Quantity<>::Output>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * S` + | + = help: the trait `Mul` is not implemented for `f32` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error[E0277]: cannot multiply `f32` by `Quantity<>::Output>` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:27:5 + | +LL | Quantity: + | ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * Quantity<>::Output>` + | + = help: the trait `Mul>::Output>>` is not implemented for `f32` +note: required by a bound in `Quantity` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:24:17 + | +LL | struct Quantity(S); + | ^ required by this bound in `Quantity` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul>::Output>> + | +++++++++++++++++++++++++++++++++++++++++++++ + +error[E0277]: cannot multiply `f32` by `S` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:27:5 + | +LL | Quantity: + | ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * S` + | + = help: the trait `Mul` is not implemented for `f32` +note: required by a bound in `Quantity` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:24:17 + | +LL | struct Quantity(S); + | ^ required by this bound in `Quantity` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error[E0277]: cannot multiply `f32` by `S` + | + = help: the trait `Mul` is not implemented for `f32` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:27:28 + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error: the type `Quantity<>::Output>` is not well-formed + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:30:21 + | +LL | fn mul(self, _: Quantity<>::Output>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: cannot multiply `f32` by `S` + --> $DIR/incorrect-old-solver-caching-ice-148095.rs:30:21 + | +LL | fn mul(self, _: Quantity<>::Output>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `f32 * S` + | + = help: the trait `Mul` is not implemented for `f32` +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | Quantity:, f32: Mul + | +++++++++++++ + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0207, E0276, E0277. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.rs b/tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.rs new file mode 100644 index 0000000000000..4b0c3885ac8a9 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/incorrect-old-solver-caching-ice-148095.rs @@ -0,0 +1,33 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] dont-require-annotations: ERROR +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #148095 + +// A regression test for #148095. The old solver incorrectly cached +// a result from in one context and then used that result in a different +// context, triggering an assert. +// +// More specifically, when in `self.query_mode == TraitQueryMode::Canonical`, +// `WfPredicates::normalize` creates a separate `SelectionContext` for +// normalization which is not in that mode. That then ICEs when accessing +// a cache entry from the `infcx`-local cache, which also caches canonical +// overflow. +// +// This test results in a lot of errors with the new solver, so lets not add +// explicit annotations here. + +use std::ops::Mul; + +struct Quantity(S); +impl Mul>::Output>> for f32 +where + Quantity: +{ + type Output = (); + fn mul(self, _: Quantity<>::Output>) {} +} + +fn main() {} From baa250343803858aad84aad811b0c8ab34dcbd0a Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 11:12:13 +0200 Subject: [PATCH 52/59] yeet duplicate test --- tests/crashes/150263.rs | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 tests/crashes/150263.rs diff --git a/tests/crashes/150263.rs b/tests/crashes/150263.rs deleted file mode 100644 index 44d0fdbdda9b0..0000000000000 --- a/tests/crashes/150263.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ known-bug: #150263 -//@ compile-flags: --crate-type lib -C opt-level=3 - -pub trait Scope { - type Timestamp; -} -impl Scope for G { - type Timestamp = (); -} - -pub fn create() { - enter::(); -} - -fn enter() { - unary::(|_: ::Timestamp| {}); -} - -fn unary(constructor: impl FnOnce(G::Timestamp)) { - constructor(None.unwrap()); -} From 89242d818d6bd5a99d8dc505bb8dcc01418f1828 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 11:30:51 +0200 Subject: [PATCH 53/59] yeet duplicate test --- tests/crashes/150517.rs | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 tests/crashes/150517.rs diff --git a/tests/crashes/150517.rs b/tests/crashes/150517.rs deleted file mode 100644 index de14628547d28..0000000000000 --- a/tests/crashes/150517.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #150517 -trait Stream { - type Item; - fn next(self) -> (); -} -impl Stream for &'a () {} -impl<'a, A> Stream for <&A as Stream>::Item {} -trait StreamExt { - fn f(self) -> () - where - for<'b> &'b A: Stream, - { - self.next() - } -} From ab3e7ce856dc4c40d4f6092a47b267edb380c526 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 11:44:54 +0200 Subject: [PATCH 54/59] crashes migration --- tests/crashes/151069.rs | 16 ---------- .../old-solver-caching-bug-151069.next.stderr | 31 +++++++++++++++++++ .../old-solver-caching-bug-151069.rs | 27 ++++++++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) delete mode 100644 tests/crashes/151069.rs create mode 100644 tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.next.stderr create mode 100644 tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.rs diff --git a/tests/crashes/151069.rs b/tests/crashes/151069.rs deleted file mode 100644 index ae6f4da5c6c70..0000000000000 --- a/tests/crashes/151069.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #151069 -trait Trait { - type Assoc2; -} -struct Bar; -impl Trait for Bar -where - ::Assoc2: Trait, -{ - type Assoc2 = (); -} -struct Foo { - field: ::Assoc2, -} -static FOO2: &Foo = 0; -fn main() {} diff --git a/tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.next.stderr b/tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.next.stderr new file mode 100644 index 0000000000000..b52a8a2a424a5 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.next.stderr @@ -0,0 +1,31 @@ +error[E0275]: overflow evaluating the requirement `::Assoc2 == _` + --> $DIR/old-solver-caching-bug-151069.rs:17:1 + | +LL | / impl Trait for Bar +LL | | where +LL | | ::Assoc2: Trait, + | |__________________________________^ + +error[E0275]: overflow evaluating the requirement `::Assoc2 == _` + --> $DIR/old-solver-caching-bug-151069.rs:21:5 + | +LL | type Assoc2 = (); + | ^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `::Assoc2 == _` + --> $DIR/old-solver-caching-bug-151069.rs:24:12 + | +LL | field: ::Assoc2, + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating whether `::Assoc2` is well-formed + --> $DIR/old-solver-caching-bug-151069.rs:24:12 + | +LL | field: ::Assoc2, + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `::Metadata == _` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.rs b/tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.rs new file mode 100644 index 0000000000000..ffed91181042e --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/old-solver-caching-bug-151069.rs @@ -0,0 +1,27 @@ +//@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] dont-require-annotations: ERROR +//@[old] failure-status: 101 +//@[old] dont-check-compiler-stderr +//@[old] known-bug: #151069 + +// Regression test for #151069. This triggers a caching bug in the old solver, +// resulting in an ICE. IT results in a bunch of overflow errors, so let's just +// ignore the annotations here. + +trait Trait { + type Assoc2; +} +struct Bar; +impl Trait for Bar +where + ::Assoc2: Trait, +{ + type Assoc2 = (); +} +struct Foo { + field: ::Assoc2, +} +static FOO2: &Foo = 0; +fn main() {} From b1a3475aece76762fb5f6d4cc6649b8993d19bf0 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 25 Sep 2026 18:01:58 +0200 Subject: [PATCH 55/59] `unit` and `[1 x unit]` layouts are incompatible on `aarch64_be` so don't unwrap singleton arrays for it --- compiler/rustc_codegen_llvm/src/abi.rs | 15 +-- .../rustc_target/src/callconv/powerpc64.rs | 2 +- tests/assembly-llvm/singleton-hfa.rs | 99 +++++++++++++++++++ .../aarch64-abi/homogeneous-aggregate.rs | 23 ++++- .../arm-abi/homogeneous-aggregate.rs | 66 +++++++++---- .../codegen-llvm/arm-abi/struct-alignment.rs | 8 +- tests/codegen-llvm/complex-abi.rs | 4 +- .../powerpc64-abi/homogeneous-aggregate.rs | 25 +++-- 8 files changed, 201 insertions(+), 41 deletions(-) create mode 100644 tests/assembly-llvm/singleton-hfa.rs diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 19e6a3314f20a..2c3d805e4c63b 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -195,13 +195,16 @@ impl LlvmType for CastTarget { self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes()) }; - // Simplify to a single unit or an array if there's no prefix. - // This produces the same layout, but using a simpler type. + // Simplify to an array if there is no prefix. if self.prefix.is_empty() { - // We can't do this if is_consecutive is set and the unit would get - // split on the target. Currently, this is only relevant for i128 - // registers. - if rest_count == 1 && (!self.rest.is_consecutive || self.rest.unit != Reg::i128()) { + // Pass `[1 x unit]` as just `unit`. + // + // On little-endian targets this produces a compatible layout, but using a simpler type. + // But on big-endian targets (e.g. aarch64_be or powerpc64) the value may be passed in + // different halves of the register-sized slot, so unit and [1 x unit] are incompatible. + // + // Setting `is_consecutive` forces use of an array. + if rest_count == 1 && !self.rest.is_consecutive { return rest_ll_unit; } diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs index ca79a52d2874f..daaaa00572e61 100644 --- a/compiler/rustc_target/src/callconv/powerpc64.rs +++ b/compiler/rustc_target/src/callconv/powerpc64.rs @@ -75,7 +75,7 @@ where RegKind::Vector { .. } => unit.size.bits() == 128, }; - valid_unit.then_some(Uniform::consecutive(unit, arg.layout.size)) + valid_unit.then_some(Uniform::new(unit, arg.layout.size)) }) } diff --git a/tests/assembly-llvm/singleton-hfa.rs b/tests/assembly-llvm/singleton-hfa.rs new file mode 100644 index 0000000000000..218e9e284d728 --- /dev/null +++ b/tests/assembly-llvm/singleton-hfa.rs @@ -0,0 +1,99 @@ +//@ add-minicore +//@ revisions: powerpc64 aarch64_be +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 -Z merge-functions=disabled +// +//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@[powerpc64] needs-llvm-components: powerpc +// +//@[aarch64_be] compile-flags: --target aarch64_be-unknown-linux-gnu +//@[aarch64_be] needs-llvm-components: aarch64 +#![feature(no_core)] +#![no_core] +#![crate_type = "lib"] + +// On big-endian targets, the singleton HFA and the unit are not ABI-compatible, so it matters +// which is used. Test that: +// +// - on powerpc64 SingletonStruct is passed like f32 +// - on aarch64_be SingletonStruct is passed like [f32; 1] +// +// The test start with 13 float arguments, to exhaust float registers and force the last argument +// onto the stack (technically we only need 8 float arguments on aarch64_be but a couple more +// does not matter). + +extern crate minicore; +use minicore::*; + +#[repr(C)] +struct SingletonStruct(T); + +#[no_mangle] +extern "C" fn singleton_struct_float( + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + x: SingletonStruct, +) -> f32 { + // powerpc64: lfs 1, 156(1) + // aarch64_be: ldr s0, [sp, #40] + x.0 +} + +// CHECK-LABEL: singleton_array_float: +#[no_mangle] +extern "C" fn singleton_array_float( + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + x: [f32; 1], +) -> f32 { + // powerpc64: lfs 1, 156(1) + // aarch64_be: ldr s0, [sp, #40] + match x { + [a] => a, + } +} + +// CHECK-LABEL: float: +#[no_mangle] +extern "C" fn float( + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + _: f64, + x: f32, +) -> f32 { + // powerpc64: lfs 1, 156(1) + // aarch64_be: ldr s0, [sp, #44] + x +} diff --git a/tests/codegen-llvm/aarch64-abi/homogeneous-aggregate.rs b/tests/codegen-llvm/aarch64-abi/homogeneous-aggregate.rs index 3d5ec10f2b2f7..ecb318ddbb794 100644 --- a/tests/codegen-llvm/aarch64-abi/homogeneous-aggregate.rs +++ b/tests/codegen-llvm/aarch64-abi/homogeneous-aggregate.rs @@ -1,8 +1,9 @@ //@ add-minicore //@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 // -//@ revisions: linux win +//@ revisions: linux linux-be win //@[linux] compile-flags: --target aarch64-unknown-linux-gnu +//@[linux-be] compile-flags: --target aarch64_be-unknown-linux-gnu //@[win] compile-flags: --target aarch64-pc-windows-msvc // //@ needs-llvm-components: aarch64 @@ -17,17 +18,29 @@ extern crate minicore; use minicore::simd::*; use minicore::*; +// A singleton homogeneous float aggregate. +#[repr(C)] +pub struct Hfa1 { + pub a: f32, +} + +// NOTE: on aarch64_be `[1 x float]` is not abi-compatible with a bare `float`. +// CHECK: define void @test_hfa1([1 x float] %0) +#[unsafe(no_mangle)] +pub extern "C" fn test_hfa1(a: Hfa1) { + hint::black_box(a); +} + // A homogeneous float aggregate. #[repr(C)] -pub struct Hfa { +pub struct Hfa2 { pub a: f32, pub b: f32, } -impl Copy for Hfa {} -// CHECK: define void @test_hfa([2 x float] %0) +// CHECK: define void @test_hfa2([2 x float] %0) #[unsafe(no_mangle)] -pub extern "C" fn test_hfa(a: Hfa) { +pub extern "C" fn test_hfa2(a: Hfa2) { hint::black_box(a); } diff --git a/tests/codegen-llvm/arm-abi/homogeneous-aggregate.rs b/tests/codegen-llvm/arm-abi/homogeneous-aggregate.rs index 272eb419494b0..8c058a95b322a 100644 --- a/tests/codegen-llvm/arm-abi/homogeneous-aggregate.rs +++ b/tests/codegen-llvm/arm-abi/homogeneous-aggregate.rs @@ -19,37 +19,69 @@ extern crate minicore; use minicore::simd::*; use minicore::*; +// A singleton homogeneous float aggregate. +#[repr(C)] +pub struct Hfa1 { + pub a: f32, +} + +// linux: define void @test_hfa1([1 x float] %0) +// eabi: define dso_local void @test_hfa1([1 x i32] %0) +// watchos: define void @test_hfa1([1 x float] %0) +#[unsafe(no_mangle)] +pub extern "C" fn test_hfa1(a: Hfa1) { + hint::black_box(a); +} + +// linux: define [1 x float] @ret_hfa1([1 x float] %0) +// eabi: define dso_local i32 @ret_hfa1([1 x i32] %0) +// watchos: define [1 x float] @ret_hfa1([1 x float] %0) +#[unsafe(no_mangle)] +pub extern "C" fn ret_hfa1(a: Hfa1) -> Hfa1 { + a +} + +// When we ask for `extern "aapcs"` specifically, GPRs are used, except on watchOS. +// +// linux: define arm_aapcscc void @test_hfa1_aapcs([1 x i32] %0) +// eabi: define dso_local arm_aapcscc void @test_hfa1_aapcs([1 x i32] %0) +// watchos: define arm_aapcscc void @test_hfa1_aapcs([1 x float] %0) +#[unsafe(no_mangle)] +pub extern "aapcs" fn test_hfa1_aapcs(a: Hfa1) { + hint::black_box(a); +} + // A homogeneous float aggregate, which a hard-float ABI passes in VFP registers. #[repr(C)] -pub struct Hfa { +pub struct Hfa2 { pub a: f32, pub b: f32, } -impl Copy for Hfa {} +impl Copy for Hfa2 {} -// linux: define void @test_hfa([2 x float] %0) -// eabi: define dso_local void @test_hfa([2 x i32] %0) -// watchos: define void @test_hfa([2 x float] %0) +// linux: define void @test_hfa2([2 x float] %0) +// eabi: define dso_local void @test_hfa2([2 x i32] %0) +// watchos: define void @test_hfa2([2 x float] %0) #[unsafe(no_mangle)] -pub extern "C" fn test_hfa(a: Hfa) { +pub extern "C" fn test_hfa2(a: Hfa2) { hint::black_box(a); } -// linux: define [2 x float] @ret_hfa([2 x float] %0) -// eabi: define dso_local void @ret_hfa(ptr sret([8 x i8]) align 4 %_0, [2 x i32] %0) -// watchos: define [2 x float] @ret_hfa([2 x float] %0) +// linux: define [2 x float] @ret_hfa2([2 x float] %0) +// eabi: define dso_local void @ret_hfa2(ptr sret([8 x i8]) align 4 %_0, [2 x i32] %0) +// watchos: define [2 x float] @ret_hfa2([2 x float] %0) #[unsafe(no_mangle)] -pub extern "C" fn ret_hfa(a: Hfa) -> Hfa { +pub extern "C" fn ret_hfa2(a: Hfa2) -> Hfa2 { a } // When we ask for `extern "aapcs"` specifically, GPRs are used, except on watchOS. // -// linux: define arm_aapcscc void @test_hfa_aapcs([2 x i32] %0) -// eabi: define dso_local arm_aapcscc void @test_hfa_aapcs([2 x i32] %0) -// watchos: define arm_aapcscc void @test_hfa_aapcs([2 x float] %0) +// linux: define arm_aapcscc void @test_hfa2_aapcs([2 x i32] %0) +// eabi: define dso_local arm_aapcscc void @test_hfa2_aapcs([2 x i32] %0) +// watchos: define arm_aapcscc void @test_hfa2_aapcs([2 x float] %0) #[unsafe(no_mangle)] -pub extern "aapcs" fn test_hfa_aapcs(a: Hfa) { +pub extern "aapcs" fn test_hfa2_aapcs(a: Hfa2) { hint::black_box(a); } @@ -216,7 +248,7 @@ extern "C" { // linux: declare void @test_hfa_variadic_c([2 x i32], ...) // eabi: declare dso_local void @test_hfa_variadic_c([2 x i32], ...) // watchos: declare void @test_hfa_variadic_c([2 x float], ...) - fn test_hfa_variadic_c(_: Hfa, ...); + fn test_hfa_variadic_c(_: Hfa2, ...); // linux: declare void @test_ints_6_variadic_c([6 x i32], ...) // eabi: declare dso_local void @test_ints_6_variadic_c([6 x i32], ...) @@ -228,7 +260,7 @@ extern "aapcs" { // linux: declare arm_aapcscc void @test_hfa_variadic_aapcs([2 x i32], ...) // eabi: declare dso_local arm_aapcscc void @test_hfa_variadic_aapcs([2 x i32], ...) // watchos: declare arm_aapcscc void @test_hfa_variadic_aapcs([2 x float], ...) - fn test_hfa_variadic_aapcs(_: Hfa, ...); + fn test_hfa_variadic_aapcs(_: Hfa2, ...); // linux: declare arm_aapcscc void @test_ints_6_variadic_aapcs([6 x i32], ...) // eabi: declare dso_local arm_aapcscc void @test_ints_6_variadic_aapcs([6 x i32], ...) @@ -236,7 +268,7 @@ extern "aapcs" { fn test_ints_6_variadic_aapcs(_: Ints6, ...); } -pub unsafe fn call_variadics(a: Hfa, b: Ints6) { +pub unsafe fn call_variadics(a: Hfa2, b: Ints6) { test_hfa_variadic_c(a); test_ints_6_variadic_c(b); diff --git a/tests/codegen-llvm/arm-abi/struct-alignment.rs b/tests/codegen-llvm/arm-abi/struct-alignment.rs index 1921b8a9ddda9..42f8bb318e85a 100644 --- a/tests/codegen-llvm/arm-abi/struct-alignment.rs +++ b/tests/codegen-llvm/arm-abi/struct-alignment.rs @@ -36,9 +36,9 @@ pub struct HasU64 { pub a: u64, } -// linux: define void @test_has_u64(i64 %0) -// eabi: define dso_local void @test_has_u64(i64 %0) -// watchos: define void @test_has_u64(i64 %0) +// linux: define void @test_has_u64([1 x i64] %0) +// eabi: define dso_local void @test_has_u64([1 x i64] %0) +// watchos: define void @test_has_u64([1 x i64] %0) #[unsafe(no_mangle)] pub extern "C" fn test_has_u64(a: HasU64) { hint::black_box(a); @@ -62,7 +62,7 @@ pub struct Transparent8 { // // linux: define void @test_8([2 x i32] %0, [2 x i32] %1) // eabi: define dso_local void @test_8([2 x i32] %0, [2 x i32] %1) -// watchos: define void @test_8(i64 %0, i64 %1) +// watchos: define void @test_8([1 x i64] %0, [1 x i64] %1) #[unsafe(no_mangle)] pub extern "C" fn test_8(a: Align8, b: Transparent8) { hint::black_box(a); diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index c9e59f6f7eaa7..45224bd9316fe 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -230,7 +230,7 @@ pub extern "C" fn cplx_i8(x: Complex) -> Complex { // AARCH64_MSVC: define{{.*}} i64 @cplx_i8(i64{{.*}}) // AIX: define{{.*}} { i8, i8 } @cplx_i8({ i8, i8 } %0) // ARM64EC: define{{.*}} i64 @cplx_i8(i64{{.*}}) - // ARM: define{{.*}} i32 @cplx_i8(i32{{.*}}) + // ARM: define{{.*}} i32 @cplx_i8([1 x i32]{{.*}}) // BPF: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, i16 {{.*}}) // CSKY: define{{.*}} i32 @cplx_i8(i32{{.*}}) // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) @@ -265,7 +265,7 @@ pub extern "C" fn cplx_i16(x: Complex) -> Complex { // AARCH64_MSVC: define{{.*}} i64 @cplx_i16(i64{{.*}}) // AIX: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) // ARM64EC: define{{.*}} i64 @cplx_i16(i64{{.*}}) - // ARM: define{{.*}} i32 @cplx_i16(i32{{.*}}) + // ARM: define{{.*}} i32 @cplx_i16([1 x i32]{{.*}}) // BPF: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, i32 {{.*}}) // CSKY: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) diff --git a/tests/codegen-llvm/powerpc64-abi/homogeneous-aggregate.rs b/tests/codegen-llvm/powerpc64-abi/homogeneous-aggregate.rs index 58dd9c837603f..a85901cf55bfd 100644 --- a/tests/codegen-llvm/powerpc64-abi/homogeneous-aggregate.rs +++ b/tests/codegen-llvm/powerpc64-abi/homogeneous-aggregate.rs @@ -18,19 +18,32 @@ extern crate minicore; use minicore::simd::*; use minicore::*; +// A singleton homogeneous float aggregate. +#[repr(C)] +pub struct Hfa1 { + pub a: f32, +} + +// NOTE: on powerpc64 `[1 x float]` is not abi-compatible with a bare `float`. +// CHECK: define void @test_hfa1(float %0) +#[unsafe(no_mangle)] +pub extern "C" fn test_hfa1(a: Hfa1) { + hint::black_box(a); +} + // A homogeneous float aggregate. #[repr(C)] -pub struct Hfa { +pub struct Hfa2 { pub a: f32, pub b: f32, } -impl Copy for Hfa {} +impl Copy for Hfa2 {} -// ppc64: define void @test_hfa(i64 %0) -// ppc64_vsx: define void @test_hfa(i64 %0) -// ppc64le: define void @test_hfa([2 x float] %0) +// ppc64: define void @test_hfa2(i64 %0) +// ppc64_vsx: define void @test_hfa2(i64 %0) +// ppc64le: define void @test_hfa2([2 x float] %0) #[unsafe(no_mangle)] -pub extern "C" fn test_hfa(a: Hfa) { +pub extern "C" fn test_hfa2(a: Hfa2) { hint::black_box(a); } From 579a6bdff1b5909b94ab32cab1206f556f005120 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Oct 2026 17:46:33 +0200 Subject: [PATCH 56/59] review --- .../normalize-hir-typeck/in-closure-capture-ice-125553.rs | 2 +- .../normalize-hir-typeck/switch-int-terminator-140850.rs | 2 +- tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs index 052b82a4056eb..b99adadcc01f6 100644 --- a/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs +++ b/tests/ui/impl-trait/normalize-hir-typeck/in-closure-capture-ice-125553.rs @@ -1,10 +1,10 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@[next] check-pass //@[old] failure-status: 101 //@[old] dont-check-compiler-stderr //@[old] known-bug: #125553 -//@[next] check-pass //@ edition:2021 #![feature(type_alias_impl_trait)] diff --git a/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs index 513e4e382a4d9..353e99315a57e 100644 --- a/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs +++ b/tests/ui/impl-trait/normalize-hir-typeck/switch-int-terminator-140850.rs @@ -1,10 +1,10 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@[next] check-pass //@[old] failure-status: 101 //@[old] dont-check-compiler-stderr //@[old] known-bug: #140850 -//@[next] check-pass //@ compile-flags: -Zvalidate-mir //@ edition:2021 diff --git a/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs b/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs index 3ca4976b19195..774ea54e20895 100644 --- a/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs +++ b/tests/ui/trivial-bounds/cant-normalize-fully-concrete-const.rs @@ -6,7 +6,7 @@ //@[old] known-bug: #135617 // The bound `for<'a> (): Project` prevents us from normalizing the -// array length. This caused and ICE with the new solver. The actual +// array length. This caused an ICE with the new solver. The actual // behavior doesn't really matter here as long as it doesn't ICE. trait Project { From a2ca8f2a33d0a28514bfeddde965ed6018b9a70e Mon Sep 17 00:00:00 2001 From: Maksim Bondarenkov Date: Tue, 6 Oct 2026 20:33:17 +0300 Subject: [PATCH 57/59] INSTALL.md: use UCRT64 instead of MINGW64 in MSYS2 section --- INSTALL.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 066422a57eb09..91910ee9eaad0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -184,15 +184,15 @@ toolchain. 2. Download and install [Git for Windows](https://git-scm.com/download/win). Make sure that it's in your Windows PATH. To enable access to it from within - MSYS2, edit the relevant `mingw[32|64].ini` file in your MSYS2 installation + MSYS2, edit the relevant `[mingw32|ucrt64].ini` file in your MSYS2 installation directory and uncomment the line `MSYS2_PATH_TYPE=inherit`. You could install and use MSYS2's version of git instead with `pacman`, however this is not recommended as it's excruciatingly slow, and not frequently tested for compatibility. -3. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit - or 64-bit Rust) either from your start menu, or by running `mingw64.exe` +3. Start a UCRT64 or MINGW32 shell (depending on whether you want 32-bit + or 64-bit Rust) either from your start menu, or by running `ucrt64.exe` or `mingw32.exe` from your MSYS2 installation directory (e.g. `C:\msys64`). 4. From this terminal, install the required tools: @@ -202,17 +202,17 @@ toolchain. pacman -Sy pacman-mirrors # Install build tools needed for Rust. If you're building a 32-bit compiler, - # then replace "x86_64" below with "i686". - # Note that it is important that you do **not** use the 'python2', 'cmake', + # then replace "ucrt-x86_64" below with "i686". + # Note that it is important that you do **not** use the 'python', 'cmake', # and 'ninja' packages from the 'msys2' subsystem. # The build has historically been known to fail with these packages. - pacman -S make \ + pacman -S --needed make \ diffutils \ tar \ - mingw-w64-x86_64-python \ - mingw-w64-x86_64-cmake \ - mingw-w64-x86_64-gcc \ - mingw-w64-x86_64-ninja + mingw-w64-ucrt-x86_64-python \ + mingw-w64-ucrt-x86_64-cmake \ + mingw-w64-ucrt-x86_64-gcc \ + mingw-w64-ucrt-x86_64-ninja ``` 5. Navigate to Rust's source code (or clone it), then build it: From ea9748525bb834f6aa20beb797143bcf7d5b8d20 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Wed, 30 Sep 2026 00:46:11 +0200 Subject: [PATCH 58/59] Document the `rustc_on_unimplemented` attribute. --- compiler/rustc_attr_ir/src/attribute_docs.rs | 111 ++++++++++ src/doc/rustc-dev-guide/src/diagnostics.md | 205 ++---------------- .../doc_examples/rustc_on_unimplemented.rs | 16 ++ .../rustc_on_unimplemented.stderr | 18 ++ .../rustc_on_unimplemented_filter.rs | 18 ++ .../rustc_on_unimplemented_filter.stderr | 18 ++ .../rustc_on_unimplemented_format.rs | 15 ++ .../rustc_on_unimplemented_format.stderr | 19 ++ 8 files changed, 232 insertions(+), 188 deletions(-) create mode 100644 tests/ui/attributes/doc_examples/rustc_on_unimplemented.rs create mode 100644 tests/ui/attributes/doc_examples/rustc_on_unimplemented.stderr create mode 100644 tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.rs create mode 100644 tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.stderr create mode 100644 tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.rs create mode 100644 tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.stderr diff --git a/compiler/rustc_attr_ir/src/attribute_docs.rs b/compiler/rustc_attr_ir/src/attribute_docs.rs index b354e0c075c77..cc6e3d849d6b1 100644 --- a/compiler/rustc_attr_ir/src/attribute_docs.rs +++ b/compiler/rustc_attr_ir/src/attribute_docs.rs @@ -325,3 +325,114 @@ const _: () = (); /// [`mem::type_info`]: std::mem::type_info /// [reflection and comptime project goal]: https://goals.rust-lang.org/2026/reflection-and-comptime.html const _: () = (); + +#[doc(attribute = "rustc_on_unimplemented")] +/// Customize the error message when a trait is not implemented. +/// +/// It must be used on the declaration of said trait. +/// +/// # Syntax +/// +/// ```grammar +/// RustcOnUnimplementedAttribute -> +/// rustc_on_unimplemented ( ( Directive ),+ ) +/// +/// Directive -> +/// on ( Filter, ( DirectiveOption ),+ ) +/// | ( DirectiveOption ),* +/// +/// DirectiveOption -> +/// message = STRING_LITERAL +/// | label = STRING_LITERAL +/// | note = STRING_LITERAL +/// +/// Filter -> +/// FilterAll +/// | FilterAny +/// | FilterNot +/// | FilterOption +/// +/// FilterAll -> +/// all ( ( Filter ),* ) +/// +/// FilterAny -> +/// any ( ( Filter ),* ) +/// +/// FilterNot -> +/// not ( Filter ) +/// +/// FilterOption -> +/// crate_local +/// | direct +/// | from_desugaring ( = STRING_LITERAL )? +/// | cause = STRING_LITERAL +/// | IDENTIFIER = STRING_LITERAL +/// +/// ``` +/// +/// The following keys have the given meaning. At least one must be specified. +/// - `on` - filters the application of the attribute. See [#Filters](#filters). +/// - `message` — The text for the top level error message. May only be specified at most once. +/// - `label` — The text for the label shown inline in the broken code in the error message. +/// May only be specified at most once. +/// - `note` — Provides additional note(s) +/// +/// `message`, `label`, and `note` are available with the [`diagnostic::on_unimplemented`] +/// attribute. If possible, use that instead. +/// +/// # Example +/// +#[doc = include_example!("rustc_on_unimplemented")] +/// +/// # Filters +/// +/// To allow more targeted error messages, it is possible to filter the +/// application of these keys with `on`. +/// +/// You can filter on the following boolean flags: +/// - `crate_local`: whether the code causing the trait bound to not be +/// fulfilled is part of the user's crate. +/// This is used to avoid suggesting code changes that would require modifying a dependency. +/// - `direct`: whether this is a user-specified rather than derived obligation. +/// - `from_desugaring`: whether we are in some kind of desugaring, like `?` +/// or a `try` block for example. +/// This flag can also be matched on, see below. +/// +/// You can match on the following names and values, using `name = "value"`: +/// - `cause`: Match against one variant of the `ObligationCauseCode` enum. +/// Only `"MainFunctionType"` is supported. +/// - `from_desugaring`: Match against a particular variant of the `DesugaringKind` enum. +/// The desugaring is identified by its variant name, for example +/// `"QuestionMark"` for `?` desugaring, or `"TryBlock"` for `try` blocks. +/// - `Self` and any generic arguments of the trait, like `Self = "alloc::string::String"` +/// or `Rhs="i32"`. +/// +/// The compiler provides several values to match on, for example: +/// - the self_ty, pretty printed with and without type arguments resolved. +/// - `"{integral}"`, if self_ty is an integral of which the type is known. +/// - `"[]"`, `"[{ty}]"`, `"[{ty}; _]"`, `"[{ty}; $N]"` when applicable. +/// - references to said slices and arrays. +/// - `"fn"`, `"unsafe fn"` or `"#[target_feature] fn"` when self is a function. +/// - `"{integer}"` and `"{float}"` if the type is a number but we haven't inferred it yet. +/// - `"{struct}"`, `"{enum}"` and `"{union}"` to match self as an ADT +/// - combinations of the above, like `"[{integral}; _]"`. +/// +#[doc = include_example!("rustc_on_unimplemented_filter")] +/// +/// # Formatting +/// +/// The string literals are format strings that accept parameters wrapped in braces - +/// positional and listed parameters are not accepted. +/// The following parameter names are valid: +/// - `Self` and all generic parameters of the trait. +/// - `This`: the name of the trait the attribute is on, without generics. +/// - `This:path`: the full path of the trait the attribute is on, with unresolved generics. +/// - `This:resolved`: the full path of the trait the attribute is on, with resolved generics. +/// Additionally, this will "sugar" the `Fn(...)` traits. +/// - `ItemContext`: the kind of `hir::Node` we're in, things like `"an async block"`, +/// `"a function"`, `"an async function"`, etc. +/// +#[doc = include_example!("rustc_on_unimplemented_format")] +/// +/// [`diagnostic::on_unimplemented`]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute +const _: () = (); diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 661e07af7189c..bdb3f8c9f22ae 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -862,192 +862,21 @@ struct](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/json/struct Don't confuse this with [`errors::Diag`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html)! -## `#[rustc_on_unimplemented]` - -This attribute allows trait definitions to modify error messages when an implementation was -expected but not found. -The string literals in the attribute are format strings and can be formatted with named parameters. -See the Formatting section below for what parameters are permitted. - -```rust,ignore -#[rustc_on_unimplemented(message = "an iterator over \ - elements of type `{A}` cannot be built from a \ - collection of type `{Self}`")] -trait MyIterator { - fn next(&mut self) -> A; -} - -fn iterate_chars>(i: I) { - // ... -} - -fn main() { - iterate_chars(&[1, 2, 3][..]); -} -``` - -When the user compiles this, they will see the following; - -```txt -error[E0277]: an iterator over elements of type `char` cannot be built from a collection of type `&[{integer}]` - --> src/main.rs:13:19 - | -13 | iterate_chars(&[1, 2, 3][..]); - | ------------- ^^^^^^^^^^^^^^ the trait `MyIterator` is not implemented for `&[{integer}]` - | | - | required by a bound introduced by this call - | -note: required by a bound in `iterate_chars` -``` - -You can modify the contents of: - - the main error message (`message`) - - the label (`label`) - - the note(s) (`note`) - -For example, the following attribute - -```rust,ignore -#[rustc_on_unimplemented(message = "message", label = "label", note = "note")] -trait MyIterator { - fn next(&mut self) -> A; -} -``` - -Would generate the following output: - -```text -error[E0277]: message - --> :10:19 - | -10 | iterate_chars(&[1, 2, 3][..]); - | ------------- ^^^^^^^^^^^^^^ label - | | - | required by a bound introduced by this call - | - = help: the trait `MyIterator` is not implemented for `&[{integer}]` - = note: note -note: required by a bound in `iterate_chars` -``` - -The functionality discussed so far is also available with -[`#[diagnostic::on_unimplemented]`](https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnosticon_unimplemented-attribute). -If you can, you should use that instead. - -### Filtering - -To allow more targeted error messages, -it is possible to filter the application of these fields with `on`. - -You can filter on the following boolean flags: - - `crate_local`: whether the code causing the trait bound to not be - fulfilled is part of the user's crate. - This is used to avoid suggesting code changes that would require modifying a dependency. - - `direct`: whether this is a user-specified rather than derived obligation. - - `from_desugaring`: whether we are in some kind of desugaring, - like `?` or a `try` block for example. - This flag can also be matched on, see below. - -You can match on the following names and values, using `name = "value"`: - - `cause`: Match against one variant of the `ObligationCauseCode` enum. - Only `"MainFunctionType"` is supported. - - `from_desugaring`: Match against a particular variant of the `DesugaringKind` enum. - The desugaring is identified by its variant name, for example - `"QuestionMark"` for `?` desugaring, or `"TryBlock"` for `try` blocks. - - `Self` and any generic arguments of the trait, - like `Self = "alloc::string::String"` or `Rhs="i32"`. - -The compiler can provide several values to match on, for example: - - the self_ty, pretty printed with and without type arguments resolved. - - `"{integral}"`, if self_ty is an integral of which the type is known. - - `"[]"`, `"[{ty}]"`, `"[{ty}; _]"`, `"[{ty}; $N]"` when applicable. - - references to said slices and arrays. - - `"fn"`, `"unsafe fn"` or `"#[target_feature] fn"` when self is a function. - - `"{integer}"` and `"{float}"` if the type is a number but we haven't inferred it yet. - - `"{struct}"`, `"{enum}"` and `"{union}"` to match self as an ADT - - combinations of the above, like `"[{integral}; _]"`. - -For example, the `Iterator` trait can be filtered in the following way: - -```rust,ignore -#[rustc_on_unimplemented( - on(Self = "&str", note = "call `.chars()` or `.as_bytes()` on `{Self}`"), - message = "`{Self}` is not an iterator", - label = "`{Self}` is not an iterator", - note = "maybe try calling `.iter()` or a similar method" -)] -pub trait Iterator {} -``` - -Which would produce the following outputs: - -```text -error[E0277]: `Foo` is not an iterator - --> src/main.rs:4:16 - | -4 | for foo in Foo {} - | ^^^ `Foo` is not an iterator - | - = note: maybe try calling `.iter()` or a similar method - = help: the trait `std::iter::Iterator` is not implemented for `Foo` - = note: required by `std::iter::IntoIterator::into_iter` - -error[E0277]: `&str` is not an iterator - --> src/main.rs:5:16 - | -5 | for foo in "" {} - | ^^ `&str` is not an iterator - | - = note: call `.chars()` or `.bytes() on `&str` - = help: the trait `std::iter::Iterator` is not implemented for `&str` - = note: required by `std::iter::IntoIterator::into_iter` -``` - -The `on` filter accepts `all`, `any` and `not` predicates similar to the `cfg` attribute: - -```rust,ignore -#[rustc_on_unimplemented(on( - all(Self = "&str", T = "alloc::string::String"), - note = "you can coerce a `{T}` into a `{Self}` by writing `&*variable`" -))] -pub trait From: Sized { - /* ... */ -} -``` - -### Formatting - -The string literals are format strings that accept parameters wrapped in braces -but positional and listed parameters are not accepted. -The following parameter names are valid: -- `Self` and all generic parameters of the trait. -- `This`: the name of the trait the attribute is on, without generics. -- `This:path`: the full path of the trait the attribute is on, with unresolved generics. -- `This:resolved`: the full path of the trait the attribute is on, with resolved generics. -Additionally, this will "sugar" the `Fn(...)` traits. -- `ItemContext`: the kind of `hir::Node` we're in, things like `"an async block"`, - `"a function"`, `"an async function"`, etc. - -Something like: - -```rust,ignore -#![feature(rustc_attrs)] - -#[rustc_on_unimplemented(message = "Self = `{Self}`, \ - T = `{T}`, this = `{This}`, trait = `{Trait}`, \ - context = `{ItemContext}`")] -pub trait From: Sized { - fn from(x: T) -> Self; -} - -fn main() { - let x: i8 = From::from(42_i32); -} -``` - -Will format the message into -```text -"Self = `i8`, T = `i32`, this = `From`, trait = `From`, context = `a function`" -``` - +## Diagnostic attributes + +There are many attributes that can be used to generate or improve error messages: +- `diagnostic::on_unimplemented` and [`rustc_on_unimplemented`]: customize unimplemented trait errors +- `diagnostic::on_move`: customize borrowcheck errors +- `diagnostic::on_unknown`: customize unresolved imports errors +- `diagnostic::on_unmatched_args`: customize macro matcher errors +- `diagnostic::opaque`: stop the internals of macros from showing up in error messages +- `diagnostic::on_const`: customize non-const trait impl errors +- `rustc_as_ptr`: used by the `dangling_pointers_from_temporaries` lint. +- `rustc_never_returns_null_ptr`: used by the `useless_ptr_null_checks` lint. +- `rustc_no_implicit_autorefs`: used for the `dangerous_implicit_autorefs` lint. + +If possible, consider improving or implementing such an attribute rather than adding custom error +reporting code. + +[`rustc_on_unimplemented`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_ir/attribute.rustc_on_unimplemented.html [diag]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html diff --git a/tests/ui/attributes/doc_examples/rustc_on_unimplemented.rs b/tests/ui/attributes/doc_examples/rustc_on_unimplemented.rs new file mode 100644 index 0000000000000..d61725a4f042a --- /dev/null +++ b/tests/ui/attributes/doc_examples/rustc_on_unimplemented.rs @@ -0,0 +1,16 @@ +//@ dont-require-annotations: ERROR +//@ compile-flags: --crate-type lib -Z ui-testing=no + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented( + message = "cannot add `{Rhs}` to `{Self}`", + label = "no implementation for `{Self} + {Rhs}`", +)] +pub trait MyAdd { + fn add(self, rhs: Rhs) -> Self; +} + +fn main() { + MyAdd::add(42_u8, 42.0); +} diff --git a/tests/ui/attributes/doc_examples/rustc_on_unimplemented.stderr b/tests/ui/attributes/doc_examples/rustc_on_unimplemented.stderr new file mode 100644 index 0000000000000..fb106e0e14572 --- /dev/null +++ b/tests/ui/attributes/doc_examples/rustc_on_unimplemented.stderr @@ -0,0 +1,18 @@ +error[E0277]: cannot add `_` to `u8` + --> $DIR/rustc_on_unimplemented.rs:15:16 + | +15 | MyAdd::add(42_u8, 42.0); + | ---------- ^^^^^ no implementation for `u8 + _` + | | + | required by a bound introduced by this call + | + = help: the trait `MyAdd<_>` is not implemented for `u8` +help: this trait has no implementations, consider adding one + --> $DIR/rustc_on_unimplemented.rs:10:1 + | +10 | pub trait MyAdd { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.rs b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.rs new file mode 100644 index 0000000000000..76eac2be8e098 --- /dev/null +++ b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.rs @@ -0,0 +1,18 @@ +//@ dont-require-annotations: ERROR +//@ compile-flags: --crate-type lib -Z ui-testing=no + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented( + on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",), + on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",), + message = "cannot add `{Rhs}` to `{Self}`", + label = "no implementation for `{Self} + {Rhs}`" +)] +pub trait MyAdd { + fn add(self, rhs: Rhs) -> Self; +} + +fn main() { + MyAdd::add(42_u8, 42.0); +} diff --git a/tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.stderr b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.stderr new file mode 100644 index 0000000000000..3518953c9051d --- /dev/null +++ b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_filter.stderr @@ -0,0 +1,18 @@ +error[E0277]: cannot add `_` to `u8` + --> $DIR/rustc_on_unimplemented_filter.rs:17:16 + | +17 | MyAdd::add(42_u8, 42.0); + | ---------- ^^^^^ no implementation for `u8 + _` + | | + | required by a bound introduced by this call + | + = help: the trait `MyAdd<_>` is not implemented for `u8` +help: this trait has no implementations, consider adding one + --> $DIR/rustc_on_unimplemented_filter.rs:12:1 + | +12 | pub trait MyAdd { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.rs b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.rs new file mode 100644 index 0000000000000..f67f54e279efd --- /dev/null +++ b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.rs @@ -0,0 +1,15 @@ +//@ dont-require-annotations: ERROR +//@ compile-flags: --crate-type lib -Z ui-testing=no + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented(message = "Self = `{Self}`, \n \ + T = `{T}`, this = `{This}`, path = `{This:path}`, \n \ + resolved = `{This:resolved}`, context = `{ItemContext}`")] +pub trait From: Sized { + fn from(x: T) -> Self; +} + +fn main() { + let x: i8 = From::from(42_i32); +} diff --git a/tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.stderr b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.stderr new file mode 100644 index 0000000000000..023ffd76bc470 --- /dev/null +++ b/tests/ui/attributes/doc_examples/rustc_on_unimplemented_format.stderr @@ -0,0 +1,19 @@ +error[E0277]: Self = `i8`, + T = `i32`, this = `From`, path = `From`, + resolved = `From`, context = `a function` + --> $DIR/rustc_on_unimplemented_format.rs:14:28 + | +14 | let x: i8 = From::from(42_i32); + | ---------- ^^^^^^ the trait `From` is not implemented for `i8` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/rustc_on_unimplemented_format.rs:9:1 + | + 9 | pub trait From: Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From aaa57c9a8beec536ad85b6b117ef8c5e1e96f0ba Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 6 Oct 2026 20:28:17 -0700 Subject: [PATCH 59/59] Shrink `PartialRes` and its alignment A couple of places store `NodeMap`, which is `FxHashMap`, which stores `(NodeId, PartialRes)`. `(NodeId, PartialRes)` takes up 32 bytes. `PartialRes` contains a `usize` count of unresolved segments, in *that* path. We don't need room for more than 2^32 unresolved segments, so store it as a u32. That shrinks `PartialRes` and reduces its alignment, so `(NodeId, PartialRes)` shrinks to 20 bytes. We store a *lot* of those. For aws-sdk-ec2 (full check), this reduces max-rss by ~102 MiB (1.84%) --- compiler/rustc_middle/src/middle/resolve.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/middle/resolve.rs b/compiler/rustc_middle/src/middle/resolve.rs index bafb45469a56e..bfa0be6d8c053 100644 --- a/compiler/rustc_middle/src/middle/resolve.rs +++ b/compiler/rustc_middle/src/middle/resolve.rs @@ -38,7 +38,7 @@ use crate::ty::Visibility; #[derive(Copy, Clone, Debug)] pub struct PartialRes { base_res: Res, - unresolved_segments: usize, + unresolved_segments: u32, } impl PartialRes { @@ -52,6 +52,8 @@ impl PartialRes { if base_res == Res::Err { unresolved_segments = 0 } + let unresolved_segments: u32 = + unresolved_segments.try_into().expect("Path had 2^32 unresolved segments"); PartialRes { base_res, unresolved_segments } } @@ -62,7 +64,7 @@ impl PartialRes { #[inline] pub fn unresolved_segments(&self) -> usize { - self.unresolved_segments + self.unresolved_segments as usize } #[inline]