From c0c6e2166d586d8b4b99afd3005725d9aa15f9ea Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Thu, 22 Jan 2026 20:22:06 -0800 Subject: [PATCH 01/14] make generic test invariant of function order --- tests/codegen-llvm/autodiff/generic.rs | 43 +++++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/tests/codegen-llvm/autodiff/generic.rs b/tests/codegen-llvm/autodiff/generic.rs index 6f56460a2b6d1..b31468c91c9c2 100644 --- a/tests/codegen-llvm/autodiff/generic.rs +++ b/tests/codegen-llvm/autodiff/generic.rs @@ -1,6 +1,14 @@ //@ compile-flags: -Zautodiff=Enable -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme +//@ revisions: F32 F64 Main + +// Here we verify that the function `square` can be differentiated over f64. +// This is interesting to test, since the user never calls `square` with f64, so on it's own rustc +// would have no reason to monomorphize it that way. However, Enzyme needs the f64 version of +// `square` in order to be able to differentiate it, so we have logic to enforce the +// monomorphization. Here, we test this logic. + #![feature(autodiff)] use std::autodiff::autodiff_reverse; @@ -12,32 +20,37 @@ fn square + Copy>(x: &T) -> T { } // Ensure that `d_square::` code is generated -// -// CHECK: ; generic::square -// CHECK-NEXT: ; Function Attrs: {{.*}} -// CHECK-NEXT: define internal {{.*}} float -// CHECK-NEXT: start: -// CHECK-NOT: ret -// CHECK: fmul float + +// F32-LABEL: ; generic::square:: +// F32-NEXT: ; Function Attrs: {{.*}} +// F32-NEXT: define internal {{.*}} float +// F32-NEXT: start: +// F32-NOT: ret +// F32: fmul float // Ensure that `d_square::` code is generated even if `square::` was never called -// -// CHECK: ; generic::square -// CHECK-NEXT: ; Function Attrs: -// CHECK-NEXT: define internal {{.*}} double -// CHECK-NEXT: start: -// CHECK-NOT: ret -// CHECK: fmul double + +// F64-LABEL: ; generic::d_square:: +// F64-NEXT: ; Function Attrs: {{.*}} +// F64-NEXT: define internal {{.*}} void +// F64-NEXT: start: +// F64-NEXT: {{(tail )?}}call {{(fastcc )?}}void @diffe_{{.*}}(double {{.*}}, ptr {{.*}}) +// F64-NEXT: ret void + +// Main-LABEL: ; generic::main +// Main: ; call generic::square:: +// Main: ; call generic::d_square:: fn main() { let xf32: f32 = std::hint::black_box(3.0); let xf64: f64 = std::hint::black_box(3.0); + let seed: f64 = std::hint::black_box(1.0); let outputf32 = square::(&xf32); assert_eq!(9.0, outputf32); let mut df_dxf64: f64 = std::hint::black_box(0.0); - let output_f64 = d_square::(&xf64, &mut df_dxf64, 1.0); + let output_f64 = d_square::(&xf64, &mut df_dxf64, seed); assert_eq!(6.0, df_dxf64); } From d7877615b41be6bccfad2e6858b9abc7e1834f6e Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 23 Jan 2026 20:37:58 -0800 Subject: [PATCH 02/14] Update test after new mangling scheme, make test more robust --- tests/codegen-llvm/autodiff/identical_fnc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/codegen-llvm/autodiff/identical_fnc.rs b/tests/codegen-llvm/autodiff/identical_fnc.rs index 1c18e7acc4b63..a8b186c302ea1 100644 --- a/tests/codegen-llvm/autodiff/identical_fnc.rs +++ b/tests/codegen-llvm/autodiff/identical_fnc.rs @@ -8,7 +8,7 @@ // merged placeholder function anymore, and compilation would fail. We prevent this by disabling // LLVM's merge_function pass before AD. Here we implicetely test that our solution keeps working. // We also explicetly test that we keep running merge_function after AD, by checking for two -// identical function calls in the LLVM-IR, while having two different calls in the Rust code. +// identical function calls in the LLVM-IR, despite having two different calls in the Rust code. #![feature(autodiff)] use std::autodiff::autodiff_reverse; @@ -27,14 +27,14 @@ fn square2(x: &f64) -> f64 { // CHECK:; identical_fnc::main // CHECK-NEXT:; Function Attrs: -// CHECK-NEXT:define internal void @_ZN13identical_fnc4main17h6009e4f751bf9407E() +// CHECK-NEXT:define internal void // CHECK-NEXT:start: // CHECK-NOT:br // CHECK-NOT:ret // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) +// CHECK-NEXT:call fastcc void @[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) +// CHECK-NEXT:call fastcc void @[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) fn main() { let x = std::hint::black_box(3.0); From 7bcc8a705383710fe8ae1105799d4e1cb852f0e0 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 23 Jan 2026 21:54:04 -0800 Subject: [PATCH 03/14] update abi handling test --- tests/codegen-llvm/autodiff/abi_handling.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs index 5c8126898a8d7..a8bc482fc293f 100644 --- a/tests/codegen-llvm/autodiff/abi_handling.rs +++ b/tests/codegen-llvm/autodiff/abi_handling.rs @@ -38,14 +38,14 @@ fn square(x: f32) -> f32 { // CHECK-LABEL: ; abi_handling::df1 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } -// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0) +// debug-SAME: (ptr {{.*}}%x, ptr {{.*}}%bx_0) // release-NEXT: define internal fastcc float // release-SAME: (float %x.0.val, float %x.4.val) // CHECK-LABEL: ; abi_handling::f1 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x) +// debug-SAME: (ptr {{.*}}%x) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.val, float %x.4.val) #[autodiff_forward(df1, Dual, Dual)] @@ -58,7 +58,7 @@ fn f1(x: &[f32; 2]) -> f32 { // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } // debug-SAME: (ptr %f, float %x, float %dret) -// release-NEXT: define internal fastcc float +// release-NEXT: define internal fastcc noundef float // release-SAME: (float noundef %x) // CHECK-LABEL: ; abi_handling::f2 @@ -77,13 +77,13 @@ fn f2(f: fn(f32) -> f32, x: f32) -> f32 { // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } // debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0, ptr align 4 %y, ptr align 4 %by_0) -// release-NEXT: define internal fastcc { float, float } +// release-NEXT: define internal fastcc float // release-SAME: (float %x.0.val) // CHECK-LABEL: ; abi_handling::f3 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x, ptr align 4 %y) +// debug-SAME: (ptr {{.*}}%x, ptr {{.*}}%y) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.val) #[autodiff_forward(df3, Dual, Dual, Dual)] @@ -160,7 +160,7 @@ fn f6(i: NestedInput) -> f32 { // CHECK-LABEL: ; abi_handling::f7 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1) +// debug-SAME: (ptr {{.*}}%x.0, ptr {{.*}}%x.1) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.0.val, float %x.1.0.val) #[autodiff_forward(df7, Dual, Dual)] From b6d567c12cb16a0c02928dfea0db24523ddb9c5f Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 23 Jan 2026 23:18:52 -0800 Subject: [PATCH 04/14] Shorten the autodiff batching test, to make it more reliable --- tests/codegen-llvm/autodiff/batched.rs | 83 +++++--------------------- 1 file changed, 16 insertions(+), 67 deletions(-) diff --git a/tests/codegen-llvm/autodiff/batched.rs b/tests/codegen-llvm/autodiff/batched.rs index 0ff6134bc07d5..5a723ff041839 100644 --- a/tests/codegen-llvm/autodiff/batched.rs +++ b/tests/codegen-llvm/autodiff/batched.rs @@ -1,13 +1,11 @@ //@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme -// -// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many -// breakages. One benefit is that we match the IR generated by Enzyme only after running it -// through LLVM's O3 pipeline, which will remove most of the noise. -// However, our integration test could also be affected by changes in how rustc lowers MIR into -// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should -// reduce this test to only match the first lines and the ret instructions. + +// This test combines two features of Enzyme, automatic differentiation and batching. As such, it is +// especially prone to breakages. I reduced it therefore to a minimal check matches argument/return +// types. Based on the original batching author, implementing the batching feature over MLIR instead +// of LLVM should give significantly more reliable performance. #![feature(autodiff)] @@ -22,69 +20,20 @@ fn square(x: &f32) -> f32 { x * x } +// The base ("scalar") case d_square3, without batching. +// CHECK: define internal fastcc float @fwddiffesquare(float %x.0.val, float %"x'.0.val") +// CHECK: %0 = fadd fast float %"x'.0.val", %"x'.0.val" +// CHECK-NEXT: %1 = fmul fast float %0, %x.0.val +// CHECK-NEXT: ret float %1 +// CHECK-NEXT: } + // d_square2 -// CHECK: define internal [4 x float] @fwddiffe4square(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 -// CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 -// CHECK-NEXT: %1 = extractvalue [4 x ptr] %"x'", 1 -// CHECK-NEXT: %"_2'ipl1" = load float, ptr %1, align 4 -// CHECK-NEXT: %2 = extractvalue [4 x ptr] %"x'", 2 -// CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 -// CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 -// CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_2 = load float, ptr %x, align 4 -// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %12 = fadd fast float %4, %8 -// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 -// CHECK-NEXT: %14 = fadd fast float %5, %9 -// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 -// CHECK-NEXT: %16 = fadd fast float %6, %10 -// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 -// CHECK-NEXT: %18 = fadd fast float %7, %11 -// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 -// CHECK-NEXT: ret [4 x float] %19 +// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'") +// CHECK: ret [4 x float] // CHECK-NEXT: } -// d_square3, the extra float is the original return value (x * x) -// CHECK: define internal { float, [4 x float] } @fwddiffe4square.1(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 -// CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 -// CHECK-NEXT: %1 = extractvalue [4 x ptr] %"x'", 1 -// CHECK-NEXT: %"_2'ipl1" = load float, ptr %1, align 4 -// CHECK-NEXT: %2 = extractvalue [4 x ptr] %"x'", 2 -// CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 -// CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 -// CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_2 = load float, ptr %x, align 4 -// CHECK-NEXT: %_0 = fmul float %_2, %_2 -// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %12 = fadd fast float %4, %8 -// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 -// CHECK-NEXT: %14 = fadd fast float %5, %9 -// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 -// CHECK-NEXT: %16 = fadd fast float %6, %10 -// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 -// CHECK-NEXT: %18 = fadd fast float %7, %11 -// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 -// CHECK-NEXT: %20 = insertvalue { float, [4 x float] } undef, float %_0, 0 -// CHECK-NEXT: %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1 -// CHECK-NEXT: ret { float, [4 x float] } %21 +// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.{{.*}}(float %x.0.val, [4 x ptr] %"x'") +// CHECK: ret { float, [4 x float] } // CHECK-NEXT: } fn main() { From 76b6623267dc944fd61e06741327f74ee4820a21 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 23 Jan 2026 11:06:57 +0000 Subject: [PATCH 05/14] target: fix destabilising target-spec-json --- compiler/rustc_target/src/spec/mod.rs | 3 +++ tests/run-make/rust-lld-custom-target/rmake.rs | 6 +++++- tests/run-make/rustdoc-target-spec-json-path/rmake.rs | 8 +++++++- tests/run-make/target-specs/rmake.rs | 9 ++++++++- tests/ui/check-cfg/values-target-json.rs | 3 ++- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ef475630d4943..164db15d24e09 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3352,6 +3352,9 @@ impl Target { Err(format!("could not find specification for target {target_tuple:?}")) } + TargetTuple::TargetJson { ref contents, .. } if !unstable_options => { + Err("custom targets are unstable and require `-Zunstable-options`".to_string()) + } TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents), } } diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 90ba424ffe940..d281d820f47b4 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -15,7 +15,11 @@ fn main() { // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking // the linker to display its version number with a link-arg. assert_rustc_uses_lld( - rustc().crate_type("cdylib").target("custom-target.json").input("lib.rs"), + rustc() + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zunstable-options") + .input("lib.rs"), ); // But it can also be disabled via linker features. diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs index d43aa9b90ac72..8660556564f1e 100644 --- a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs @@ -5,8 +5,14 @@ use run_make_support::{cwd, rustc, rustdoc}; fn main() { let out_dir = "rustdoc-target-spec-json-path"; - rustc().crate_type("lib").input("dummy_core.rs").target("target.json").run(); + rustc() + .arg("-Zunstable-options") + .crate_type("lib") + .input("dummy_core.rs") + .target("target.json") + .run(); rustdoc() + .arg("-Zunstable-options") .input("my_crate.rs") .out_dir(out_dir) .library_search_path(cwd()) diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 69292af5fd69c..6c88f3164e9e4 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -20,13 +20,20 @@ fn main() { .target("my-incomplete-platform.json") .run_fail() .assert_stderr_contains("missing field `llvm-target`"); - let test_platform = rustc() + let _ = rustc() .input("foo.rs") .target("my-x86_64-unknown-linux-gnu-platform") .crate_type("lib") .emit("asm") .run_fail() .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); + let _ = rustc() + .input("foo.rs") + .target("my-awesome-platform.json") + .crate_type("lib") + .emit("asm") + .run_fail() + .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); rustc() .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".") diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index defb286ed19be..21b6af9b55605 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -4,7 +4,8 @@ //@ check-pass //@ no-auto-check-cfg //@ needs-llvm-components: x86 -//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json +//@ compile-flags: --crate-type=lib --check-cfg=cfg() +//@ compile-flags: -Zunstable-options --target={{src-base}}/check-cfg/my-awesome-platform.json //@ ignore-backends: gcc #![feature(lang_items, no_core, auto_traits, rustc_attrs)] From 2a9de6ba853ff78b9b34b655b87313f0737417c5 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 27 Jan 2026 21:35:59 +0100 Subject: [PATCH 06/14] CI: rfl: move to temporary commit to pass `-Zunstable-options` for custom target specs This also takes the chance to move forward the job to Linux v6.19-rc7, thus the previous workaround is not needed anymore. Link: https://github.com/rust-lang/rust/pull/151534 Signed-off-by: Miguel Ojeda --- src/ci/docker/scripts/rfl-build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index e7f86e10f55a5..5352505577400 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,8 +2,8 @@ set -euo pipefail -# https://github.com/rust-lang/rust/pull/145974 -LINUX_VERSION=842cfd8e5aff3157cb25481b2900b49c188d628a +# https://github.com/rust-lang/rust/pull/151534 +LINUX_VERSION=eb268c7972f65fa0b11b051c5ef2b92747bb2b62 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt From 590fa1e6cb42ffdec1857d03ebeb26b5e9ab43c1 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 3 Feb 2026 21:31:28 +0100 Subject: [PATCH 07/14] Convert to inline diagnostics in `rustc_ty_utils` --- Cargo.lock | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_ty_utils/Cargo.toml | 1 - compiler/rustc_ty_utils/messages.ftl | 61 ----------------------- compiler/rustc_ty_utils/src/errors.rs | 72 ++++++++++++++------------- compiler/rustc_ty_utils/src/lib.rs | 2 - 7 files changed, 38 insertions(+), 102 deletions(-) delete mode 100644 compiler/rustc_ty_utils/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 91fce715c8cd1..ee6b26aeebc56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3817,7 +3817,6 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "rustc_ty_utils", "serde_json", "shlex", "tracing", @@ -4809,7 +4808,6 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hashes", "rustc_hir", "rustc_index", diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index d97c552b412b5..0c07c23c6394d 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -49,7 +49,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } -rustc_ty_utils = { path = "../rustc_ty_utils" } serde_json = "1.0.59" shlex = "1.0" tracing = { version = "0.1.35" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b163ae2068a66..49a100fd67573 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -143,7 +143,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_resolve::DEFAULT_LOCALE_RESOURCE, rustc_session::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, - rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index ce08b300cc800..682cf941561fc 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -9,7 +9,6 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl deleted file mode 100644 index c1684bfb43b66..0000000000000 --- a/compiler/rustc_ty_utils/messages.ftl +++ /dev/null @@ -1,61 +0,0 @@ -ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants - -ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants - -ty_utils_array_not_supported = array construction is not supported in generic constants - -ty_utils_assign_not_supported = assignment is not supported in generic constants - -ty_utils_binary_not_supported = unsupported binary operation in generic constants - -ty_utils_block_not_supported = blocks are not supported in generic constants - -ty_utils_borrow_not_supported = borrowing is not supported in generic constants - -ty_utils_box_not_supported = allocations are not allowed in generic constants - -ty_utils_by_use_not_supported = .use is not allowed in generic constants - -ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants - -ty_utils_const_block_not_supported = const blocks are not supported in generic constants - -ty_utils_control_flow_not_supported = control flow is not supported in generic constants - -ty_utils_field_not_supported = field access is not supported in generic constants - -ty_utils_generic_constant_too_complex = overly complex generic constant - .help = consider moving this anonymous constant into a `const` function - .maybe_supported = this operation may be supported in the future - -ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope - .label = generic argument `{$arg}` used twice - .note = for this opaque type - -ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope - .label = argument `{$arg}` is not a generic parameter - .note = for this opaque type - -ty_utils_index_not_supported = indexing is not supported in generic constants - -ty_utils_inline_asm_not_supported = assembly is not supported in generic constants - -ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow - -ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants - -ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop - -ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants - -ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` - -ty_utils_operation_not_supported = unsupported operation in generic constants - -ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants - -ty_utils_tuple_not_supported = tuple construction is not supported in generic constants - -ty_utils_unexpected_fnptr_associated_item = `FnPtr` trait with unexpected associated item - -ty_utils_yield_not_supported = coroutine control flow is not allowed in generic constants diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index f92c405242ce9..ccea5a49bd7cf 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -6,18 +6,18 @@ use rustc_middle::ty::{GenericArg, Ty}; use rustc_span::Span; #[derive(Diagnostic)] -#[diag(ty_utils_needs_drop_overflow)] +#[diag("overflow while checking whether `{$query_ty}` requires drop")] pub(crate) struct NeedsDropOverflow<'tcx> { pub query_ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(ty_utils_generic_constant_too_complex)] -#[help] +#[diag("overly complex generic constant")] +#[help("consider moving this anonymous constant into a `const` function")] pub(crate) struct GenericConstantTooComplex { #[primary_span] pub span: Span, - #[note(ty_utils_maybe_supported)] + #[note("this operation may be supported in the future")] pub maybe_supported: bool, #[subdiagnostic] pub sub: GenericConstantTooComplexSub, @@ -25,84 +25,88 @@ pub(crate) struct GenericConstantTooComplex { #[derive(Subdiagnostic)] pub(crate) enum GenericConstantTooComplexSub { - #[label(ty_utils_borrow_not_supported)] + #[label("borrowing is not supported in generic constants")] BorrowNotSupported(#[primary_span] Span), - #[label(ty_utils_address_and_deref_not_supported)] + #[label("dereferencing or taking the address is not supported in generic constants")] AddressAndDerefNotSupported(#[primary_span] Span), - #[label(ty_utils_array_not_supported)] + #[label("array construction is not supported in generic constants")] ArrayNotSupported(#[primary_span] Span), - #[label(ty_utils_block_not_supported)] + #[label("blocks are not supported in generic constants")] BlockNotSupported(#[primary_span] Span), - #[label(ty_utils_never_to_any_not_supported)] + #[label("coercing the `never` type is not supported in generic constants")] NeverToAnyNotSupported(#[primary_span] Span), - #[label(ty_utils_tuple_not_supported)] + #[label("tuple construction is not supported in generic constants")] TupleNotSupported(#[primary_span] Span), - #[label(ty_utils_index_not_supported)] + #[label("indexing is not supported in generic constants")] IndexNotSupported(#[primary_span] Span), - #[label(ty_utils_field_not_supported)] + #[label("field access is not supported in generic constants")] FieldNotSupported(#[primary_span] Span), - #[label(ty_utils_const_block_not_supported)] + #[label("const blocks are not supported in generic constants")] ConstBlockNotSupported(#[primary_span] Span), - #[label(ty_utils_adt_not_supported)] + #[label("struct/enum construction is not supported in generic constants")] AdtNotSupported(#[primary_span] Span), - #[label(ty_utils_pointer_not_supported)] + #[label("pointer casts are not allowed in generic constants")] PointerNotSupported(#[primary_span] Span), - #[label(ty_utils_yield_not_supported)] + #[label("coroutine control flow is not allowed in generic constants")] YieldNotSupported(#[primary_span] Span), - #[label(ty_utils_loop_not_supported)] + #[label("loops and loop control flow are not supported in generic constants")] LoopNotSupported(#[primary_span] Span), - #[label(ty_utils_box_not_supported)] + #[label("allocations are not allowed in generic constants")] BoxNotSupported(#[primary_span] Span), - #[label(ty_utils_binary_not_supported)] + #[label("unsupported binary operation in generic constants")] BinaryNotSupported(#[primary_span] Span), - #[label(ty_utils_by_use_not_supported)] + #[label(".use is not allowed in generic constants")] ByUseNotSupported(#[primary_span] Span), - #[label(ty_utils_logical_op_not_supported)] + #[label( + "unsupported operation in generic constants, short-circuiting operations would imply control flow" + )] LogicalOpNotSupported(#[primary_span] Span), - #[label(ty_utils_assign_not_supported)] + #[label("assignment is not supported in generic constants")] AssignNotSupported(#[primary_span] Span), - #[label(ty_utils_closure_and_return_not_supported)] + #[label("closures and function keywords are not supported in generic constants")] ClosureAndReturnNotSupported(#[primary_span] Span), - #[label(ty_utils_control_flow_not_supported)] + #[label("control flow is not supported in generic constants")] ControlFlowNotSupported(#[primary_span] Span), - #[label(ty_utils_inline_asm_not_supported)] + #[label("assembly is not supported in generic constants")] InlineAsmNotSupported(#[primary_span] Span), - #[label(ty_utils_operation_not_supported)] + #[label("unsupported operation in generic constants")] OperationNotSupported(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(ty_utils_unexpected_fnptr_associated_item)] +#[diag("`FnPtr` trait with unexpected associated item")] pub(crate) struct UnexpectedFnPtrAssociatedItem { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ty_utils_non_primitive_simd_type)] +#[diag( + "monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}`" +)] pub(crate) struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(ty_utils_impl_trait_duplicate_arg)] +#[diag("non-defining opaque type use in defining scope")] pub(crate) struct DuplicateArg<'tcx> { pub arg: GenericArg<'tcx>, #[primary_span] - #[label] + #[label("generic argument `{$arg}` used twice")] pub span: Span, - #[note] + #[note("for this opaque type")] pub opaque_span: Span, } #[derive(Diagnostic)] -#[diag(ty_utils_impl_trait_not_param, code = E0792)] +#[diag("non-defining opaque type use in defining scope", code = E0792)] pub(crate) struct NotParam<'tcx> { pub arg: GenericArg<'tcx>, #[primary_span] - #[label] + #[label("argument `{$arg}` is not a generic parameter")] pub span: Span, - #[note] + #[note("for this opaque type")] pub opaque_span: Span, } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index d8b50b2d2e42f..9f8f3b240890b 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -31,8 +31,6 @@ pub mod sig_types; mod structural_match; mod ty; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { abi::provide(providers); assoc::provide(providers); From d457ffd4f4589dfdd1f8fd2ef1c3d784018cf127 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 3 Feb 2026 22:44:03 +0100 Subject: [PATCH 08/14] Convert to inline diagnostics in `rustc_monomorphize` --- Cargo.lock | 2 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_monomorphize/Cargo.toml | 1 - compiler/rustc_monomorphize/messages.ftl | 82 ---------------- compiler/rustc_monomorphize/src/errors.rs | 109 ++++++++++++++++------ compiler/rustc_monomorphize/src/lib.rs | 2 - 7 files changed, 82 insertions(+), 116 deletions(-) delete mode 100644 compiler/rustc_monomorphize/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 91fce715c8cd1..b7dd59d857fdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3805,7 +3805,6 @@ dependencies = [ "rustc_mir_build", "rustc_mir_dataflow", "rustc_mir_transform", - "rustc_monomorphize", "rustc_parse", "rustc_passes", "rustc_pattern_analysis", @@ -4384,7 +4383,6 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index d97c552b412b5..28972d1c35ecd 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -37,7 +37,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_mir_build = { path = "../rustc_mir_build" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } rustc_mir_transform = { path = "../rustc_mir_transform" } -rustc_monomorphize = { path = "../rustc_monomorphize" } rustc_parse = { path = "../rustc_parse" } rustc_passes = { path = "../rustc_passes" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b163ae2068a66..80724c6a24f5c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -134,7 +134,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE, rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, - rustc_monomorphize::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 0829d52283abf..552c092ef7c46 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl deleted file mode 100644 index 9c791208c0935..0000000000000 --- a/compiler/rustc_monomorphize/messages.ftl +++ /dev/null @@ -1,82 +0,0 @@ -monomorphize_abi_error_disabled_vector_type = - this function {$is_call -> - [true] call - *[false] definition - } uses {$is_scalable -> - [true] scalable - *[false] SIMD - } vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> - [true] {" "}in the caller - *[false] {""} - } - .label = function {$is_call -> - [true] called - *[false] defined - } here - .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) - -monomorphize_abi_error_unsupported_unsized_parameter = - this function {$is_call -> - [true] call - *[false] definition - } uses unsized type `{$ty}` which is not supported with the chosen ABI - .label = function {$is_call -> - [true] called - *[false] defined - } here - .help = only rustic ABIs support unsized parameters - -monomorphize_abi_error_unsupported_vector_type = - this function {$is_call -> - [true] call - *[false] definition - } uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI - .label = function {$is_call -> - [true] called - *[false] defined - } here - -monomorphize_abi_required_target_feature = - this function {$is_call -> - [true] call - *[false] definition - } uses ABI "{$abi}" which requires the `{$required_feature}` target feature, which is not enabled{$is_call -> - [true] {" "}in the caller - *[false] {""} - } - .label = function {$is_call -> - [true] called - *[false] defined - } here - .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) - -monomorphize_couldnt_dump_mono_stats = - unexpected error occurred while dumping monomorphization stats: {$error} - -monomorphize_encountered_error_while_instantiating = - the above error was encountered while instantiating `{$kind} {$instance}` - -monomorphize_encountered_error_while_instantiating_global_asm = - the above error was encountered while instantiating `global_asm` - -monomorphize_large_assignments = - moving {$size} bytes - .label = value moved from here - .note = the current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` - -monomorphize_no_optimized_mir = - missing optimized MIR for `{$instance}` in the crate `{$crate_name}` - .note = missing optimized MIR for this item (was the crate `{$crate_name}` compiled with `--emit=metadata`?) - -monomorphize_recursion_limit = - reached the recursion limit while instantiating `{$instance}` - .note = `{$def_path_str}` defined here - -monomorphize_start_not_found = using `fn main` requires the standard library - .help = use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]` - -monomorphize_static_initializer_cyclic = static initializer forms a cycle involving `{$head}` - .label = part of this cycle - .note = cyclic static initializers are not supported for target `{$target}` - -monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 723649f22117e..d045ae0b92cba 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -3,37 +3,41 @@ use rustc_middle::ty::{Instance, Ty}; use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] -#[diag(monomorphize_recursion_limit)] +#[diag("reached the recursion limit while instantiating `{$instance}`")] pub(crate) struct RecursionLimit<'tcx> { #[primary_span] pub span: Span, pub instance: Instance<'tcx>, - #[note] + #[note("`{$def_path_str}` defined here")] pub def_span: Span, pub def_path_str: String, } #[derive(Diagnostic)] -#[diag(monomorphize_no_optimized_mir)] +#[diag("missing optimized MIR for `{$instance}` in the crate `{$crate_name}`")] pub(crate) struct NoOptimizedMir { - #[note] + #[note( + "missing optimized MIR for this item (was the crate `{$crate_name}` compiled with `--emit=metadata`?)" + )] pub span: Span, pub crate_name: Symbol, pub instance: String, } #[derive(LintDiagnostic)] -#[diag(monomorphize_large_assignments)] -#[note] +#[diag("moving {$size} bytes")] +#[note( + "the current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = \"...\"]`" +)] pub(crate) struct LargeAssignmentsLint { - #[label] + #[label("value moved from here")] pub span: Span, pub size: u64, pub limit: u64, } #[derive(Diagnostic)] -#[diag(monomorphize_symbol_already_defined)] +#[diag("symbol `{$symbol}` is already defined")] pub(crate) struct SymbolAlreadyDefined { #[primary_span] pub span: Option, @@ -41,13 +45,13 @@ pub(crate) struct SymbolAlreadyDefined { } #[derive(Diagnostic)] -#[diag(monomorphize_couldnt_dump_mono_stats)] +#[diag("unexpected error occurred while dumping monomorphization stats: {$error}")] pub(crate) struct CouldntDumpMonoStats { pub error: String, } #[derive(Diagnostic)] -#[diag(monomorphize_encountered_error_while_instantiating)] +#[diag("the above error was encountered while instantiating `{$kind} {$instance}`")] pub(crate) struct EncounteredErrorWhileInstantiating<'tcx> { #[primary_span] pub span: Span, @@ -56,23 +60,41 @@ pub(crate) struct EncounteredErrorWhileInstantiating<'tcx> { } #[derive(Diagnostic)] -#[diag(monomorphize_encountered_error_while_instantiating_global_asm)] +#[diag("the above error was encountered while instantiating `global_asm`")] pub(crate) struct EncounteredErrorWhileInstantiatingGlobalAsm { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(monomorphize_start_not_found)] -#[help] +#[diag("using `fn main` requires the standard library")] +#[help( + "use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]`" +)] pub(crate) struct StartNotFound; #[derive(Diagnostic)] -#[diag(monomorphize_abi_error_disabled_vector_type)] -#[help] +#[diag("this function {$is_call -> + [true] call + *[false] definition +} uses {$is_scalable -> + [true] scalable + *[false] SIMD +} vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {\" \"}in the caller + *[false] {\"\"} +}")] +#[help( + "consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable=\"{$required_feature}\")]`)" +)] pub(crate) struct AbiErrorDisabledVectorType<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> + [true] called + *[false] defined + } here" + )] pub span: Span, pub required_feature: &'a str, pub ty: Ty<'a>, @@ -83,11 +105,21 @@ pub(crate) struct AbiErrorDisabledVectorType<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_abi_error_unsupported_unsized_parameter)] -#[help] +#[diag( + "this function {$is_call -> + [true] call + *[false] definition + } uses unsized type `{$ty}` which is not supported with the chosen ABI" +)] +#[help("only rustic ABIs support unsized parameters")] pub(crate) struct AbiErrorUnsupportedUnsizedParameter<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> + [true] called + *[false] defined + } here" + )] pub span: Span, pub ty: Ty<'a>, /// Whether this is a problem at a call site or at a declaration. @@ -95,10 +127,20 @@ pub(crate) struct AbiErrorUnsupportedUnsizedParameter<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_abi_error_unsupported_vector_type)] +#[diag( + "this function {$is_call -> + [true] call + *[false] definition + } uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI" +)] pub(crate) struct AbiErrorUnsupportedVectorType<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> + [true] called + *[false] defined + } here" + )] pub span: Span, pub ty: Ty<'a>, /// Whether this is a problem at a call site or at a declaration. @@ -106,11 +148,24 @@ pub(crate) struct AbiErrorUnsupportedVectorType<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_abi_required_target_feature)] -#[help] +#[diag("this function {$is_call -> + [true] call + *[false] definition +} uses ABI \"{$abi}\" which requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {\" \"}in the caller + *[false] {\"\"} +}")] +#[help( + "consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable=\"{$required_feature}\")]`)" +)] pub(crate) struct AbiRequiredTargetFeature<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> +[true] called +*[false] defined +} here" + )] pub span: Span, pub required_feature: &'a str, pub abi: &'a str, @@ -119,12 +174,12 @@ pub(crate) struct AbiRequiredTargetFeature<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_static_initializer_cyclic)] -#[note] +#[diag("static initializer forms a cycle involving `{$head}`")] +#[note("cyclic static initializers are not supported for target `{$target}`")] pub(crate) struct StaticInitializerCyclic<'a> { #[primary_span] pub span: Span, - #[label] + #[label("part of this cycle")] pub labels: Vec, pub head: &'a str, pub target: &'a str, diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 30f6934bb9372..51753563b67c9 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -20,8 +20,6 @@ mod mono_checks; mod partitioning; mod util; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, From 07e4a994d61dccda69135a7b50ce69f6d93deec8 Mon Sep 17 00:00:00 2001 From: Usman Akinyemi Date: Thu, 29 Jan 2026 14:07:41 +0530 Subject: [PATCH 09/14] citool: report debuginfo test statistics Extend CI postprocessing to aggregate pass/fail/ignored counts for debuginfo tests. Tests are identified via their reported suite names (e.g. debuginfo-gdb, debuginfo-lldb or debuginfo-cdb). Signed-off-by: Usman Akinyemi --- src/build_helper/src/metrics.rs | 23 +++++++++++++++++++++++ src/ci/citool/src/analysis.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 07157e364158d..98dd952033e5c 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -111,6 +111,29 @@ pub struct JsonStepSystemStats { pub cpu_utilization_percent: f64, } +#[derive(Eq, Hash, PartialEq, Debug)] +pub enum DebuggerKind { + Gdb, + Lldb, + Cdb, +} + +impl DebuggerKind { + pub fn debuginfo_kind(name: &str) -> Option { + let name = name.to_ascii_lowercase(); + + if name.contains("debuginfo-gdb") { + Some(DebuggerKind::Gdb) + } else if name.contains("debuginfo-lldb") { + Some(DebuggerKind::Lldb) + } else if name.contains("debuginfo-cdb") { + Some(DebuggerKind::Cdb) + } else { + None + } + } +} + fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result { use serde::Deserialize as _; Option::::deserialize(d).map(|f| f.unwrap_or(f64::NAN)) diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs index 39b115154f9f4..ec65d9dcb5282 100644 --- a/src/ci/citool/src/analysis.rs +++ b/src/ci/citool/src/analysis.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use std::time::Duration; use build_helper::metrics::{ - BuildStep, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name, + BuildStep, DebuggerKind, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name, format_build_steps, }; @@ -139,11 +139,39 @@ fn record_test_suites(metrics: &JsonRoot) { let table = render_table(aggregated); println!("\n# Test results\n"); println!("{table}"); + report_debuginfo_statistics(&suites); } else { eprintln!("No test suites found in metrics"); } } +fn report_debuginfo_statistics(suites: &[&TestSuite]) { + let mut debugger_test_record: HashMap = HashMap::new(); + for suite in suites { + if let TestSuiteMetadata::Compiletest { .. } = suite.metadata { + for test in &suite.tests { + if let Some(kind) = DebuggerKind::debuginfo_kind(&test.name) { + let record = + debugger_test_record.entry(kind).or_insert(TestSuiteRecord::default()); + match test.outcome { + TestOutcome::Passed => record.passed += 1, + TestOutcome::Ignored { .. } => record.ignored += 1, + TestOutcome::Failed => record.failed += 1, + } + } + } + } + } + + println!("## DebugInfo Test Statistics"); + for (kind, record) in debugger_test_record { + println!( + "- {:?}: Passed ✅={}, Failed ❌={}, Ignored 🚫={}", + kind, record.passed, record.failed, record.ignored + ); + } +} + fn render_table(suites: BTreeMap) -> String { use std::fmt::Write; From dcdffe8d808b84f2208c0dcb817bc46b0242e34a Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Mon, 12 Jan 2026 14:48:05 +0800 Subject: [PATCH 10/14] link modifier `export-symbols`: export all global symbols from selected uptream c static libraries --- .../src/attributes/link_attrs.rs | 21 +++- .../src/session_diagnostics.rs | 9 +- compiler/rustc_codegen_ssa/src/back/link.rs | 95 +++++++++++++++++-- .../rustc_hir/src/attrs/data_structures.rs | 6 +- compiler/rustc_interface/src/tests.rs | 18 ++-- compiler/rustc_metadata/src/native_libs.rs | 2 +- .../rustc_session/src/config/native_libs.rs | 15 ++- compiler/rustc_span/src/symbol.rs | 1 + .../cdylib-export-c-library-symbols/foo.c | 1 + .../cdylib-export-c-library-symbols/foo.rs | 10 ++ .../foo_export.rs | 10 ++ .../cdylib-export-c-library-symbols/rmake.rs | 36 +++++++ ...ure-gate-link-arg-attribute.in_flag.stderr | 2 +- tests/ui/link-native-libs/link-arg-error2.rs | 5 + .../link-native-libs/link-arg-error2.stderr | 2 + .../ui/link-native-libs/link-arg-from-rs2.rs | 7 ++ .../link-native-libs/link-arg-from-rs2.stderr | 8 ++ .../link-attr-validation-late.stderr | 6 +- .../modifiers-bad.blank.stderr | 2 +- .../modifiers-bad.no-prefix.stderr | 2 +- .../modifiers-bad.prefix-only.stderr | 2 +- .../modifiers-bad.unknown.stderr | 2 +- 22 files changed, 226 insertions(+), 36 deletions(-) create mode 100644 tests/run-make/cdylib-export-c-library-symbols/foo.c create mode 100644 tests/run-make/cdylib-export-c-library-symbols/foo.rs create mode 100644 tests/run-make/cdylib-export-c-library-symbols/foo_export.rs create mode 100644 tests/run-make/cdylib-export-c-library-symbols/rmake.rs create mode 100644 tests/ui/link-native-libs/link-arg-error2.rs create mode 100644 tests/ui/link-native-libs/link-arg-error2.stderr create mode 100644 tests/ui/link-native-libs/link-arg-from-rs2.rs create mode 100644 tests/ui/link-native-libs/link-arg-from-rs2.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index c9da2f3b14bf9..6c52be9bd2294 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -12,10 +12,10 @@ use super::prelude::*; use super::util::parse_single_integer; use crate::attributes::cfg::parse_cfg_entry; use crate::session_diagnostics::{ - AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86, - IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange, - LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, - WholeArchiveNeedsStatic, + AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic, + ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier, + LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers, + NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic, }; pub(crate) struct LinkNameParser; @@ -165,6 +165,14 @@ impl CombineAttributeParser for LinkParser { cx.emit_err(BundleNeedsStatic { span }); } + (sym::export_symbols, Some(NativeLibKind::Static { export_symbols, .. })) => { + assign_modifier(export_symbols) + } + + (sym::export_symbols, _) => { + cx.emit_err(ExportSymbolsNeedsStatic { span }); + } + (sym::verbatim, _) => assign_modifier(&mut verbatim), ( @@ -190,6 +198,7 @@ impl CombineAttributeParser for LinkParser { span, &[ sym::bundle, + sym::export_symbols, sym::verbatim, sym::whole_dash_archive, sym::as_dash_needed, @@ -285,7 +294,9 @@ impl LinkParser { }; let link_kind = match link_kind { - kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None }, + kw::Static => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } sym::dylib => NativeLibKind::Dylib { as_needed: None }, sym::framework => { if !sess.target.is_like_darwin { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index fb4d9c660a190..b0a334210f746 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -909,7 +909,7 @@ pub(crate) struct RawDylibOnlyWindows { #[derive(Diagnostic)] #[diag( - "invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed" + "invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols" )] pub(crate) struct InvalidLinkModifier { #[primary_span] @@ -938,6 +938,13 @@ pub(crate) struct BundleNeedsStatic { pub span: Span, } +#[derive(Diagnostic)] +#[diag("linking modifier `export-symbols` is only compatible with `static` linking kind")] +pub(crate) struct ExportSymbolsNeedsStatic { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("linking modifier `whole-archive` is only compatible with `static` linking kind")] pub(crate) struct WholeArchiveNeedsStatic { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c8109db86e2f2..5a732382c9818 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -11,10 +11,11 @@ use std::{env, fmt, fs, io, mem, str}; use find_msvc_tools; use itertools::Itertools; +use object::{Object, ObjectSection, ObjectSymbol}; use regex::Regex; use rustc_arena::TypedArena; use rustc_attr_parsing::eval_config_entry; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; @@ -2185,6 +2186,71 @@ fn add_rpath_args( } } +fn add_c_staticlib_symbols( + sess: &Session, + lib: &NativeLib, + out: &mut Vec<(String, SymbolExportKind)>, +) -> io::Result<()> { + let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess); + + let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? }; + + let archive = object::read::archive::ArchiveFile::parse(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + for member in archive.members() { + let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let data = member + .data(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // clang LTO: raw LLVM bitcode + if data.starts_with(b"BC\xc0\xde") { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LLVM bitcode object in C static library (LTO not supported)", + )); + } + + let object = object::File::parse(&*data) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // gcc / clang ELF / Mach-O LTO + if object.sections().any(|s| { + s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false) + }) { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LTO object in C static library is not supported", + )); + } + + for symbol in object.symbols() { + if symbol.scope() != object::SymbolScope::Dynamic { + continue; + } + + let name = match symbol.name() { + Ok(n) => n, + Err(_) => continue, + }; + + let export_kind = match symbol.kind() { + object::SymbolKind::Text => SymbolExportKind::Text, + object::SymbolKind::Data => SymbolExportKind::Data, + _ => continue, + }; + + // FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. + // Need to be resolved. + out.push((name.to_string(), export_kind)); + } + } + + Ok(()) +} + /// Produce the linker command line containing linker path and arguments. /// /// When comments in the function say "order-(in)dependent" they mean order-dependence between @@ -2217,6 +2283,25 @@ fn linker_with_args( ); let link_output_kind = link_output_kind(sess, crate_type); + let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + + if crate_type == CrateType::Cdylib { + let mut seen = FxHashSet::default(); + + for lib in &codegen_results.crate_info.used_libraries { + if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind + && seen.insert((lib.name, lib.verbatim)) + { + if let Err(err) = add_c_staticlib_symbols(&sess, lib, &mut export_symbols) { + sess.dcx().fatal(format!( + "failed to process C static library `{}`: {}", + lib.name, err + )); + } + } + } + } + // ------------ Early order-dependent options ------------ // If we're building something like a dynamic library then some platforms @@ -2224,11 +2309,7 @@ fn linker_with_args( // dynamic library. // Must be passed before any libraries to prevent the symbols to export from being thrown away, // at least on some platforms (e.g. windows-gnu). - cmd.export_symbols( - tmpdir, - crate_type, - &codegen_results.crate_info.exported_symbols[&crate_type], - ); + cmd.export_symbols(tmpdir, crate_type, &export_symbols); // Can be used for adding custom CRT objects or overriding order-dependent options above. // FIXME: In practice built-in target specs use this for arbitrary order-independent options, @@ -2678,7 +2759,7 @@ fn add_native_libs_from_crate( let name = lib.name.as_str(); let verbatim = lib.verbatim; match lib.kind { - NativeLibKind::Static { bundle, whole_archive } => { + NativeLibKind::Static { bundle, whole_archive, .. } => { if link_static { let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 6138ffc8d9544..a53eff4637ff2 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -331,6 +331,8 @@ pub enum NativeLibKind { bundle: Option, /// Whether to link static library without throwing any object files away whole_archive: Option, + /// Whether to export c static library symbols + export_symbols: Option, }, /// Dynamic library (e.g. `libfoo.so` on Linux) /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). @@ -363,8 +365,8 @@ pub enum NativeLibKind { impl NativeLibKind { pub fn has_modifiers(&self) -> bool { match self { - NativeLibKind::Static { bundle, whole_archive } => { - bundle.is_some() || whole_archive.is_some() + NativeLibKind::Static { bundle, whole_archive, export_symbols } => { + bundle.is_some() || whole_archive.is_some() || export_symbols.is_some() } NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0f60e86e0ca3c..b0272d726bc38 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -379,7 +379,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -401,7 +401,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -423,13 +423,13 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { name: String::from("b"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -445,7 +445,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -467,7 +467,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -501,7 +501,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -528,7 +528,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -549,7 +549,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b160b3fe9bb3c..0c06d1be9a3fd 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -161,7 +161,7 @@ fn find_bundled_library( tcx: TyCtxt<'_>, ) -> Option { let sess = tcx.sess; - if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind + if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) { diff --git a/compiler/rustc_session/src/config/native_libs.rs b/compiler/rustc_session/src/config/native_libs.rs index 71d3e222c8a15..28e2d0f94104b 100644 --- a/compiler/rustc_session/src/config/native_libs.rs +++ b/compiler/rustc_session/src/config/native_libs.rs @@ -53,7 +53,9 @@ fn parse_native_lib(cx: &ParseNativeLibCx<'_>, value: &str) -> NativeLib { let NativeLibParts { kind, modifiers, name, new_name } = split_native_lib_value(value); let kind = kind.map_or(NativeLibKind::Unspecified, |kind| match kind { - "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, + "static" => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } "dylib" => NativeLibKind::Dylib { as_needed: None }, "framework" => NativeLibKind::Framework { as_needed: None }, "link-arg" => { @@ -105,7 +107,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li Some(("-", m)) => (m, false), _ => cx.early_dcx.early_fatal( "invalid linking modifier syntax, expected '+' or '-' prefix \ - before one of: bundle, verbatim, whole-archive, as-needed", + before one of: bundle, verbatim, whole-archive, as-needed, export-symbols", ), }; @@ -125,6 +127,13 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li ("bundle", _) => early_dcx .early_fatal("linking modifier `bundle` is only compatible with `static` linking kind"), + ("export-symbols", NativeLibKind::Static { export_symbols, .. }) => { + assign_modifier(export_symbols) + } + ("export-symbols", _) => early_dcx.early_fatal( + "linking modifier `export-symbols` is only compatible with `static` linking kind", + ), + ("verbatim", _) => assign_modifier(&mut native_lib.verbatim), ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { @@ -151,7 +160,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li _ => early_dcx.early_fatal(format!( "unknown linking modifier `{modifier}`, expected one \ - of: bundle, verbatim, whole-archive, as-needed" + of: bundle, verbatim, whole-archive, as-needed, export-symbols" )), } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b0ef95d10ffa0..c88dd0948b2a9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1002,6 +1002,7 @@ symbols! { explicit_tail_calls, export_name, export_stable, + export_symbols: "export-symbols", expr, expr_2021, expr_fragment_specifier_2024, diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.c b/tests/run-make/cdylib-export-c-library-symbols/foo.c new file mode 100644 index 0000000000000..a062aca03b315 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.c @@ -0,0 +1 @@ +void my_function() {} diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.rs b/tests/run-make/cdylib-export-c-library-symbols/foo.rs new file mode 100644 index 0000000000000..ac641aaed00f8 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.rs @@ -0,0 +1,10 @@ +extern "C" { + pub fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +} diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs new file mode 100644 index 0000000000000..1eda294ef41c3 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs @@ -0,0 +1,10 @@ +extern "C" { + fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +} diff --git a/tests/run-make/cdylib-export-c-library-symbols/rmake.rs b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs new file mode 100644 index 0000000000000..cb237eceedadf --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs @@ -0,0 +1,36 @@ +//@ ignore-nvptx64 +//@ ignore-wasm +//@ ignore-cross-compile +// FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. +// Need to be resolved. +//@ ignore-windows +//@ ignore-apple +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, cc, dynamic_lib_name, is_darwin, llvm_nm, rustc}; + +fn main() { + cc().input("foo.c").arg("-c").out_exe("foo.o").run(); + build_native_static_lib("foo"); + + rustc().input("foo.rs").arg("-lstatic=foo").crate_type("cdylib").run(); + + let out = llvm_nm() + .input(dynamic_lib_name("foo")) + .run() + .assert_stdout_not_contains_regex("T *my_function"); + + rustc().input("foo_export.rs").arg("-lstatic:+export-symbols=foo").crate_type("cdylib").run(); + + if is_darwin() { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T _my_function"); + } else { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T my_function"); + } +} diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr index 4d65db3c66d0b..218a4769d9542 100644 --- a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr +++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/link-arg-error2.rs b/tests/ui/link-native-libs/link-arg-error2.rs new file mode 100644 index 0000000000000..a51dec0614b5f --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -l link-arg:+export-symbols=arg -Z unstable-options + +fn main() {} + +//~? ERROR linking modifier `export-symbols` is only compatible with `static` linking kind diff --git a/tests/ui/link-native-libs/link-arg-error2.stderr b/tests/ui/link-native-libs/link-arg-error2.stderr new file mode 100644 index 0000000000000..61bcf7dba2829 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.stderr @@ -0,0 +1,2 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.rs b/tests/ui/link-native-libs/link-arg-from-rs2.rs new file mode 100644 index 0000000000000..3074fec6c1c8f --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.rs @@ -0,0 +1,7 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] +//~^ ERROR linking modifier `export-symbols` is only compatible with `static` linking kind +extern "C" {} + +pub fn main() {} diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.stderr b/tests/ui/link-native-libs/link-arg-from-rs2.stderr new file mode 100644 index 0000000000000..af3b25253e052 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.stderr @@ -0,0 +1,8 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + --> $DIR/link-arg-from-rs2.rs:3:53 + | +LL | #[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index b09431f923aaf..4a4a193752070 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -178,13 +178,13 @@ LL | #[link(name = "...", wasm_import_module())] | = note: for more information, visit -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:31:34 | LL | #[link(name = "...", modifiers = "")] | ^^ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:32:34 | LL | #[link(name = "...", modifiers = "no-plus-minus")] @@ -196,7 +196,7 @@ error[E0539]: malformed `link` attribute input LL | #[link(name = "...", modifiers = "+unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ | | - | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" + | valid arguments are "bundle", "export-symbols", "verbatim", "whole-archive" or "as-needed" | = note: for more information, visit diff --git a/tests/ui/link-native-libs/modifiers-bad.blank.stderr b/tests/ui/link-native-libs/modifiers-bad.blank.stderr index ea36af0b4cfa9..6a1953e008eef 100644 --- a/tests/ui/link-native-libs/modifiers-bad.blank.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.blank.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr index ea36af0b4cfa9..6a1953e008eef 100644 --- a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr index 1e701374688fe..46720cf0b15e9 100644 --- a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr index 75950ad9c64c7..d47694a5aeca8 100644 --- a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols From 8e62b1d0e119e498ad51f44475b376b20d60fea8 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 4 Feb 2026 03:55:50 +0000 Subject: [PATCH 11/14] Fix set_times_nofollow for directory on windows --- library/std/src/fs/tests.rs | 51 +++++++++++++++++++++++++++++++ library/std/src/sys/fs/windows.rs | 4 +-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 6d0b261dcadcf..42f3ccc340b27 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -2301,6 +2301,57 @@ fn test_fs_set_times() { } } +#[test] +fn test_fs_set_times_on_dir() { + #[cfg(target_vendor = "apple")] + use crate::os::darwin::fs::FileTimesExt; + #[cfg(windows)] + use crate::os::windows::fs::FileTimesExt; + + let tmp = tmpdir(); + let dir_path = tmp.join("testdir"); + fs::create_dir(&dir_path).unwrap(); + + let mut times = FileTimes::new(); + let accessed = SystemTime::UNIX_EPOCH + Duration::from_secs(12345); + let modified = SystemTime::UNIX_EPOCH + Duration::from_secs(54321); + times = times.set_accessed(accessed).set_modified(modified); + + #[cfg(any(windows, target_vendor = "apple"))] + let created = SystemTime::UNIX_EPOCH + Duration::from_secs(32123); + #[cfg(any(windows, target_vendor = "apple"))] + { + times = times.set_created(created); + } + + match fs::set_times(&dir_path, times) { + // Allow unsupported errors on platforms which don't support setting times. + #[cfg(not(any( + windows, + all( + unix, + not(any( + target_os = "android", + target_os = "redox", + target_os = "espidf", + target_os = "horizon" + )) + ) + )))] + Err(e) if e.kind() == ErrorKind::Unsupported => return, + Err(e) => panic!("error setting directory times: {e:?}"), + Ok(_) => {} + } + + let metadata = fs::metadata(&dir_path).unwrap(); + assert_eq!(metadata.accessed().unwrap(), accessed); + assert_eq!(metadata.modified().unwrap(), modified); + #[cfg(any(windows, target_vendor = "apple"))] + { + assert_eq!(metadata.created().unwrap(), created); + } +} + #[test] fn test_fs_set_times_follows_symlink() { #[cfg(target_vendor = "apple")] diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index fc8aec2f3f7c4..74854cdeb498d 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -1556,7 +1556,7 @@ pub fn set_perm(p: &WCStr, perm: FilePermissions) -> io::Result<()> { pub fn set_times(p: &WCStr, times: FileTimes) -> io::Result<()> { let mut opts = OpenOptions::new(); - opts.write(true); + opts.access_mode(c::FILE_WRITE_ATTRIBUTES); opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS); let file = File::open_native(p, &opts)?; file.set_times(times) @@ -1564,7 +1564,7 @@ pub fn set_times(p: &WCStr, times: FileTimes) -> io::Result<()> { pub fn set_times_nofollow(p: &WCStr, times: FileTimes) -> io::Result<()> { let mut opts = OpenOptions::new(); - opts.write(true); + opts.access_mode(c::FILE_WRITE_ATTRIBUTES); // `FILE_FLAG_OPEN_REPARSE_POINT` for no_follow behavior opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT); let file = File::open_native(p, &opts)?; From c77779e5294722c372ee834306118810e930f96e Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 3 Feb 2026 22:15:36 -0800 Subject: [PATCH 12/14] rustbook/README.md: add missing `)` To match the opening `(` before the reference to PR 127786 --- src/tools/rustbook/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rustbook/README.md b/src/tools/rustbook/README.md index d9570c23ead17..a9fd1b75b5724 100644 --- a/src/tools/rustbook/README.md +++ b/src/tools/rustbook/README.md @@ -10,7 +10,7 @@ This is invoked automatically when building mdbook-style documentation, for exam ## Cargo workspace -This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786): +This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786)): - Avoids requiring checking out submodules for developers who are not working on the documentation. Otherwise, some submodules such as those that have custom preprocessors would be required for cargo to find the dependencies. - Avoids problems with updating dependencies. Unfortunately this workspace has a rather large set of dependencies, which can make coordinating updates difficult (see [#127890](https://github.com/rust-lang/rust/issues/127890)). From ae21d43933419d80a2471afbd26d6e288e6666a7 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 3 Feb 2026 22:28:34 +0100 Subject: [PATCH 13/14] Convert to inline diagnostics in `rustc_privacy` --- Cargo.lock | 2 -- compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_privacy/Cargo.toml | 1 - compiler/rustc_privacy/messages.ftl | 39 --------------------- compiler/rustc_privacy/src/errors.rs | 50 ++++++++++++++++++--------- compiler/rustc_privacy/src/lib.rs | 2 -- 7 files changed, 33 insertions(+), 63 deletions(-) delete mode 100644 compiler/rustc_privacy/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 4cbc98beae116..e209821c5d701 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3803,7 +3803,6 @@ dependencies = [ "rustc_parse", "rustc_passes", "rustc_pattern_analysis", - "rustc_privacy", "rustc_public", "rustc_resolve", "rustc_session", @@ -4487,7 +4486,6 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_macros", "rustc_middle", diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index d184b6c8947c6..ee6ffcca29ad0 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -37,7 +37,6 @@ rustc_monomorphize = { path = "../rustc_monomorphize" } rustc_parse = { path = "../rustc_parse" } rustc_passes = { path = "../rustc_passes" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } -rustc_privacy = { path = "../rustc_privacy" } rustc_public = { path = "../rustc_public", features = ["rustc_internal"] } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 0ab71ad9981b7..ffed24d72c418 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -134,7 +134,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_privacy::DEFAULT_LOCALE_RESOURCE, rustc_resolve::DEFAULT_LOCALE_RESOURCE, rustc_session::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index c8bfdb913041c..ff59c19b6bb66 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl deleted file mode 100644 index 43c34a109d721..0000000000000 --- a/compiler/rustc_privacy/messages.ftl +++ /dev/null @@ -1,39 +0,0 @@ -privacy_field_is_private = - {$len -> - [1] field - *[other] fields - } {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> - [1] is - *[other] are - } private - .label = in this type -privacy_field_is_private_is_update_syntax_label = {$rest_len -> - [1] field - *[other] fields - } {$rest_field_names} {$rest_len -> - [1] is - *[other] are - } private -privacy_field_is_private_label = private field - -privacy_from_private_dep_in_public_interface = - {$kind} `{$descr}` from private dependency '{$krate}' in public interface - -privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface - .label = can't leak {$vis_descr} {$kind} - .visibility_label = `{$descr}` declared as {$vis_descr} - -privacy_item_is_private = {$kind} `{$descr}` is private - .label = private {$kind} - -privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}` - .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}` - .ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}` - -privacy_report_effective_visibility = {$descr} - -privacy_unnameable_types_lint = {$kind} `{$descr}` is reachable but cannot be named - .label = reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}` - -privacy_unnamed_item_is_private = {$kind} is private - .label = private {$kind} diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 4d1d58c08528c..af4f0d61aa11e 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -4,11 +4,17 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] -#[diag(privacy_field_is_private, code = E0451)] +#[diag("{$len -> + [1] field + *[other] fields +} {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> + [1] is + *[other] are +} private", code = E0451)] pub(crate) struct FieldIsPrivate { #[primary_span] pub span: MultiSpan, - #[label] + #[label("in this type")] pub struct_span: Option, pub field_names: String, pub variant_descr: &'static str, @@ -20,14 +26,22 @@ pub(crate) struct FieldIsPrivate { #[derive(Subdiagnostic)] pub(crate) enum FieldIsPrivateLabel { - #[label(privacy_field_is_private_is_update_syntax_label)] + #[label( + "{$rest_len -> + [1] field + *[other] fields + } {$rest_field_names} {$rest_len -> + [1] is + *[other] are + } private" + )] IsUpdateSyntax { #[primary_span] span: Span, rest_field_names: String, rest_len: usize, }, - #[label(privacy_field_is_private_label)] + #[label("private field")] Other { #[primary_span] span: Span, @@ -35,17 +49,17 @@ pub(crate) enum FieldIsPrivateLabel { } #[derive(Diagnostic)] -#[diag(privacy_item_is_private)] +#[diag("{$kind} `{$descr}` is private")] pub(crate) struct ItemIsPrivate<'a> { #[primary_span] - #[label] + #[label("private {$kind}")] pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, } #[derive(Diagnostic)] -#[diag(privacy_unnamed_item_is_private)] +#[diag("{$kind} is private")] pub(crate) struct UnnamedItemIsPrivate { #[primary_span] pub span: Span, @@ -53,20 +67,20 @@ pub(crate) struct UnnamedItemIsPrivate { } #[derive(Diagnostic)] -#[diag(privacy_in_public_interface, code = E0446)] +#[diag("{$vis_descr} {$kind} `{$descr}` in public interface", code = E0446)] pub(crate) struct InPublicInterface<'a> { #[primary_span] - #[label] + #[label("can't leak {$vis_descr} {$kind}")] pub span: Span, pub vis_descr: &'static str, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, - #[label(privacy_visibility_label)] + #[label("`{$descr}` declared as {$vis_descr}")] pub vis_span: Span, } #[derive(Diagnostic)] -#[diag(privacy_report_effective_visibility)] +#[diag("{$descr}")] pub(crate) struct ReportEffectiveVisibility { #[primary_span] pub span: Span, @@ -74,7 +88,7 @@ pub(crate) struct ReportEffectiveVisibility { } #[derive(LintDiagnostic)] -#[diag(privacy_from_private_dep_in_public_interface)] +#[diag("{$kind} `{$descr}` from private dependency '{$krate}' in public interface")] pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, @@ -82,9 +96,11 @@ pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[diag(privacy_unnameable_types_lint)] +#[diag("{$kind} `{$descr}` is reachable but cannot be named")] pub(crate) struct UnnameableTypesLint<'a> { - #[label] + #[label( + "reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}`" + )] pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, @@ -96,14 +112,14 @@ pub(crate) struct UnnameableTypesLint<'a> { // They will replace private-in-public errors and compatibility lints in future. // See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details. #[derive(LintDiagnostic)] -#[diag(privacy_private_interface_or_bounds_lint)] +#[diag("{$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`")] pub(crate) struct PrivateInterfacesOrBoundsLint<'a> { - #[label(privacy_item_label)] + #[label("{$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`")] pub item_span: Span, pub item_kind: &'a str, pub item_descr: DiagArgFromDisplay<'a>, pub item_vis_descr: &'a str, - #[note(privacy_ty_note)] + #[note("but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}`")] pub ty_span: Span, pub ty_kind: &'a str, pub ty_descr: DiagArgFromDisplay<'a>, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3336775210233..4a88ea0cc4450 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -39,8 +39,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::{Ident, Span, Symbol, sym}; use tracing::debug; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - //////////////////////////////////////////////////////////////////////////////// // Generic infrastructure used to implement specific visitors below. //////////////////////////////////////////////////////////////////////////////// From 0f9b0d38410c1d17e6c8f3186595110a79702eb6 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 3 Feb 2026 21:50:59 +0100 Subject: [PATCH 14/14] Convert to inline diagnostics in `rustc_session` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_interface/src/interface.rs | 4 +- compiler/rustc_session/Cargo.toml | 1 - compiler/rustc_session/messages.ftl | 149 ----------------- compiler/rustc_session/src/errors.rs | 187 ++++++++++++---------- compiler/rustc_session/src/lib.rs | 2 - 7 files changed, 106 insertions(+), 239 deletions(-) delete mode 100644 compiler/rustc_session/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 1631d5362612e..49563a61d2dc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4641,7 +4641,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_fs_util", "rustc_hashes", "rustc_hir", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3059a4fefc613..268040d3cb7d3 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -135,7 +135,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, rustc_privacy::DEFAULT_LOCALE_RESOURCE, rustc_resolve::DEFAULT_LOCALE_RESOURCE, - rustc_session::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 916618cb50496..bb22bd20ac2ac 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -55,7 +55,7 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec) -> Cfg { cfgs.into_iter() .map(|s| { let psess = ParseSess::emitter_with_note( - vec![rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_session::DEFAULT_LOCALE_RESOURCE], + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], format!("this occurred on the command line: `--cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); @@ -127,7 +127,7 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch for s in specs { let psess = ParseSess::emitter_with_note( - vec![rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_session::DEFAULT_LOCALE_RESOURCE], + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], format!("this occurred on the command line: `--check-cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index aebac3880d2fd..d66e04f581069 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -12,7 +12,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl deleted file mode 100644 index 5c851cb90a667..0000000000000 --- a/compiler/rustc_session/messages.ftl +++ /dev/null @@ -1,149 +0,0 @@ -session_apple_deployment_target_invalid = - failed to parse deployment target specified in {$env_var}: {$error} - -session_apple_deployment_target_too_low = - deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min} - -session_binary_float_literal_not_supported = binary float literal is not supported -session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64 - -session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static` - -session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}` - -session_cli_feature_diagnostic_help = - add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable - -session_crate_name_empty = crate name must not be empty - -session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version} - -session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled - -session_expr_parentheses_needed = parentheses are required to parse this as an expression - -session_failed_to_create_profiler = failed to create profiler: {$err} - -session_feature_diagnostic_for_issue = - see issue #{$n} for more information - -session_feature_diagnostic_help = - add `#![feature({$feature})]` to the crate attributes to enable - -session_feature_diagnostic_suggestion = - add `#![feature({$feature})]` to the crate attributes to enable - -session_feature_suggest_upgrade_compiler = - this compiler was built on {$date}; consider upgrading it if it is out of date - -session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions - -session_file_write_fail = failed to write `{$path}` due to error `{$err}` - -session_function_return_requires_x86_or_x86_64 = `-Zfunction-return` (except `keep`) is only supported on x86 and x86_64 - -session_function_return_thunk_extern_requires_non_large_code_model = `-Zfunction-return=thunk-extern` is only supported on non-large code models - -session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported - -session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target - .note = compatible flavors are: {$compatible_list} - -session_indirect_branch_cs_prefix_requires_x86_or_x86_64 = `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64 - -session_instrumentation_not_supported = {$us} instrumentation is not supported for this target - -session_int_literal_too_large = integer literal is too large - .note = value exceeds limit of `{$limit}` - -session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}` - -session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -session_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - -session_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - -session_invalid_literal_suffix = suffixes on {$kind} literals are invalid - .label = invalid suffix `{$suffix}` - -session_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -session_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - -session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets - -session_must_be_name_of_associated_function = must be a name of an associated function - -session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine - -session_not_supported = not supported - -session_octal_float_literal_not_supported = octal float literal is not supported - -session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist - -session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist - -session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi` - -session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` - -session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` - -session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto` - -session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1` - -session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi` - -session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort` - -session_sanitizer_not_supported = {$us} sanitizer is not supported for this target - -session_sanitizers_not_supported = {$us} sanitizers are not supported for this target - -session_skipping_const_checks = skipping const checks - -session_soft_float_deprecated = - `-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead - .note = it will be removed or ignored in a future version of Rust -session_soft_float_deprecated_issue = see issue #129893 for more information - -session_soft_float_ignored = - `-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets - .note = this may become a hard error in a future version of Rust - -session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform - -session_split_lto_unit_requires_lto = `-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` - -session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no` - -session_target_small_data_threshold_not_supported = `-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored - -session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored - -session_unexpected_builtin_cfg = unexpected `--cfg {$cfg}` flag - .controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}` - .incoherent = manually setting a built-in cfg can and does create incoherent behaviors - -session_unleashed_feature_help_named = skipping check for `{$gate}` feature -session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate - -session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto` - -session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is not supported -session_unsupported_dwarf_version_help = supported DWARF versions are 2, 3, 4 and 5 - -session_unsupported_reg_struct_return_arch = `-Zreg-struct-return` is only supported on x86 -session_unsupported_regparm = `-Zregparm={$regparm}` is unsupported (valid values 0-3) -session_unsupported_regparm_arch = `-Zregparm=N` is only supported on x86 diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 54e792fd7b59d..0c6a33f228082 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -15,9 +15,11 @@ use crate::parse::ParseSess; #[derive(Diagnostic)] pub(crate) enum AppleDeploymentTarget { - #[diag(session_apple_deployment_target_invalid)] + #[diag("failed to parse deployment target specified in {$env_var}: {$error}")] Invalid { env_var: &'static str, error: ParseIntError }, - #[diag(session_apple_deployment_target_too_low)] + #[diag( + "deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}" + )] TooLow { env_var: &'static str, version: String, os_min: String }, } @@ -34,13 +36,13 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for FeatureGateError { } #[derive(Subdiagnostic)] -#[note(session_feature_diagnostic_for_issue)] +#[note("see issue #{$n} for more information")] pub(crate) struct FeatureDiagnosticForIssue { pub(crate) n: NonZero, } #[derive(Subdiagnostic)] -#[note(session_feature_suggest_upgrade_compiler)] +#[note("this compiler was built on {$date}; consider upgrading it if it is out of date")] pub(crate) struct SuggestUpgradeCompiler { date: &'static str, } @@ -58,14 +60,14 @@ impl SuggestUpgradeCompiler { } #[derive(Subdiagnostic)] -#[help(session_feature_diagnostic_help)] +#[help("add `#![feature({$feature})]` to the crate attributes to enable")] pub(crate) struct FeatureDiagnosticHelp { pub(crate) feature: Symbol, } #[derive(Subdiagnostic)] #[suggestion( - session_feature_diagnostic_suggestion, + "add `#![feature({$feature})]` to the crate attributes to enable", applicability = "maybe-incorrect", code = "#![feature({feature})]\n" )] @@ -76,169 +78,181 @@ pub struct FeatureDiagnosticSuggestion { } #[derive(Subdiagnostic)] -#[help(session_cli_feature_diagnostic_help)] +#[help("add `-Zcrate-attr=\"feature({$feature})\"` to the command-line options to enable")] pub(crate) struct CliFeatureDiagnosticHelp { pub(crate) feature: Symbol, } #[derive(Diagnostic)] -#[diag(session_must_be_name_of_associated_function)] +#[diag("must be a name of an associated function")] pub struct MustBeNameOfAssociatedFunction { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(session_not_circumvent_feature)] +#[diag( + "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine" +)] pub(crate) struct NotCircumventFeature; #[derive(Diagnostic)] -#[diag(session_linker_plugin_lto_windows_not_supported)] +#[diag( + "linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets" +)] pub(crate) struct LinkerPluginToWindowsNotSupported; #[derive(Diagnostic)] -#[diag(session_profile_use_file_does_not_exist)] +#[diag("file `{$path}` passed to `-C profile-use` does not exist")] pub(crate) struct ProfileUseFileDoesNotExist<'a> { pub(crate) path: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_profile_sample_use_file_does_not_exist)] +#[diag("file `{$path}` passed to `-C profile-sample-use` does not exist")] pub(crate) struct ProfileSampleUseFileDoesNotExist<'a> { pub(crate) path: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_target_requires_unwind_tables)] +#[diag("target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`")] pub(crate) struct TargetRequiresUnwindTables; #[derive(Diagnostic)] -#[diag(session_instrumentation_not_supported)] +#[diag("{$us} instrumentation is not supported for this target")] pub(crate) struct InstrumentationNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_sanitizer_not_supported)] +#[diag("{$us} sanitizer is not supported for this target")] pub(crate) struct SanitizerNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_sanitizers_not_supported)] +#[diag("{$us} sanitizers are not supported for this target")] pub(crate) struct SanitizersNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_cannot_mix_and_match_sanitizers)] +#[diag("`-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`")] pub(crate) struct CannotMixAndMatchSanitizers { pub(crate) first: String, pub(crate) second: String, } #[derive(Diagnostic)] -#[diag(session_cannot_enable_crt_static_linux)] +#[diag( + "sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`" +)] pub(crate) struct CannotEnableCrtStaticLinux; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_requires_lto)] +#[diag("`-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`")] pub(crate) struct SanitizerCfiRequiresLto; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_requires_single_codegen_unit)] +#[diag("`-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`")] pub(crate) struct SanitizerCfiRequiresSingleCodegenUnit; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] +#[diag("`-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`")] pub(crate) struct SanitizerCfiCanonicalJumpTablesRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)] +#[diag("`-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] +#[diag("`-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_kcfi_arity_requires_kcfi)] +#[diag("`-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerKcfiArityRequiresKcfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_kcfi_requires_panic_abort)] +#[diag("`-Z sanitizer=kcfi` requires `-C panic=abort`")] pub(crate) struct SanitizerKcfiRequiresPanicAbort; #[derive(Diagnostic)] -#[diag(session_split_lto_unit_requires_lto)] +#[diag("`-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`")] pub(crate) struct SplitLtoUnitRequiresLto; #[derive(Diagnostic)] -#[diag(session_unstable_virtual_function_elimination)] +#[diag("`-Zvirtual-function-elimination` requires `-Clto`")] pub(crate) struct UnstableVirtualFunctionElimination; #[derive(Diagnostic)] -#[diag(session_unsupported_dwarf_version)] -#[help(session_unsupported_dwarf_version_help)] +#[diag("requested DWARF version {$dwarf_version} is not supported")] +#[help("supported DWARF versions are 2, 3, 4 and 5")] pub(crate) struct UnsupportedDwarfVersion { pub(crate) dwarf_version: u32, } #[derive(Diagnostic)] -#[diag(session_embed_source_insufficient_dwarf_version)] +#[diag( + "`-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version}" +)] pub(crate) struct EmbedSourceInsufficientDwarfVersion { pub(crate) dwarf_version: u32, } #[derive(Diagnostic)] -#[diag(session_embed_source_requires_debug_info)] +#[diag("`-Zembed-source=y` requires debug information to be enabled")] pub(crate) struct EmbedSourceRequiresDebugInfo; #[derive(Diagnostic)] -#[diag(session_target_stack_protector_not_supported)] +#[diag( + "`-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored" +)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { pub(crate) stack_protector: StackProtector, pub(crate) target_triple: &'a TargetTuple, } #[derive(Diagnostic)] -#[diag(session_target_small_data_threshold_not_supported)] +#[diag( + "`-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored" +)] pub(crate) struct SmallDataThresholdNotSupportedForTarget<'a> { pub(crate) target_triple: &'a TargetTuple, } #[derive(Diagnostic)] -#[diag(session_branch_protection_requires_aarch64)] +#[diag("`-Zbranch-protection` is only supported on aarch64")] pub(crate) struct BranchProtectionRequiresAArch64; #[derive(Diagnostic)] -#[diag(session_split_debuginfo_unstable_platform)] +#[diag("`-Csplit-debuginfo={$debuginfo}` is unstable on this platform")] pub(crate) struct SplitDebugInfoUnstablePlatform { pub(crate) debuginfo: SplitDebuginfo, } #[derive(Diagnostic)] -#[diag(session_file_is_not_writeable)] +#[diag("output file {$file} is not writeable -- check its permissions")] pub(crate) struct FileIsNotWriteable<'a> { pub(crate) file: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_file_write_fail)] +#[diag("failed to write `{$path}` due to error `{$err}`")] pub(crate) struct FileWriteFail<'a> { pub(crate) path: &'a std::path::Path, pub(crate) err: String, } #[derive(Diagnostic)] -#[diag(session_crate_name_empty)] +#[diag("crate name must not be empty")] pub(crate) struct CrateNameEmpty { #[primary_span] pub(crate) span: Option, } #[derive(Diagnostic)] -#[diag(session_invalid_character_in_crate_name)] +#[diag("invalid character {$character} in crate name: `{$crate_name}`")] pub(crate) struct InvalidCharacterInCrateName { #[primary_span] pub(crate) span: Option, @@ -247,7 +261,10 @@ pub(crate) struct InvalidCharacterInCrateName { } #[derive(Subdiagnostic)] -#[multipart_suggestion(session_expr_parentheses_needed, applicability = "machine-applicable")] +#[multipart_suggestion( + "parentheses are required to parse this as an expression", + applicability = "machine-applicable" +)] pub struct ExprParenthesesNeeded { #[suggestion_part(code = "(")] left: Span, @@ -262,7 +279,7 @@ impl ExprParenthesesNeeded { } #[derive(Diagnostic)] -#[diag(session_skipping_const_checks)] +#[diag("skipping const checks")] pub(crate) struct SkippingConstChecks { #[subdiagnostic] pub(crate) unleashed_features: Vec, @@ -270,13 +287,13 @@ pub(crate) struct SkippingConstChecks { #[derive(Subdiagnostic)] pub(crate) enum UnleashedFeatureHelp { - #[help(session_unleashed_feature_help_named)] + #[help("skipping check for `{$gate}` feature")] Named { #[primary_span] span: Span, gate: Symbol, }, - #[help(session_unleashed_feature_help_unnamed)] + #[help("skipping check that does not even have a feature gate")] Unnamed { #[primary_span] span: Span, @@ -284,10 +301,10 @@ pub(crate) enum UnleashedFeatureHelp { } #[derive(Diagnostic)] -#[diag(session_invalid_literal_suffix)] +#[diag("suffixes on {$kind} literals are invalid")] struct InvalidLiteralSuffix<'a> { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, // FIXME(#100717) kind: &'a str, @@ -295,8 +312,8 @@ struct InvalidLiteralSuffix<'a> { } #[derive(Diagnostic)] -#[diag(session_invalid_int_literal_width)] -#[help] +#[diag("invalid width `{$width}` for integer literal")] +#[help("valid widths are 8, 16, 32, 64 and 128")] struct InvalidIntLiteralWidth { #[primary_span] span: Span, @@ -304,28 +321,32 @@ struct InvalidIntLiteralWidth { } #[derive(Diagnostic)] -#[diag(session_invalid_num_literal_base_prefix)] -#[note] +#[diag("invalid base prefix for number literal")] +#[note("base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase")] struct InvalidNumLiteralBasePrefix { #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")] + #[suggestion( + "try making the prefix lowercase", + applicability = "maybe-incorrect", + code = "{fixed}" + )] span: Span, fixed: String, } #[derive(Diagnostic)] -#[diag(session_invalid_num_literal_suffix)] -#[help] +#[diag("invalid suffix `{$suffix}` for number literal")] +#[help("the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)")] struct InvalidNumLiteralSuffix { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, suffix: String, } #[derive(Diagnostic)] -#[diag(session_invalid_float_literal_width)] -#[help] +#[diag("invalid width `{$width}` for float literal")] +#[help("valid widths are 32 and 64")] struct InvalidFloatLiteralWidth { #[primary_span] span: Span, @@ -333,18 +354,18 @@ struct InvalidFloatLiteralWidth { } #[derive(Diagnostic)] -#[diag(session_invalid_float_literal_suffix)] -#[help] +#[diag("invalid suffix `{$suffix}` for float literal")] +#[help("valid suffixes are `f32` and `f64`")] struct InvalidFloatLiteralSuffix { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, suffix: String, } #[derive(Diagnostic)] -#[diag(session_int_literal_too_large)] -#[note] +#[diag("integer literal is too large")] +#[note("value exceeds limit of `{$limit}`")] struct IntLiteralTooLarge { #[primary_span] span: Span, @@ -352,26 +373,26 @@ struct IntLiteralTooLarge { } #[derive(Diagnostic)] -#[diag(session_hexadecimal_float_literal_not_supported)] +#[diag("hexadecimal float literal is not supported")] struct HexadecimalFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } #[derive(Diagnostic)] -#[diag(session_octal_float_literal_not_supported)] +#[diag("octal float literal is not supported")] struct OctalFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } #[derive(Diagnostic)] -#[diag(session_binary_float_literal_not_supported)] +#[diag("binary float literal is not supported")] struct BinaryFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } @@ -457,60 +478,60 @@ pub fn create_lit_error(psess: &ParseSess, err: LitError, lit: token::Lit, span: } #[derive(Diagnostic)] -#[diag(session_incompatible_linker_flavor)] -#[note] +#[diag("linker flavor `{$flavor}` is incompatible with the current target")] +#[note("compatible flavors are: {$compatible_list}")] pub(crate) struct IncompatibleLinkerFlavor { pub(crate) flavor: &'static str, pub(crate) compatible_list: String, } #[derive(Diagnostic)] -#[diag(session_function_return_requires_x86_or_x86_64)] +#[diag("`-Zfunction-return` (except `keep`) is only supported on x86 and x86_64")] pub(crate) struct FunctionReturnRequiresX86OrX8664; #[derive(Diagnostic)] -#[diag(session_function_return_thunk_extern_requires_non_large_code_model)] +#[diag("`-Zfunction-return=thunk-extern` is only supported on non-large code models")] pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel; #[derive(Diagnostic)] -#[diag(session_indirect_branch_cs_prefix_requires_x86_or_x86_64)] +#[diag("`-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64")] pub(crate) struct IndirectBranchCsPrefixRequiresX86OrX8664; #[derive(Diagnostic)] -#[diag(session_unsupported_regparm)] +#[diag("`-Zregparm={$regparm}` is unsupported (valid values 0-3)")] pub(crate) struct UnsupportedRegparm { pub(crate) regparm: u32, } #[derive(Diagnostic)] -#[diag(session_unsupported_regparm_arch)] +#[diag("`-Zregparm=N` is only supported on x86")] pub(crate) struct UnsupportedRegparmArch; #[derive(Diagnostic)] -#[diag(session_unsupported_reg_struct_return_arch)] +#[diag("`-Zreg-struct-return` is only supported on x86")] pub(crate) struct UnsupportedRegStructReturnArch; #[derive(Diagnostic)] -#[diag(session_failed_to_create_profiler)] +#[diag("failed to create profiler: {$err}")] pub(crate) struct FailedToCreateProfiler { pub(crate) err: String, } #[derive(Diagnostic)] -#[diag(session_soft_float_ignored)] -#[note] +#[diag("`-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets")] +#[note("this may become a hard error in a future version of Rust")] pub(crate) struct SoftFloatIgnored; #[derive(Diagnostic)] -#[diag(session_soft_float_deprecated)] -#[note] -#[note(session_soft_float_deprecated_issue)] +#[diag("`-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead")] +#[note("it will be removed or ignored in a future version of Rust")] +#[note("see issue #129893 for more information")] pub(crate) struct SoftFloatDeprecated; #[derive(LintDiagnostic)] -#[diag(session_unexpected_builtin_cfg)] -#[note(session_controlled_by)] -#[note(session_incoherent)] +#[diag("unexpected `--cfg {$cfg}` flag")] +#[note("config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`")] +#[note("manually setting a built-in cfg can and does create incoherent behaviors")] pub(crate) struct UnexpectedBuiltinCfg { pub(crate) cfg: String, pub(crate) cfg_name: Symbol, diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 90108e9110440..98731a235d41d 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -32,8 +32,6 @@ pub mod output; pub use getopts; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`.