From 5e5eb34bda25fd687a95b86addc829b4f0be5a99 Mon Sep 17 00:00:00 2001 From: "Kevin K." Date: Sun, 20 Sep 2026 15:31:39 +0200 Subject: [PATCH 1/6] wip: fix offload_kernel error message --- .../rustc_builtin_macros/src/diagnostics.rs | 7 +++ compiler/rustc_builtin_macros/src/offload.rs | 2 +- tests/ui/offload/offload_kernel_illegal.rs | 21 +++++++++ .../ui/offload/offload_kernel_illegal.stderr | 47 +++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/ui/offload/offload_kernel_illegal.rs create mode 100644 tests/ui/offload/offload_kernel_illegal.stderr diff --git a/compiler/rustc_builtin_macros/src/diagnostics.rs b/compiler/rustc_builtin_macros/src/diagnostics.rs index 62f0063a7fbd3..f11321b0973ed 100644 --- a/compiler/rustc_builtin_macros/src/diagnostics.rs +++ b/compiler/rustc_builtin_macros/src/diagnostics.rs @@ -233,6 +233,13 @@ mod autodiff { } } +#[derive(Diagnostic)] +#[diag("offload_kernel must be applied to function")] +pub(crate) struct OffloadKernelInvalidApplication { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag("cannot concatenate {$lit_kind} literals")] pub(crate) struct ConcatBytesInvalid { diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 53bf0f4ca6b86..f50ea01a5076c 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -68,7 +68,7 @@ pub(crate) fn expand_kernel( let dcx = ecx.sess.dcx(); let Some((vis, sig, ident, generics, body)) = extract_fn(&item) else { - dcx.emit_err(diagnostics::AutoDiffInvalidApplication { span: item.span() }); + dcx.emit_err(diagnostics::OffloadKernelInvalidApplication { span: item.span() }); return vec![item]; }; diff --git a/tests/ui/offload/offload_kernel_illegal.rs b/tests/ui/offload/offload_kernel_illegal.rs new file mode 100644 index 0000000000000..027ef31b4cae7 --- /dev/null +++ b/tests/ui/offload/offload_kernel_illegal.rs @@ -0,0 +1,21 @@ +#![feature(gpu_offload)] + +fn dummy() { + #[core::offload::offload_kernel] + //~^ ERROR macro attributes on statements are unstable + let mut x = 5; + //~^ ERROR offload_kernel must be applied to function + + #[core::offload::offload_kernel] + x = x + 3; + //~^^ ERROR attributes on expressions are experimental [E0658] + //~| ERROR macro attributes on expressions are unstable + //~^^^ ERROR offload_kernel must be applied to function + + #[core::offload::offload_kernel] + //~^ ERROR macro attributes on statements are unstable + let add_one_v2 = |x: u32| -> u32 { x + 1 }; + //~^ ERROR offload_kernel must be applied to function +} + +fn main() {} \ No newline at end of file diff --git a/tests/ui/offload/offload_kernel_illegal.stderr b/tests/ui/offload/offload_kernel_illegal.stderr new file mode 100644 index 0000000000000..60ba957daccae --- /dev/null +++ b/tests/ui/offload/offload_kernel_illegal.stderr @@ -0,0 +1,47 @@ +error[E0658]: macro attributes on statements are unstable + --> $DIR/offload_kernel_illegal.rs:49:5 + | +LL | #[autodiff_forward(df7, Dual)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54727 for more information + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: autodiff must be applied to function + --> $DIR/offload_kernel_illegal.rs:51:5 + | +LL | let mut x = 5; + | ^^^^^^^^^^^^^^ + +error[E0658]: macro attributes on expressions are unstable + --> $DIR/offload_kernel_illegal.rs:54:5 + | +LL | #[autodiff_forward(df7, Dual)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54727 for more information + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: autodiff must be applied to function + --> $DIR/offload_kernel_illegal.rs:55:5 + | +LL | x = x + 3; + | ^ + +error[E0658]: macro attributes on statements are unstable + --> $DIR/offload_kernel_illegal.rs:60:5 + | +LL | #[autodiff_forward(df7, Dual)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54727 for more information + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: autodiff must be applied to function + --> $DIR/offload_kernel_illegal.rs:62:5 + | +LL | let add_one_v2 = |x: u32| -> u32 { x + 1 }; + | \ No newline at end of file From e16d9eec4feaf133b7df785396d74e3c6f1643dd Mon Sep 17 00:00:00 2001 From: xkevio Date: Sun, 20 Sep 2026 18:19:43 +0200 Subject: [PATCH 2/6] fix: stderr output for offload_kernel test --- tests/ui/offload/offload_kernel_illegal.rs | 2 +- .../ui/offload/offload_kernel_illegal.stderr | 46 ++++++++++++------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/tests/ui/offload/offload_kernel_illegal.rs b/tests/ui/offload/offload_kernel_illegal.rs index 027ef31b4cae7..ce3d14b9d906f 100644 --- a/tests/ui/offload/offload_kernel_illegal.rs +++ b/tests/ui/offload/offload_kernel_illegal.rs @@ -18,4 +18,4 @@ fn dummy() { //~^ ERROR offload_kernel must be applied to function } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/tests/ui/offload/offload_kernel_illegal.stderr b/tests/ui/offload/offload_kernel_illegal.stderr index 60ba957daccae..d41e01d54d17f 100644 --- a/tests/ui/offload/offload_kernel_illegal.stderr +++ b/tests/ui/offload/offload_kernel_illegal.stderr @@ -1,47 +1,61 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/offload_kernel_illegal.rs:9:5 + | +LL | #[core::offload::offload_kernel] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: macro attributes on statements are unstable - --> $DIR/offload_kernel_illegal.rs:49:5 + --> $DIR/offload_kernel_illegal.rs:4:5 | -LL | #[autodiff_forward(df7, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[core::offload::offload_kernel] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #54727 for more information = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: autodiff must be applied to function - --> $DIR/offload_kernel_illegal.rs:51:5 +error: offload_kernel must be applied to function + --> $DIR/offload_kernel_illegal.rs:6:5 | LL | let mut x = 5; | ^^^^^^^^^^^^^^ error[E0658]: macro attributes on expressions are unstable - --> $DIR/offload_kernel_illegal.rs:54:5 + --> $DIR/offload_kernel_illegal.rs:9:5 | -LL | #[autodiff_forward(df7, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[core::offload::offload_kernel] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #54727 for more information = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: autodiff must be applied to function - --> $DIR/offload_kernel_illegal.rs:55:5 +error: offload_kernel must be applied to function + --> $DIR/offload_kernel_illegal.rs:10:5 | LL | x = x + 3; | ^ error[E0658]: macro attributes on statements are unstable - --> $DIR/offload_kernel_illegal.rs:60:5 + --> $DIR/offload_kernel_illegal.rs:15:5 | -LL | #[autodiff_forward(df7, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[core::offload::offload_kernel] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #54727 for more information = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: autodiff must be applied to function - --> $DIR/offload_kernel_illegal.rs:62:5 +error: offload_kernel must be applied to function + --> $DIR/offload_kernel_illegal.rs:17:5 | LL | let add_one_v2 = |x: u32| -> u32 { x + 1 }; - | \ No newline at end of file + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0658`. From 6dd7e1e98448637d2871cada61824aec7b723b16 Mon Sep 17 00:00:00 2001 From: xkevio Date: Sun, 20 Sep 2026 18:52:22 +0200 Subject: [PATCH 3/6] feat: nested functions with offload_kernel --- compiler/rustc_builtin_macros/src/offload.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index f50ea01a5076c..43ad68c568f0a 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -28,6 +28,15 @@ fn extract_fn( } _ => None, }, + Annotatable::Stmt(stmt) => match &stmt.kind { + ast::StmtKind::Item(iitem) => match &iitem.kind { + ast::ItemKind::Fn(ast::Fn { sig, ident, generics, body, .. }) => { + Some((iitem.vis.clone(), sig.clone(), *ident, generics.clone(), body.clone())) + } + _ => None, + }, + _ => None, + }, _ => None, } } From 7e4dca65923bf9e1db7d67fe62ae676453abfbe9 Mon Sep 17 00:00:00 2001 From: xkevio Date: Sun, 20 Sep 2026 23:02:50 +0200 Subject: [PATCH 4/6] fix: correct annotation type when generating inner function --- compiler/rustc_builtin_macros/src/offload.rs | 27 ++++++++++++++------ tests/ui/offload/offload_kernel_nested.rs | 9 +++++++ 2 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 tests/ui/offload/offload_kernel_nested.rs diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 43ad68c568f0a..cf905c6911279 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -1,6 +1,7 @@ use rustc_ast::ast; use rustc_ast::token::{Delimiter, IdentKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree}; +use rustc_ast::{DUMMY_NODE_ID, ast}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_session::config::Offload; use rustc_span::{DUMMY_SP, Ident, Span, sym}; @@ -179,14 +180,24 @@ pub(crate) fn expand_kernel( let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); let inline_never = outer_normal_attr(&inline_never_attr, new_id, span); - let host_item = { - let mut item = ecx.item( - span, - thin_vec![rustc_offload_kernel, inline_never], - ast::ItemKind::Fn(host_fn), - ); - item.vis = vis; - Annotatable::Item(item) + let mut host_item_ecx = + ecx.item(span, thin_vec![rustc_offload_kernel, inline_never], ast::ItemKind::Fn(host_fn)); + let host_item = match &item { + Annotatable::Item(_) => { + host_item_ecx.vis = vis; + Annotatable::Item(host_item_ecx) + } + Annotatable::Stmt(_) => { + host_item_ecx.vis = vis; + Annotatable::Stmt(Box::new(ast::Stmt { + id: DUMMY_NODE_ID, + kind: ast::StmtKind::Item(host_item_ecx), + span, + })) + } + _ => { + unreachable!("item kind checked previously") + } }; if compile_for_device(ecx) { vec![device_item] } else { vec![host_item] } diff --git a/tests/ui/offload/offload_kernel_nested.rs b/tests/ui/offload/offload_kernel_nested.rs new file mode 100644 index 0000000000000..68f6e94679e6a --- /dev/null +++ b/tests/ui/offload/offload_kernel_nested.rs @@ -0,0 +1,9 @@ +//@ check-pass +#![feature(gpu_offload)] + +fn kernel() { + #[core::offload::offload_kernel] + fn inner_kernel() {} +} + +fn main() {} From a7ef099a0c288fedddf33b908151dae70ac50347 Mon Sep 17 00:00:00 2001 From: xkevio Date: Tue, 22 Sep 2026 23:09:25 +0200 Subject: [PATCH 5/6] chore: mv offload_kernel test to diff folder --- compiler/rustc_builtin_macros/src/offload.rs | 1 - tests/{ui => pretty}/offload/offload_kernel_nested.rs | 0 2 files changed, 1 deletion(-) rename tests/{ui => pretty}/offload/offload_kernel_nested.rs (100%) diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index cf905c6911279..98b555d549b58 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -1,4 +1,3 @@ -use rustc_ast::ast; use rustc_ast::token::{Delimiter, IdentKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{DUMMY_NODE_ID, ast}; diff --git a/tests/ui/offload/offload_kernel_nested.rs b/tests/pretty/offload/offload_kernel_nested.rs similarity index 100% rename from tests/ui/offload/offload_kernel_nested.rs rename to tests/pretty/offload/offload_kernel_nested.rs From e034af011185565116e72edc1687fe6913570592 Mon Sep 17 00:00:00 2001 From: xkevio Date: Wed, 23 Sep 2026 00:29:31 +0200 Subject: [PATCH 6/6] fix: nested function expansion for device item --- compiler/rustc_builtin_macros/src/offload.rs | 46 ++++++++++++------- .../offload/offload_kernel_nested.device.pp | 25 ++++++++++ .../offload/offload_kernel_nested.host.pp | 28 +++++++++++ tests/pretty/offload/offload_kernel_nested.rs | 15 +++++- 4 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 tests/pretty/offload/offload_kernel_nested.device.pp create mode 100644 tests/pretty/offload/offload_kernel_nested.host.pp diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 98b555d549b58..c6afd49d64c41 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -118,10 +118,21 @@ pub(crate) fn expand_kernel( ); let device_item = { - let mut item = + let mut device_item_ecx = ecx.item(span, thin_vec![rustc_offload_kernel.clone()], ast::ItemKind::Fn(device_fn)); - item.vis = vis.clone(); - Annotatable::Item(item) + device_item_ecx.vis = vis.clone(); + + match &item { + Annotatable::Item(_) => Annotatable::Item(device_item_ecx), + Annotatable::Stmt(_) => Annotatable::Stmt(Box::new(ast::Stmt { + id: DUMMY_NODE_ID, + kind: ast::StmtKind::Item(device_item_ecx), + span, + })), + _ => { + unreachable!("item kind checked previously") + } + } }; // unimplemented! body @@ -179,23 +190,24 @@ pub(crate) fn expand_kernel( let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); let inline_never = outer_normal_attr(&inline_never_attr, new_id, span); - let mut host_item_ecx = - ecx.item(span, thin_vec![rustc_offload_kernel, inline_never], ast::ItemKind::Fn(host_fn)); - let host_item = match &item { - Annotatable::Item(_) => { - host_item_ecx.vis = vis; - Annotatable::Item(host_item_ecx) - } - Annotatable::Stmt(_) => { - host_item_ecx.vis = vis; - Annotatable::Stmt(Box::new(ast::Stmt { + let host_item = { + let mut host_item_ecx = ecx.item( + span, + thin_vec![rustc_offload_kernel, inline_never], + ast::ItemKind::Fn(host_fn), + ); + host_item_ecx.vis = vis; + + match &item { + Annotatable::Item(_) => Annotatable::Item(host_item_ecx), + Annotatable::Stmt(_) => Annotatable::Stmt(Box::new(ast::Stmt { id: DUMMY_NODE_ID, kind: ast::StmtKind::Item(host_item_ecx), span, - })) - } - _ => { - unreachable!("item kind checked previously") + })), + _ => { + unreachable!("item kind checked previously") + } } }; diff --git a/tests/pretty/offload/offload_kernel_nested.device.pp b/tests/pretty/offload/offload_kernel_nested.device.pp new file mode 100644 index 0000000000000..78ae27d5617b7 --- /dev/null +++ b/tests/pretty/offload/offload_kernel_nested.device.pp @@ -0,0 +1,25 @@ +#![feature(prelude_import)] +#![no_std] +//@ only-nightly +//@ revisions: host device + +//@ pretty-mode:expanded +//@ pretty-compare-only +//@[host] pp-exact:offload_kernel_nested.host.pp +//@[device] pp-exact:offload_kernel_nested.device.pp + +//@[device] compile-flags: -Zunstable-options -Zoffload=Device + +#![feature(gpu_offload)] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +use std::offload::offload_kernel; + +fn kernel() { + #[rustc_offload_kernel] + unsafe extern "gpu-kernel" fn inner_kernel() {} +} + +fn main() {} diff --git a/tests/pretty/offload/offload_kernel_nested.host.pp b/tests/pretty/offload/offload_kernel_nested.host.pp new file mode 100644 index 0000000000000..e6e2658a6e5be --- /dev/null +++ b/tests/pretty/offload/offload_kernel_nested.host.pp @@ -0,0 +1,28 @@ +#![feature(prelude_import)] +#![no_std] +//@ only-nightly +//@ revisions: host device + +//@ pretty-mode:expanded +//@ pretty-compare-only +//@[host] pp-exact:offload_kernel_nested.host.pp +//@[device] pp-exact:offload_kernel_nested.device.pp + +//@[device] compile-flags: -Zunstable-options -Zoffload=Device + +#![feature(gpu_offload)] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +use std::offload::offload_kernel; + +fn kernel() { + #[rustc_offload_kernel] + #[inline(never)] + fn inner_kernel() { + + ::core::panicking::panic("not implemented") + } +} +fn main() {} diff --git a/tests/pretty/offload/offload_kernel_nested.rs b/tests/pretty/offload/offload_kernel_nested.rs index 68f6e94679e6a..d50a90b34104a 100644 --- a/tests/pretty/offload/offload_kernel_nested.rs +++ b/tests/pretty/offload/offload_kernel_nested.rs @@ -1,8 +1,19 @@ -//@ check-pass +//@ only-nightly +//@ revisions: host device + +//@ pretty-mode:expanded +//@ pretty-compare-only +//@[host] pp-exact:offload_kernel_nested.host.pp +//@[device] pp-exact:offload_kernel_nested.device.pp + +//@[device] compile-flags: -Zunstable-options -Zoffload=Device + #![feature(gpu_offload)] +use std::offload::offload_kernel; + fn kernel() { - #[core::offload::offload_kernel] + #[offload_kernel] fn inner_kernel() {} }