From 5c85d522d0083bee0d5fd7f26868fa0e62372485 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 13 Jan 2026 09:52:36 -0800 Subject: [PATCH 1/5] Generate global openmp metadata to trigger llvm openmp-opt pass --- compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs | 4 ++++ tests/codegen-llvm/gpu_offload/gpu_host.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index b8eb4f038216..084d40317ba8 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -55,6 +55,10 @@ impl<'ll> OffloadGlobals<'ll> { let init_ty = cx.type_func(&[], cx.type_void()); let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + // We want LLVM's openmp-opt pass to pick up and optimize this module, since it covers both + // openmp and offload optimizations. + llvm::add_module_flag_u32(cx.llmod(), llvm::ModuleFlagMergeBehavior::Max, "openmp", 51); + OffloadGlobals { launcher_fn, launcher_ty, diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index dcbd65b14427..27ff6f325aa0 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -104,3 +104,5 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-NEXT: call void @__tgt_unregister_lib(ptr nonnull %EmptyDesc) // CHECK-NEXT: ret void // CHECK-NEXT: } + +// CHECK: !{i32 7, !"openmp", i32 51} From 7216b035fa406b924099d1b1e8c4f392e4e02597 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 21:27:40 +0100 Subject: [PATCH 2/5] Factor out diagnostic slug checking from `DiagnosticDerive` and `LintDiagnosticDerive` --- .../src/diagnostics/diagnostic.rs | 100 +++--------------- .../src/diagnostics/diagnostic_builder.rs | 49 +++++++++ 2 files changed, 66 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 185d07049669..7e784e3464e9 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -4,12 +4,10 @@ use std::cell::RefCell; use proc_macro2::TokenStream; use quote::quote; -use syn::spanned::Spanned; use synstructure::Structure; use crate::diagnostics::diagnostic_builder::DiagnosticDeriveKind; -use crate::diagnostics::error::{DiagnosticDeriveError, span_err}; -use crate::diagnostics::utils::SetOnce; +use crate::diagnostics::error::DiagnosticDeriveError; /// The central struct for constructing the `into_diag` method from an annotated struct. pub(crate) struct DiagnosticDerive<'a> { @@ -29,36 +27,16 @@ impl<'a> DiagnosticDerive<'a> { let preamble = builder.preamble(variant); let body = builder.body(variant); - let init = match builder.slug.value_ref() { - None => { - span_err(builder.span, "diagnostic slug not specified") - .help( - "specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(hir_analysis_example_error)]`", - ) - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - Some(slug) - if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = - Mismatch::check(slug) => - { - span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) - .help(format!("expected a slug starting with `{slug_prefix}_...`")) - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - Some(slug) => { - slugs.borrow_mut().push(slug.clone()); - quote! { - let mut diag = rustc_errors::Diag::new( - dcx, - level, - crate::fluent_generated::#slug - ); - } - } + let Some(slug) = builder.primary_message() else { + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + }; + slugs.borrow_mut().push(slug.clone()); + let init = quote! { + let mut diag = rustc_errors::Diag::new( + dcx, + level, + crate::fluent_generated::#slug + ); }; let formatting_init = &builder.formatting_init; @@ -113,32 +91,12 @@ impl<'a> LintDiagnosticDerive<'a> { let preamble = builder.preamble(variant); let body = builder.body(variant); - let primary_message = match builder.slug.value_ref() { - None => { - span_err(builder.span, "diagnostic slug not specified") - .help( - "specify the slug as the first argument to the attribute, such as \ - `#[diag(compiletest_example)]`", - ) - .emit(); - DiagnosticDeriveError::ErrorHandled.to_compile_error() - } - Some(slug) - if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = - Mismatch::check(slug) => - { - span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) - .help(format!("expected a slug starting with `{slug_prefix}_...`")) - .emit(); - DiagnosticDeriveError::ErrorHandled.to_compile_error() - } - Some(slug) => { - slugs.borrow_mut().push(slug.clone()); - quote! { - diag.primary_message(crate::fluent_generated::#slug); - } - } + let Some(slug) = builder.primary_message() else { + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + }; + slugs.borrow_mut().push(slug.clone()); + let primary_message = quote! { + diag.primary_message(crate::fluent_generated::#slug); }; let formatting_init = &builder.formatting_init; @@ -172,30 +130,6 @@ impl<'a> LintDiagnosticDerive<'a> { } } -struct Mismatch { - slug_name: String, - crate_name: String, - slug_prefix: String, -} - -impl Mismatch { - /// Checks whether the slug starts with the crate name it's in. - fn check(slug: &syn::Path) -> Option { - // If this is missing we're probably in a test, so bail. - let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; - - // If we're not in a "rustc_" crate, bail. - let Some(("rustc", slug_prefix)) = crate_name.split_once('_') else { return None }; - - let slug_name = slug.segments.first()?.ident.to_string(); - if !slug_name.starts_with(slug_prefix) { - Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) - } else { - None - } - } -} - /// Generates a `#[test]` that verifies that all referenced variables /// exist on this structure. fn generate_test(slug: &syn::Path, structure: &Structure<'_>) -> TokenStream { diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 1055f27c1e48..cbc70b55d7ee 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -110,6 +110,31 @@ impl DiagnosticDeriveKind { } impl DiagnosticDeriveVariantBuilder { + pub(crate) fn primary_message(&self) -> Option<&Path> { + match self.slug.value_ref() { + None => { + span_err(self.span, "diagnostic slug not specified") + .help( + "specify the slug as the first argument to the `#[diag(...)]` \ + attribute, such as `#[diag(hir_analysis_example_error)]`", + ) + .emit(); + None + } + Some(slug) + if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = + Mismatch::check(slug) => + { + span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") + .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) + .help(format!("expected a slug starting with `{slug_prefix}_...`")) + .emit(); + None + } + Some(slug) => Some(slug), + } + } + /// Generates calls to `code` and similar functions based on the attributes on the type or /// variant. pub(crate) fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream { @@ -504,3 +529,27 @@ impl DiagnosticDeriveVariantBuilder { } } } + +struct Mismatch { + slug_name: String, + crate_name: String, + slug_prefix: String, +} + +impl Mismatch { + /// Checks whether the slug starts with the crate name it's in. + fn check(slug: &syn::Path) -> Option { + // If this is missing we're probably in a test, so bail. + let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; + + // If we're not in a "rustc_" crate, bail. + let Some(("rustc", slug_prefix)) = crate_name.split_once('_') else { return None }; + + let slug_name = slug.segments.first()?.ident.to_string(); + if slug_name.starts_with(slug_prefix) { + return None; + } + + Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) + } +} From 7ec4a8e798cc37bdf4c9cac1c4a481f6c1d22a0d Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 22:36:39 +0100 Subject: [PATCH 3/5] Update uitests --- tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 90ad21ef08f9..77c48aceca8e 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -384,7 +384,7 @@ error: derive(Diagnostic): diagnostic slug not specified LL | #[lint(no_crate_example, code = E0123)] | ^ | - = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): attribute specified multiple times --> $DIR/diagnostic-derive.rs:613:53 From 3a8b57715f1e762fbb78edc89c767446b7fdc0ea Mon Sep 17 00:00:00 2001 From: KaiTomotake Date: Sun, 18 Jan 2026 22:43:35 +0900 Subject: [PATCH 4/5] add lint test Co-authored-by: Redddy --- .../unused_assignments_across_match_guards.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/ui/lint/unused/unused_assignments_across_match_guards.rs diff --git a/tests/ui/lint/unused/unused_assignments_across_match_guards.rs b/tests/ui/lint/unused/unused_assignments_across_match_guards.rs new file mode 100644 index 000000000000..666a529b8f85 --- /dev/null +++ b/tests/ui/lint/unused/unused_assignments_across_match_guards.rs @@ -0,0 +1,19 @@ +// Regression test for +// This test ensures that unused_assignments does not report assignments used in a match. +//@ check-pass + +fn pnk(x: usize) -> &'static str { + let mut k1 = "k1"; + let mut h1 = "h1"; + match x & 3 { + 3 if { k1 = "unused?"; false } => (), + _ if { h1 = k1; true } => (), + _ => (), + } + h1 +} + +#[deny(unused_assignments)] +fn main() { + pnk(3); +} From 0895c4cbe6ff960b23626a538d1691d2ebf51311 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Mon, 19 Jan 2026 04:48:23 +0000 Subject: [PATCH 5/5] ci: Move lockfile updates to a script --- .github/workflows/dependencies.yml | 16 +++------------- src/tools/update-lockfile.sh | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) create mode 100755 src/tools/update-lockfile.sh diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 80ffd67e04e1..7c721c7abeaa 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -62,19 +62,9 @@ jobs: rustup toolchain install --no-self-update --profile minimal $TOOLCHAIN rustup default $TOOLCHAIN - - name: cargo update compiler & tools - # Remove first line that always just says "Updating crates.io index" - run: | - echo -e "\ncompiler & tools dependencies:" >> cargo_update.log - cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - - name: cargo update library - run: | - echo -e "\nlibrary dependencies:" >> cargo_update.log - cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - - name: cargo update rustbook - run: | - echo -e "\nrustbook dependencies:" >> cargo_update.log - cargo update --manifest-path src/tools/rustbook/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log + - name: cargo update + run: ./src/tools/update-lockfile.sh + - name: upload Cargo.lock artifact for use in PR uses: actions/upload-artifact@v4 with: diff --git a/src/tools/update-lockfile.sh b/src/tools/update-lockfile.sh new file mode 100755 index 000000000000..a968d83d8152 --- /dev/null +++ b/src/tools/update-lockfile.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Updates the workspaces in `.`, `library` and `src/tools/rustbook` +# Logs are written to `cargo_update.log` +# Used as part of regular dependency bumps + +set -euo pipefail + +echo -e "\ncompiler & tools dependencies:" > cargo_update.log +# Remove first line that always just says "Updating crates.io index" +cargo update 2>&1 | sed '/crates.io index/d' | \ + tee -a cargo_update.log +echo -e "\nlibrary dependencies:" >> cargo_update.log +cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | \ + tee -a cargo_update.log +echo -e "\nrustbook dependencies:" >> cargo_update.log +cargo update --manifest-path src/tools/rustbook/Cargo.toml 2>&1 | sed '/crates.io index/d' | \ + tee -a cargo_update.log