From bc2853f4c1d2d39efca5898fbe188f25ec778ece Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 27 Dec 2025 14:34:20 -0500 Subject: [PATCH 01/10] do not suggest method call removal if it changes receiver type --- .../src/error_reporting/traits/suggestions.rs | 28 +++++++++++++------ .../argument-with-unnecessary-method-call.rs | 8 ++++++ ...gument-with-unnecessary-method-call.stderr | 16 +++++++++-- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index d14ff2c3b7e2a..c5b014293f98d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4069,15 +4069,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) && expr.span.hi() != rcvr.span.hi() { - err.span_suggestion_verbose( - expr.span.with_lo(rcvr.span.hi()), - format!( - "consider removing this method call, as the receiver has type `{ty}` and \ - `{pred}` trivially holds", - ), - "", - Applicability::MaybeIncorrect, - ); + match tcx.hir_node(call_hir_id) { + // Do not suggest removing a method call if the argument is the receiver of the parent call: + // `x.a().b()`, suggesting removing `.a()` would change the type and could make `.b()` unavailable. + Node::Expr(hir::Expr { + kind: hir::ExprKind::MethodCall(_, call_receiver, _, _), + .. + }) if call_receiver.hir_id == arg_hir_id => {} + _ => { + err.span_suggestion_verbose( + expr.span.with_lo(rcvr.span.hi()), + format!( + "consider removing this method call, as the receiver has type `{ty}` and \ + `{pred}` trivially holds", + ), + "", + Applicability::MaybeIncorrect, + ); + } + } } if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr { let inner_expr = expr.peel_blocks(); diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs index d8fd1d44a9858..37fa016920535 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs @@ -9,3 +9,11 @@ fn main() { //~| HELP try using a fully qualified path to specify the expected types //~| HELP consider removing this method call, as the receiver has type `Bar` and `Bar: From` trivially holds } + +// regression test for https://github.com/rust-lang/rust/issues/149487. +fn quux() { + let mut tx_heights: std::collections::BTreeMap<(), Option<()>> = <_>::default(); + tx_heights.get(&()).unwrap_or_default(); + //~^ ERROR the trait bound `&Option<()>: Default` is not satisfied + //~| HELP: the trait `Default` is implemented for `Option` +} diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr index 7d795581ea9d8..f0c9931252792 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr @@ -23,6 +23,18 @@ LL - qux(Bar.into()); LL + qux(Bar); | -error: aborting due to 1 previous error +error[E0277]: the trait bound `&Option<()>: Default` is not satisfied + --> $DIR/argument-with-unnecessary-method-call.rs:16:25 + | +LL | tx_heights.get(&()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&Option<()>` + | +help: the trait `Default` is implemented for `Option` + --> $SRC_DIR/core/src/option.rs:LL:COL +note: required by a bound in `Option::::unwrap_or_default` + --> $SRC_DIR/core/src/option.rs:LL:COL + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0277, E0283. +For more information about an error, try `rustc --explain E0277`. From 998a0df610eff8c262106c3dc567358d241ef026 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 28 Dec 2025 15:18:30 -0500 Subject: [PATCH 02/10] more sophisticated checking --- .../src/error_reporting/traits/suggestions.rs | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index c5b014293f98d..511e9e85b5f60 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4069,24 +4069,45 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) && expr.span.hi() != rcvr.span.hi() { - match tcx.hir_node(call_hir_id) { - // Do not suggest removing a method call if the argument is the receiver of the parent call: - // `x.a().b()`, suggesting removing `.a()` would change the type and could make `.b()` unavailable. + let should_sugg = match tcx.hir_node(call_hir_id) { Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(_, call_receiver, _, _), .. - }) if call_receiver.hir_id == arg_hir_id => {} - _ => { - err.span_suggestion_verbose( - expr.span.with_lo(rcvr.span.hi()), - format!( - "consider removing this method call, as the receiver has type `{ty}` and \ - `{pred}` trivially holds", - ), - "", - Applicability::MaybeIncorrect, - ); + }) if let Some((DefKind::AssocFn, did)) = + typeck_results.type_dependent_def(call_hir_id) + && call_receiver.hir_id == arg_hir_id => + { + // Avoid suggesting removing a method call if the argument is the receiver of the parent call and + // removing the receiver would make the method inaccessible. i.e. `x.a().b()`, suggesting removing + // `.a()` could change the type and make `.b()` unavailable. + if tcx.inherent_impl_of_assoc(did).is_some() { + // if we're calling an inherent impl method, just try to make sure that the receiver type stays the same. + Some(ty) == typeck_results.node_type_opt(arg_hir_id) + } else { + // we're calling a trait method, so we just check removing the method call still satisfies the trait. + let trait_id = tcx + .trait_of_assoc(did) + .unwrap_or_else(|| tcx.impl_trait_id(tcx.parent(did))); + let args = typeck_results.node_args(call_hir_id); + let tr = ty::TraitRef::from_assoc(tcx, trait_id, args) + .with_replaced_self_ty(tcx, ty); + self.type_implements_trait(tr.def_id, tr.args, param_env) + .must_apply_modulo_regions() + } } + _ => true, + }; + + if should_sugg { + err.span_suggestion_verbose( + expr.span.with_lo(rcvr.span.hi()), + format!( + "consider removing this method call, as the receiver has type `{ty}` and \ + `{pred}` trivially holds", + ), + "", + Applicability::MaybeIncorrect, + ); } } if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr { From 33add367e2b265f4ed0fcc32e7f795f87992c488 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Thu, 1 Jan 2026 18:34:24 +0100 Subject: [PATCH 03/10] Add checks for gpu-kernel calling conv The `gpu-kernel` calling convention has several restrictions that were not enforced by the compiler until now. Add the following restrictions: 1. Cannot be async 2. Cannot be called 3. Cannot return values, return type must be `()` or `!` 4. Arguments should be primitives, i.e. passed by value. More complicated types can work when you know what you are doing, but it is rather unintuitive, one needs to know ABI/compiler internals. 5. Export name should be unmangled, either through `no_mangle` or `export_name`. Kernels are searched by name on the CPU side, having a mangled name makes it hard to find and probably almost always unintentional. --- compiler/rustc_abi/src/extern_abi.rs | 1 - .../rustc_ast_passes/src/ast_validation.rs | 34 +-- compiler/rustc_hir_typeck/messages.ftl | 4 + compiler/rustc_hir_typeck/src/callee.rs | 26 +-- compiler/rustc_hir_typeck/src/errors.rs | 8 + compiler/rustc_lint/messages.ftl | 7 + compiler/rustc_lint/src/gpukernel_abi.rs | 194 ++++++++++++++++++ compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/lints.rs | 13 ++ tests/ui/abi/cannot-be-called.amdgpu.stderr | 87 ++++++++ tests/ui/abi/cannot-be-called.avr.stderr | 38 ++-- tests/ui/abi/cannot-be-called.i686.stderr | 38 ++-- tests/ui/abi/cannot-be-called.msp430.stderr | 38 ++-- tests/ui/abi/cannot-be-called.nvptx.stderr | 87 ++++++++ tests/ui/abi/cannot-be-called.riscv32.stderr | 42 ++-- tests/ui/abi/cannot-be-called.riscv64.stderr | 42 ++-- tests/ui/abi/cannot-be-called.rs | 39 ++-- tests/ui/abi/cannot-be-called.x64.stderr | 38 ++-- tests/ui/abi/cannot-be-called.x64_win.stderr | 38 ++-- .../ui/abi/cannot-be-coroutine.amdgpu.stderr | 23 +++ tests/ui/abi/cannot-be-coroutine.avr.stderr | 4 +- tests/ui/abi/cannot-be-coroutine.i686.stderr | 4 +- .../ui/abi/cannot-be-coroutine.msp430.stderr | 4 +- tests/ui/abi/cannot-be-coroutine.nvptx.stderr | 23 +++ .../ui/abi/cannot-be-coroutine.riscv32.stderr | 6 +- .../ui/abi/cannot-be-coroutine.riscv64.stderr | 6 +- tests/ui/abi/cannot-be-coroutine.rs | 13 +- tests/ui/abi/cannot-be-coroutine.x64.stderr | 4 +- .../ui/abi/cannot-be-coroutine.x64_win.stderr | 4 +- tests/ui/abi/cannot-return.amdgpu.stderr | 15 ++ tests/ui/abi/cannot-return.nvptx.stderr | 15 ++ tests/ui/abi/cannot-return.rs | 18 ++ tests/ui/lint/lint-gpu-kernel.amdgpu.stderr | 86 ++++++++ tests/ui/lint/lint-gpu-kernel.nvptx.stderr | 86 ++++++++ tests/ui/lint/lint-gpu-kernel.rs | 62 ++++++ 35 files changed, 998 insertions(+), 152 deletions(-) create mode 100644 compiler/rustc_lint/src/gpukernel_abi.rs create mode 100644 tests/ui/abi/cannot-be-called.amdgpu.stderr create mode 100644 tests/ui/abi/cannot-be-called.nvptx.stderr create mode 100644 tests/ui/abi/cannot-be-coroutine.amdgpu.stderr create mode 100644 tests/ui/abi/cannot-be-coroutine.nvptx.stderr create mode 100644 tests/ui/abi/cannot-return.amdgpu.stderr create mode 100644 tests/ui/abi/cannot-return.nvptx.stderr create mode 100644 tests/ui/abi/cannot-return.rs create mode 100644 tests/ui/lint/lint-gpu-kernel.amdgpu.stderr create mode 100644 tests/ui/lint/lint-gpu-kernel.nvptx.stderr create mode 100644 tests/ui/lint/lint-gpu-kernel.rs diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 6a5ea36f2a424..e44dea1ce593b 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -67,7 +67,6 @@ pub enum ExternAbi { /* gpu */ /// An entry-point function called by the GPU's host - // FIXME: should not be callable from Rust on GPU targets, is for host's use only GpuKernel, /// An entry-point function called by the GPU's host // FIXME: why do we have two of these? diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0d34ba6c2ca87..3e70687c16d3a 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -401,9 +401,16 @@ impl<'a> AstValidator<'a> { | CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::Arm(_) - | CanonAbi::GpuKernel | CanonAbi::X86(_) => { /* nothing to check */ } + CanonAbi::GpuKernel => { + // An `extern "gpu-kernel"` function cannot be `async` and/or `gen`. + self.reject_coroutine(abi, sig); + + // An `extern "gpu-kernel"` function cannot return a value. + self.reject_return(abi, sig); + } + CanonAbi::Custom => { // An `extern "custom"` function must be unsafe. self.reject_safe_fn(abi, ctxt, sig); @@ -433,18 +440,7 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::AbiX86Interrupt { spans, param_count }); } - if let FnRetTy::Ty(ref ret_ty) = sig.decl.output - && match &ret_ty.kind { - TyKind::Never => false, - TyKind::Tup(tup) if tup.is_empty() => false, - _ => true, - } - { - self.dcx().emit_err(errors::AbiMustNotHaveReturnType { - span: ret_ty.span, - abi, - }); - } + self.reject_return(abi, sig); } else { // An `extern "interrupt"` function must have type `fn()`. self.reject_params_or_return(abi, ident, sig); @@ -496,6 +492,18 @@ impl<'a> AstValidator<'a> { } } + fn reject_return(&self, abi: ExternAbi, sig: &FnSig) { + if let FnRetTy::Ty(ref ret_ty) = sig.decl.output + && match &ret_ty.kind { + TyKind::Never => false, + TyKind::Tup(tup) if tup.is_empty() => false, + _ => true, + } + { + self.dcx().emit_err(errors::AbiMustNotHaveReturnType { span: ret_ty.span, abi }); + } + } + fn reject_params_or_return(&self, abi: ExternAbi, ident: &Ident, sig: &FnSig) { let mut spans: Vec<_> = sig.decl.inputs.iter().map(|p| p.span).collect(); if let FnRetTy::Ty(ref ret_ty) = sig.decl.output diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 325be43a0065c..0c4b1f891eadb 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -133,6 +133,10 @@ hir_typeck_fru_suggestion = hir_typeck_functional_record_update_on_non_struct = functional record update syntax requires a struct +hir_typeck_gpu_kernel_abi_cannot_be_called = + functions with the "gpu-kernel" ABI cannot be called + .note = an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 714c6a104a9e1..b60d053957a9b 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -169,27 +169,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let valid = match canon_abi { + match canon_abi { // Rust doesn't know how to call functions with this ABI. - CanonAbi::Custom => false, - - // These is an entry point for the host, and cannot be called on the GPU. - CanonAbi::GpuKernel => false, - + CanonAbi::Custom // The interrupt ABIs should only be called by the CPU. They have complex // pre- and postconditions, and can use non-standard instructions like `iret` on x86. - CanonAbi::Interrupt(_) => false, + | CanonAbi::Interrupt(_) => { + let err = crate::errors::AbiCannotBeCalled { span, abi }; + self.tcx.dcx().emit_err(err); + } + + // This is an entry point for the host, and cannot be called directly. + CanonAbi::GpuKernel => { + let err = crate::errors::GpuKernelAbiCannotBeCalled { span }; + self.tcx.dcx().emit_err(err); + } CanonAbi::C | CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::Arm(_) - | CanonAbi::X86(_) => true, - }; - - if !valid { - let err = crate::errors::AbiCannotBeCalled { span, abi }; - self.tcx.dcx().emit_err(err); + | CanonAbi::X86(_) => {} } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 620002915fa8d..0cf7f09e93767 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1198,6 +1198,14 @@ pub(crate) struct AbiCannotBeCalled { pub abi: ExternAbi, } +#[derive(Diagnostic)] +#[diag(hir_typeck_gpu_kernel_abi_cannot_be_called)] +pub(crate) struct GpuKernelAbiCannotBeCalled { + #[primary_span] + #[note] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_const_continue_bad_label)] pub(crate) struct ConstContinueBadLabel { diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 56a0a3ceebf5a..2f4537b94da20 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -470,6 +470,9 @@ lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreign function interfaces +lint_improper_gpu_kernel_arg = passing type `{$ty}` to a function with "gpu-kernel" ABI may have unexpected behavior + .help = use primitive types and raw pointers to get reliable behavior + lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance .note = this is dangerous because dereferencing the resulting pointer is undefined behavior .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance @@ -597,6 +600,10 @@ lint_mismatched_lifetime_syntaxes_suggestion_mixed = lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths = use `'_` for type paths +lint_missing_gpu_kernel_export_name = function with the "gpu-kernel" ABI has a mangled name + .note = mangled names make it hard to find the kernel, this is usually not intended + .help = use `unsafe(no_mangle)` or `unsafe(export_name = "")` + lint_mixed_script_confusables = the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables .includes_note = the usage includes {$includes} diff --git a/compiler/rustc_lint/src/gpukernel_abi.rs b/compiler/rustc_lint/src/gpukernel_abi.rs new file mode 100644 index 0000000000000..dbdf5b6e7955f --- /dev/null +++ b/compiler/rustc_lint/src/gpukernel_abi.rs @@ -0,0 +1,194 @@ +use std::iter; + +use rustc_abi::ExternAbi; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{self as hir, find_attr}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::Span; +use rustc_span::def_id::LocalDefId; + +use crate::lints::{ImproperGpuKernelArg, MissingGpuKernelExportName}; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `improper_gpu_kernel_arg` lint detects incorrect use of types in `gpu-kernel` + /// arguments. + /// + /// ### Example + /// + /// ```rust,ignore (fails on non-GPU targets) + /// #[unsafe(no_mangle)] + /// extern "gpu-kernel" fn kernel(_: [i32; 10]) {} + /// ``` + /// + /// This will produce: + /// + /// ```text + /// warning: passing type `[i32; 10]` to a function with "gpu-kernel" ABI may have unexpected behavior + /// --> t.rs:2:34 + /// | + /// 2 | extern "gpu-kernel" fn kernel(_: [i32; 10]) {} + /// | ^^^^^^^^^ + /// | + /// = help: use primitive types and raw pointers to get reliable behavior + /// = note: `#[warn(improper_gpu_kernel_arg)]` on by default + /// ``` + /// + /// ### Explanation + /// + /// The compiler has several checks to verify that types used as arguments in `gpu-kernel` + /// functions follow certain rules to ensure proper compatibility with the foreign interfaces. + /// This lint is issued when it detects a probable mistake in a signature. + IMPROPER_GPU_KERNEL_ARG, + Warn, + "GPU kernel entry points have a limited ABI" +} + +declare_lint! { + /// The `missing_gpu_kernel_export_name` lint detects `gpu-kernel` functions that have a mangled name. + /// + /// ### Example + /// + /// ```rust,ignore (fails on non-GPU targets) + /// extern "gpu-kernel" fn kernel() { } + /// ``` + /// + /// This will produce: + /// + /// ```text + /// warning: function with the "gpu-kernel" ABI has a mangled name + /// --> t.rs:1:1 + /// | + /// 1 | extern "gpu-kernel" fn kernel() {} + /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// | + /// = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + /// = note: mangled names make it hard to find the kernel, this is usually not intended + /// = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + /// ``` + /// + /// ### Explanation + /// + /// `gpu-kernel` functions are usually searched by name in the compiled file. + /// A mangled name is usually unintentional as it would need to be searched by the mangled name. + /// + /// To use an unmangled name for the kernel, either `no_mangle` or `export_name` can be used. + /// ```rust,ignore (fails on non-GPU targets) + /// // Can be found by the name "kernel" + /// #[unsafe(no_mangle)] + /// extern "gpu-kernel" fn kernel() { } + /// + /// // Can be found by the name "new_name" + /// #[unsafe(export_name = "new_name")] + /// extern "gpu-kernel" fn other_kernel() { } + /// ``` + MISSING_GPU_KERNEL_EXPORT_NAME, + Warn, + "mangled gpu-kernel function" +} + +declare_lint_pass!(ImproperGpuKernelLint => [ + IMPROPER_GPU_KERNEL_ARG, + MISSING_GPU_KERNEL_EXPORT_NAME, +]); + +/// Check for valid and invalid types. +struct CheckGpuKernelTypes<'tcx> { + tcx: TyCtxt<'tcx>, + // If one or more invalid types were encountered while folding. + has_invalid: bool, +} + +impl<'tcx> TypeFolder> for CheckGpuKernelTypes<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.kind() { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {} + // Thin pointers are allowed but fat pointers with metadata are not + ty::RawPtr(_, _) => { + if !ty.pointee_metadata_ty_or_projection(self.tcx).is_unit() { + self.has_invalid = true; + } + } + + ty::Adt(_, _) + | ty::Alias(_, _) + | ty::Array(_, _) + | ty::Bound(_, _) + | ty::Closure(_, _) + | ty::Coroutine(_, _) + | ty::CoroutineClosure(_, _) + | ty::CoroutineWitness(..) + | ty::Dynamic(_, _) + | ty::FnDef(_, _) + | ty::FnPtr(..) + | ty::Foreign(_) + | ty::Never + | ty::Pat(_, _) + | ty::Placeholder(_) + | ty::Ref(_, _, _) + | ty::Slice(_) + | ty::Str + | ty::Tuple(_) => self.has_invalid = true, + + _ => return ty.super_fold_with(self), + } + ty + } +} + +/// `ImproperGpuKernelLint` checks `gpu-kernel` function definitions: +/// +/// - `extern "gpu-kernel" fn` arguments should be primitive types. +/// - `extern "gpu-kernel" fn` should have an unmangled name. +impl<'tcx> LateLintPass<'tcx> for ImproperGpuKernelLint { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + kind: hir::intravisit::FnKind<'tcx>, + decl: &'tcx hir::FnDecl<'_>, + _: &'tcx hir::Body<'_>, + span: Span, + id: LocalDefId, + ) { + use hir::intravisit::FnKind; + + let abi = match kind { + FnKind::ItemFn(_, _, header, ..) => header.abi, + FnKind::Method(_, sig, ..) => sig.header.abi, + _ => return, + }; + + if abi != ExternAbi::GpuKernel { + return; + } + + let sig = cx.tcx.fn_sig(id).instantiate_identity(); + let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); + + for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { + let mut checker = CheckGpuKernelTypes { tcx: cx.tcx, has_invalid: false }; + input_ty.fold_with(&mut checker); + if checker.has_invalid { + cx.tcx.emit_node_span_lint( + IMPROPER_GPU_KERNEL_ARG, + input_hir.hir_id, + input_hir.span, + ImproperGpuKernelArg { ty: *input_ty }, + ); + } + } + + // Check for no_mangle/export_name, so the kernel can be found when querying the compiled object for the kernel function by name + if !find_attr!( + cx.tcx.get_all_attrs(id), + AttributeKind::NoMangle(..) | AttributeKind::ExportName { .. } + ) { + cx.emit_span_lint(MISSING_GPU_KERNEL_EXPORT_NAME, span, MissingGpuKernelExportName); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 49929a0a9bc76..dd2042b57f526 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -47,6 +47,7 @@ mod expect; mod for_loops_over_fallibles; mod foreign_modules; mod function_cast_as_integer; +mod gpukernel_abi; mod if_let_rescope; mod impl_trait_overcaptures; mod interior_mutable_consts; @@ -93,6 +94,7 @@ use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use function_cast_as_integer::*; +use gpukernel_abi::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; use interior_mutable_consts::*; @@ -197,6 +199,7 @@ late_lint_methods!( DerefIntoDynSupertrait: DerefIntoDynSupertrait, DropForgetUseless: DropForgetUseless, ImproperCTypesLint: ImproperCTypesLint, + ImproperGpuKernelLint: ImproperGpuKernelLint, InvalidFromUtf8: InvalidFromUtf8, VariantSizeDifferences: VariantSizeDifferences, PathStatements: PathStatements, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 5017ce7caa525..ba486f95427d0 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2008,6 +2008,19 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { } } +#[derive(LintDiagnostic)] +#[diag(lint_improper_gpu_kernel_arg)] +#[help] +pub(crate) struct ImproperGpuKernelArg<'a> { + pub ty: Ty<'a>, +} + +#[derive(LintDiagnostic)] +#[diag(lint_missing_gpu_kernel_export_name)] +#[help] +#[note] +pub(crate) struct MissingGpuKernelExportName; + #[derive(LintDiagnostic)] #[diag(lint_variant_size_differences)] pub(crate) struct VariantSizeDifferencesDiag { diff --git a/tests/ui/abi/cannot-be-called.amdgpu.stderr b/tests/ui/abi/cannot-be-called.amdgpu.stderr new file mode 100644 index 0000000000000..039e2d7b4f009 --- /dev/null +++ b/tests/ui/abi/cannot-be-called.amdgpu.stderr @@ -0,0 +1,87 @@ +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:43:8 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:45:8 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:47:8 + | +LL | extern "riscv-interrupt-m" fn riscv_m() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:49:8 + | +LL | extern "riscv-interrupt-s" fn riscv_s() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:51:8 + | +LL | extern "x86-interrupt" fn x86(_x: *const u8) {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:76:22 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:82:25 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:88:26 + | +LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:94:26 + | +LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:100:22 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.avr.stderr b/tests/ui/abi/cannot-be-called.avr.stderr index 2128991d83cdf..752292a58705f 100644 --- a/tests/ui/abi/cannot-be-called.avr.stderr +++ b/tests/ui/abi/cannot-be-called.avr.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:53:5 + --> $DIR/cannot-be-called.rs:60:5 | LL | avr(); | ^^^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:53:5 + --> $DIR/cannot-be-called.rs:60:5 | LL | avr(); | ^^^^^ error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:69:5 + --> $DIR/cannot-be-called.rs:78:5 | LL | f() | ^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:69:5 + --> $DIR/cannot-be-called.rs:78:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.i686.stderr b/tests/ui/abi/cannot-be-called.i686.stderr index 9b1755921aea4..30e294ad61ecc 100644 --- a/tests/ui/abi/cannot-be-called.i686.stderr +++ b/tests/ui/abi/cannot-be-called.i686.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.msp430.stderr b/tests/ui/abi/cannot-be-called.msp430.stderr index 9a047b11cf795..12ab88bc858bd 100644 --- a/tests/ui/abi/cannot-be-called.msp430.stderr +++ b/tests/ui/abi/cannot-be-called.msp430.stderr @@ -1,75 +1,87 @@ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:55:5 + --> $DIR/cannot-be-called.rs:62:5 | LL | msp430(); | ^^^^^^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:55:5 + --> $DIR/cannot-be-called.rs:62:5 | LL | msp430(); | ^^^^^^^^ error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:75:5 + --> $DIR/cannot-be-called.rs:84:5 | LL | f() | ^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:75:5 + --> $DIR/cannot-be-called.rs:84:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.nvptx.stderr b/tests/ui/abi/cannot-be-called.nvptx.stderr new file mode 100644 index 0000000000000..039e2d7b4f009 --- /dev/null +++ b/tests/ui/abi/cannot-be-called.nvptx.stderr @@ -0,0 +1,87 @@ +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:43:8 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:45:8 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:47:8 + | +LL | extern "riscv-interrupt-m" fn riscv_m() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:49:8 + | +LL | extern "riscv-interrupt-s" fn riscv_s() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:51:8 + | +LL | extern "x86-interrupt" fn x86(_x: *const u8) {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:76:22 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:82:25 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:88:26 + | +LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:94:26 + | +LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:100:22 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.riscv32.stderr b/tests/ui/abi/cannot-be-called.riscv32.stderr index 135b20c50d58a..b1897b74ebbe3 100644 --- a/tests/ui/abi/cannot-be-called.riscv32.stderr +++ b/tests/ui/abi/cannot-be-called.riscv32.stderr @@ -1,87 +1,99 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.riscv64.stderr b/tests/ui/abi/cannot-be-called.riscv64.stderr index 135b20c50d58a..b1897b74ebbe3 100644 --- a/tests/ui/abi/cannot-be-called.riscv64.stderr +++ b/tests/ui/abi/cannot-be-called.riscv64.stderr @@ -1,87 +1,99 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.rs b/tests/ui/abi/cannot-be-called.rs index 315ea1601633e..8d1a4ae0b557f 100644 --- a/tests/ui/abi/cannot-be-called.rs +++ b/tests/ui/abi/cannot-be-called.rs @@ -4,7 +4,7 @@ Interrupt ABIs share similar semantics, in that they are special entry-points un So we test that they error in essentially all of the same places. */ //@ add-minicore -//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 +//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 amdgpu nvptx // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -20,6 +20,10 @@ So we test that they error in essentially all of the same places. //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -27,7 +31,8 @@ So we test that they error in essentially all of the same places. abi_msp430_interrupt, abi_avr_interrupt, abi_x86_interrupt, - abi_riscv_interrupt + abi_riscv_interrupt, + abi_gpu_kernel )] extern crate minicore; @@ -36,15 +41,17 @@ use minicore::*; /* extern "interrupt" definition */ extern "msp430-interrupt" fn msp430() {} -//[x64,x64_win,i686,riscv32,riscv64,avr]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,riscv32,riscv64,avr,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "avr-interrupt" fn avr() {} -//[x64,x64_win,i686,riscv32,riscv64,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,riscv32,riscv64,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "riscv-interrupt-m" fn riscv_m() {} -//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "riscv-interrupt-s" fn riscv_s() {} -//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "x86-interrupt" fn x86(_x: *const u8) {} -//[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI +//[riscv32,riscv64,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI +extern "gpu-kernel" fn gpu_kernel() {} +//[x64,x64_win,i686,riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI static BYTE: u8 = 0; @@ -60,36 +67,44 @@ fn call_the_interrupts() { //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called x86(&raw const BYTE); //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called + gpu_kernel(); + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be called } /* extern "interrupt" fnptr calls */ fn avr_ptr(f: extern "avr-interrupt" fn()) { - //[x64,x64_win,i686,riscv32,riscv64,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,riscv32,riscv64,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[avr]~^ ERROR functions with the "avr-interrupt" ABI cannot be called } fn msp430_ptr(f: extern "msp430-interrupt" fn()) { - //[x64,x64_win,i686,riscv32,riscv64,avr]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,riscv32,riscv64,avr,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[msp430]~^ ERROR functions with the "msp430-interrupt" ABI cannot be called } fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { - //[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-m" ABI cannot be called } fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { - //[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called } fn x86_ptr(f: extern "x86-interrupt" fn()) { - //[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI + //[riscv32,riscv64,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called } + +fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + //[x64,x64_win,i686,riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI + f() + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be called +} diff --git a/tests/ui/abi/cannot-be-called.x64.stderr b/tests/ui/abi/cannot-be-called.x64.stderr index 9b1755921aea4..30e294ad61ecc 100644 --- a/tests/ui/abi/cannot-be-called.x64.stderr +++ b/tests/ui/abi/cannot-be-called.x64.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.x64_win.stderr b/tests/ui/abi/cannot-be-called.x64_win.stderr index 9b1755921aea4..30e294ad61ecc 100644 --- a/tests/ui/abi/cannot-be-called.x64_win.stderr +++ b/tests/ui/abi/cannot-be-called.x64_win.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr b/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr new file mode 100644 index 0000000000000..a36ea0caa19eb --- /dev/null +++ b/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr @@ -0,0 +1,23 @@ +error: functions with the "gpu-kernel" ABI cannot be `async` + --> $DIR/cannot-be-coroutine.rs:62:1 + | +LL | async extern "gpu-kernel" fn async_kernel() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `async` keyword from this definition + | +LL - async extern "gpu-kernel" fn async_kernel() { +LL + extern "gpu-kernel" fn async_kernel() { + | + +error: requires `ResumeTy` lang_item + --> $DIR/cannot-be-coroutine.rs:38:19 + | +LL | async fn vanilla(){ + | ___________________^ +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/abi/cannot-be-coroutine.avr.stderr b/tests/ui/abi/cannot-be-coroutine.avr.stderr index 11bc93b1eef11..643a575bece15 100644 --- a/tests/ui/abi/cannot-be-coroutine.avr.stderr +++ b/tests/ui/abi/cannot-be-coroutine.avr.stderr @@ -1,5 +1,5 @@ error: functions with the "avr-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:37:1 + --> $DIR/cannot-be-coroutine.rs:42:1 | LL | async extern "avr-interrupt" fn avr() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "avr-interrupt" fn avr() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.i686.stderr b/tests/ui/abi/cannot-be-coroutine.i686.stderr index 4a344bb090200..f618507df47d2 100644 --- a/tests/ui/abi/cannot-be-coroutine.i686.stderr +++ b/tests/ui/abi/cannot-be-coroutine.i686.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.msp430.stderr b/tests/ui/abi/cannot-be-coroutine.msp430.stderr index c2867705df78c..f2586c8cd9755 100644 --- a/tests/ui/abi/cannot-be-coroutine.msp430.stderr +++ b/tests/ui/abi/cannot-be-coroutine.msp430.stderr @@ -1,5 +1,5 @@ error: functions with the "msp430-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:41:1 + --> $DIR/cannot-be-coroutine.rs:46:1 | LL | async extern "msp430-interrupt" fn msp430() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "msp430-interrupt" fn msp430() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.nvptx.stderr b/tests/ui/abi/cannot-be-coroutine.nvptx.stderr new file mode 100644 index 0000000000000..a36ea0caa19eb --- /dev/null +++ b/tests/ui/abi/cannot-be-coroutine.nvptx.stderr @@ -0,0 +1,23 @@ +error: functions with the "gpu-kernel" ABI cannot be `async` + --> $DIR/cannot-be-coroutine.rs:62:1 + | +LL | async extern "gpu-kernel" fn async_kernel() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `async` keyword from this definition + | +LL - async extern "gpu-kernel" fn async_kernel() { +LL + extern "gpu-kernel" fn async_kernel() { + | + +error: requires `ResumeTy` lang_item + --> $DIR/cannot-be-coroutine.rs:38:19 + | +LL | async fn vanilla(){ + | ___________________^ +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr index 398f888205dfb..c5a8c3f60a382 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:45:1 + --> $DIR/cannot-be-coroutine.rs:50:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:49:1 + --> $DIR/cannot-be-coroutine.rs:54:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr index 398f888205dfb..c5a8c3f60a382 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:45:1 + --> $DIR/cannot-be-coroutine.rs:50:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:49:1 + --> $DIR/cannot-be-coroutine.rs:54:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.rs b/tests/ui/abi/cannot-be-coroutine.rs index c070e8032e1af..239f5aa5c31fe 100644 --- a/tests/ui/abi/cannot-be-coroutine.rs +++ b/tests/ui/abi/cannot-be-coroutine.rs @@ -1,6 +1,6 @@ //@ add-minicore //@ edition: 2021 -//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 +//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 amdgpu nvptx // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -16,6 +16,10 @@ //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -23,7 +27,8 @@ abi_msp430_interrupt, abi_avr_interrupt, abi_x86_interrupt, - abi_riscv_interrupt + abi_riscv_interrupt, + abi_gpu_kernel )] extern crate minicore; @@ -53,3 +58,7 @@ async extern "riscv-interrupt-s" fn riscv_s() { async extern "x86-interrupt" fn x86(_p: *mut ()) { //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be `async` } + +async extern "gpu-kernel" fn async_kernel() { + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be `async` +} diff --git a/tests/ui/abi/cannot-be-coroutine.x64.stderr b/tests/ui/abi/cannot-be-coroutine.x64.stderr index 4a344bb090200..f618507df47d2 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr index 4a344bb090200..f618507df47d2 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-return.amdgpu.stderr b/tests/ui/abi/cannot-return.amdgpu.stderr new file mode 100644 index 0000000000000..f264907d00ec2 --- /dev/null +++ b/tests/ui/abi/cannot-return.amdgpu.stderr @@ -0,0 +1,15 @@ +error: invalid signature for `extern "gpu-kernel"` function + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + | + = note: functions with the "gpu-kernel" ABI cannot have a return type +help: remove the return type + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/cannot-return.nvptx.stderr b/tests/ui/abi/cannot-return.nvptx.stderr new file mode 100644 index 0000000000000..f264907d00ec2 --- /dev/null +++ b/tests/ui/abi/cannot-return.nvptx.stderr @@ -0,0 +1,15 @@ +error: invalid signature for `extern "gpu-kernel"` function + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + | + = note: functions with the "gpu-kernel" ABI cannot have a return type +help: remove the return type + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/cannot-return.rs b/tests/ui/abi/cannot-return.rs new file mode 100644 index 0000000000000..9a5db30431b9f --- /dev/null +++ b/tests/ui/abi/cannot-return.rs @@ -0,0 +1,18 @@ +//@ add-minicore +//@ ignore-backends: gcc +//@ edition: 2024 +//@ revisions: amdgpu nvptx +// +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib +#![no_core] +#![feature(no_core, abi_gpu_kernel)] + +extern crate minicore; +use minicore::*; + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_i32() -> i32 { 0 } +//~^ ERROR invalid signature for `extern "gpu-kernel"` function diff --git a/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr b/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr new file mode 100644 index 0000000000000..21eebe42f8b1d --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr @@ -0,0 +1,86 @@ +warning: `extern` fn uses type `()`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + = note: `#[warn(improper_ctypes_definitions)]` on by default + +warning: passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ + | + = help: use primitive types and raw pointers to get reliable behavior + = note: `#[warn(improper_gpu_kernel_arg)]` on by default + +warning: passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:41:35 + | +LL | extern "gpu-kernel" fn arg_ref(_: &i32) { } + | ^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:44:39 + | +LL | extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } + | ^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `S`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-gpu-kernel.rs:47:1 + | +LL | struct S { a: i32, b: i32 } + | ^^^^^^^^ + +warning: passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `(i32, i32)`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + +warning: passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: function with the "gpu-kernel" ABI has a mangled name + --> $DIR/lint-gpu-kernel.rs:61:1 + | +LL | pub extern "gpu-kernel" fn mangled_kernel() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + = note: mangled names make it hard to find the kernel, this is usually not intended + = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + +warning: 9 warnings emitted + diff --git a/tests/ui/lint/lint-gpu-kernel.nvptx.stderr b/tests/ui/lint/lint-gpu-kernel.nvptx.stderr new file mode 100644 index 0000000000000..21eebe42f8b1d --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.nvptx.stderr @@ -0,0 +1,86 @@ +warning: `extern` fn uses type `()`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + = note: `#[warn(improper_ctypes_definitions)]` on by default + +warning: passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ + | + = help: use primitive types and raw pointers to get reliable behavior + = note: `#[warn(improper_gpu_kernel_arg)]` on by default + +warning: passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:41:35 + | +LL | extern "gpu-kernel" fn arg_ref(_: &i32) { } + | ^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:44:39 + | +LL | extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } + | ^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `S`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-gpu-kernel.rs:47:1 + | +LL | struct S { a: i32, b: i32 } + | ^^^^^^^^ + +warning: passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `(i32, i32)`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + +warning: passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: function with the "gpu-kernel" ABI has a mangled name + --> $DIR/lint-gpu-kernel.rs:61:1 + | +LL | pub extern "gpu-kernel" fn mangled_kernel() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + = note: mangled names make it hard to find the kernel, this is usually not intended + = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + +warning: 9 warnings emitted + diff --git a/tests/ui/lint/lint-gpu-kernel.rs b/tests/ui/lint/lint-gpu-kernel.rs new file mode 100644 index 0000000000000..9b3ed0d14d8ad --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.rs @@ -0,0 +1,62 @@ +// Test argument and return type restrictions of the gpu-kernel ABI and +// check for warnings on mangled gpu-kernels. + +//@ check-pass +//@ ignore-backends: gcc +//@ revisions: amdgpu nvptx +//@ add-minicore +//@ edition: 2024 +//@[amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 +//@[amdgpu] needs-llvm-components: amdgpu +//@[nvptx] compile-flags: --target nvptx64-nvidia-cuda +//@[nvptx] needs-llvm-components: nvptx + +#![feature(no_core, abi_gpu_kernel)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +// Return types can be () or ! +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_empty() {} +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_never() -> ! { loop {} } + +// Arguments can be scalars or pointers +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_i32(_: i32) { } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ptr(_: *const i32) { } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ptr_mut(_: *mut i32) { } + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_zst(_: ()) { } +//~^ WARN passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `()`, which is not FFI-safe + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ref(_: &i32) { } +//~^ WARN passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } +//~^ WARN passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + +struct S { a: i32, b: i32 } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_struct(_: S) { } +//~^ WARN passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `S`, which is not FFI-safe + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } +//~^ WARN passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `(i32, i32)`, which is not FFI-safe + +#[unsafe(export_name = "kernel")] +pub extern "gpu-kernel" fn allowed_kernel_name() {} + +pub extern "gpu-kernel" fn mangled_kernel() { } +//~^ WARN function with the "gpu-kernel" ABI has a mangled name From ae09be596846d60d14f50399da91ffcb70bfd12e Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 20:56:06 +0100 Subject: [PATCH 04/10] std: unify `sys::pal::common` and `sys_common` into `sys::helpers` --- library/std/src/lib.rs | 2 - library/std/src/sys/helpers/mod.rs | 38 ++++++++++++++++ .../{pal/common => helpers}/small_c_string.rs | 0 .../src/sys/{pal/common => helpers}/tests.rs | 8 +++- .../src/{sys_common => sys/helpers}/wstr.rs | 1 - library/std/src/sys/mod.rs | 1 + library/std/src/sys/pal/common/mod.rs | 16 ------- library/std/src/sys/pal/mod.rs | 2 - library/std/src/sys_common/mod.rs | 44 ------------------- library/std/src/sys_common/tests.rs | 6 --- 10 files changed, 46 insertions(+), 72 deletions(-) create mode 100644 library/std/src/sys/helpers/mod.rs rename library/std/src/sys/{pal/common => helpers}/small_c_string.rs (100%) rename library/std/src/sys/{pal/common => helpers}/tests.rs (89%) rename library/std/src/{sys_common => sys/helpers}/wstr.rs (98%) delete mode 100644 library/std/src/sys/pal/common/mod.rs delete mode 100644 library/std/src/sys_common/mod.rs delete mode 100644 library/std/src/sys_common/tests.rs diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0dab29712f4fc..f5b9f69a5f9f9 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -681,9 +681,7 @@ pub mod arch { #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; -// Platform-abstraction modules mod sys; -mod sys_common; pub mod alloc; diff --git a/library/std/src/sys/helpers/mod.rs b/library/std/src/sys/helpers/mod.rs new file mode 100644 index 0000000000000..c29d9d2ce2d1c --- /dev/null +++ b/library/std/src/sys/helpers/mod.rs @@ -0,0 +1,38 @@ +//! Small helper functions used inside `sys`. +//! +//! If any of these have uses outside of `sys`, please move them to a different +//! module. + +#[cfg_attr(not(target_os = "linux"), allow(unused))] // Not used on all platforms. +mod small_c_string; +#[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. +mod wstr; + +#[cfg(test)] +mod tests; + +#[cfg_attr(not(target_os = "linux"), allow(unused))] // Not used on all platforms. +pub use small_c_string::{run_path_with_cstr, run_with_cstr}; +#[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. +pub use wstr::WStrUnits; + +// Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the +// overall result fit into i64 (which is the case for our time conversions). +#[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. +pub fn mul_div_u64(value: u64, numerator: u64, denom: u64) -> u64 { + let q = value / denom; + let r = value % denom; + // Decompose value as (value/denom*denom + value%denom), + // substitute into (value*numerator)/denom and simplify. + // r < denom, so (denom*numerator) is the upper bound of (r*numerator) + q * numerator + r * numerator / denom +} + +#[cfg_attr(not(target_os = "linux"), allow(unused))] // Not used on all platforms. +pub fn ignore_notfound(result: crate::io::Result) -> crate::io::Result<()> { + match result { + Err(err) if err.kind() == crate::io::ErrorKind::NotFound => Ok(()), + Ok(_) => Ok(()), + Err(err) => Err(err), + } +} diff --git a/library/std/src/sys/pal/common/small_c_string.rs b/library/std/src/sys/helpers/small_c_string.rs similarity index 100% rename from library/std/src/sys/pal/common/small_c_string.rs rename to library/std/src/sys/helpers/small_c_string.rs diff --git a/library/std/src/sys/pal/common/tests.rs b/library/std/src/sys/helpers/tests.rs similarity index 89% rename from library/std/src/sys/pal/common/tests.rs rename to library/std/src/sys/helpers/tests.rs index b7698907070c7..b67fdb9408d63 100644 --- a/library/std/src/sys/pal/common/tests.rs +++ b/library/std/src/sys/helpers/tests.rs @@ -1,9 +1,10 @@ use core::iter::repeat; +use super::mul_div_u64; +use super::small_c_string::run_path_with_cstr; use crate::ffi::CString; use crate::hint::black_box; use crate::path::Path; -use crate::sys::common::small_c_string::run_path_with_cstr; #[test] fn stack_allocation_works() { @@ -65,3 +66,8 @@ fn bench_heap_path_alloc(b: &mut test::Bencher) { .unwrap(); }); } + +#[test] +fn test_muldiv() { + assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000); +} diff --git a/library/std/src/sys_common/wstr.rs b/library/std/src/sys/helpers/wstr.rs similarity index 98% rename from library/std/src/sys_common/wstr.rs rename to library/std/src/sys/helpers/wstr.rs index f9a171fb7d8f5..9c4b8e09e463b 100644 --- a/library/std/src/sys_common/wstr.rs +++ b/library/std/src/sys/helpers/wstr.rs @@ -1,5 +1,4 @@ //! This module contains constructs to work with 16-bit characters (UCS-2 or UTF-16) -#![allow(dead_code)] use crate::marker::PhantomData; use crate::num::NonZero; diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 0c72f6a57fe81..bfdbc6ee5d1ee 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -11,6 +11,7 @@ mod configure_builtins; mod pal; mod alloc; +mod helpers; mod personality; pub mod args; diff --git a/library/std/src/sys/pal/common/mod.rs b/library/std/src/sys/pal/common/mod.rs deleted file mode 100644 index 9af4dee401cf3..0000000000000 --- a/library/std/src/sys/pal/common/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -// This module contains code that is shared between all platforms, mostly utility or fallback code. -// This explicitly does not include code that is shared between only a few platforms, -// such as when reusing an implementation from `unix` or `unsupported`. -// In those cases the desired code should be included directly using the #[path] attribute, -// not moved to this module. -// -// Currently `sys_common` contains a lot of code that should live in this module, -// ideally `sys_common` would only contain platform-independent abstractions on top of `sys`. -// Progress on this is tracked in #84187. - -#![allow(dead_code)] - -pub mod small_c_string; - -#[cfg(test)] -mod tests; diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 93ad4536e18f6..c039c28948773 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -22,8 +22,6 @@ #![allow(missing_debug_implementations)] -pub mod common; - cfg_select! { unix => { mod unix; diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs deleted file mode 100644 index 015042440b5a1..0000000000000 --- a/library/std/src/sys_common/mod.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! Platform-independent platform abstraction -//! -//! This is the platform-independent portion of the standard library's -//! platform abstraction layer, whereas `std::sys` is the -//! platform-specific portion. -//! -//! The relationship between `std::sys_common`, `std::sys` and the -//! rest of `std` is complex, with dependencies going in all -//! directions: `std` depending on `sys_common`, `sys_common` -//! depending on `sys`, and `sys` depending on `sys_common` and `std`. -//! This is because `sys_common` not only contains platform-independent code, -//! but also code that is shared between the different platforms in `sys`. -//! Ideally all that shared code should be moved to `sys::common`, -//! and the dependencies between `std`, `sys_common` and `sys` all would form a DAG. -//! Progress on this is tracked in #84187. - -#![allow(missing_docs)] - -#[cfg(test)] -mod tests; - -pub mod wstr; - -// common error constructors - -// Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the -// overall result fit into i64 (which is the case for our time conversions). -#[allow(dead_code)] // not used on all platforms -pub fn mul_div_u64(value: u64, numerator: u64, denom: u64) -> u64 { - let q = value / denom; - let r = value % denom; - // Decompose value as (value/denom*denom + value%denom), - // substitute into (value*numerator)/denom and simplify. - // r < denom, so (denom*numerator) is the upper bound of (r*numerator) - q * numerator + r * numerator / denom -} - -pub fn ignore_notfound(result: crate::io::Result) -> crate::io::Result<()> { - match result { - Err(err) if err.kind() == crate::io::ErrorKind::NotFound => Ok(()), - Ok(_) => Ok(()), - Err(err) => Err(err), - } -} diff --git a/library/std/src/sys_common/tests.rs b/library/std/src/sys_common/tests.rs deleted file mode 100644 index 1b6446db52d4b..0000000000000 --- a/library/std/src/sys_common/tests.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::mul_div_u64; - -#[test] -fn test_muldiv() { - assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000); -} From f4fe287d877d372c948730ad6720e74d818a2292 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 21:09:11 +0100 Subject: [PATCH 05/10] std: update imports of `sys::helpers` --- library/std/src/sys/args/windows.rs | 2 +- library/std/src/sys/env/solid.rs | 2 +- library/std/src/sys/env/uefi.rs | 2 +- library/std/src/sys/env/unix.rs | 2 +- library/std/src/sys/env/wasi.rs | 2 +- library/std/src/sys/fs/common.rs | 2 +- library/std/src/sys/fs/hermit.rs | 2 +- library/std/src/sys/fs/mod.rs | 2 +- library/std/src/sys/fs/solid.rs | 2 +- library/std/src/sys/fs/uefi.rs | 4 ++-- library/std/src/sys/fs/unix.rs | 5 ++--- library/std/src/sys/fs/vexos.rs | 2 +- library/std/src/sys/net/connection/socket/mod.rs | 2 +- library/std/src/sys/net/connection/uefi/tcp.rs | 2 +- library/std/src/sys/pal/uefi/helpers.rs | 2 +- library/std/src/sys/pal/uefi/time.rs | 2 +- library/std/src/sys/pal/unix/os.rs | 2 +- library/std/src/sys/pal/wasi/os.rs | 2 +- library/std/src/sys/pal/windows/time.rs | 2 +- library/std/src/sys/path/cygwin.rs | 2 +- library/std/src/sys/path/uefi.rs | 3 ++- .../std/src/sys/platform_version/darwin/core_foundation.rs | 2 +- library/std/src/sys/process/uefi.rs | 2 +- 23 files changed, 26 insertions(+), 26 deletions(-) diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index b4de759e1a4ce..c1988657ff1b1 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs @@ -11,11 +11,11 @@ use crate::ffi::{OsStr, OsString}; use crate::num::NonZero; use crate::os::windows::prelude::*; use crate::path::{Path, PathBuf}; +use crate::sys::helpers::WStrUnits; use crate::sys::pal::os::current_exe; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::path::get_long_path; use crate::sys::{AsInner, c, to_u16s}; -use crate::sys_common::wstr::WStrUnits; use crate::{io, iter, ptr}; pub fn args() -> Args { diff --git a/library/std/src/sys/env/solid.rs b/library/std/src/sys/env/solid.rs index ea77fc3c11930..0ce5a22b42561 100644 --- a/library/std/src/sys/env/solid.rs +++ b/library/std/src/sys/env/solid.rs @@ -6,7 +6,7 @@ use crate::io; use crate::os::raw::{c_char, c_int}; use crate::os::solid::ffi::{OsStrExt, OsStringExt}; use crate::sync::{PoisonError, RwLock}; -use crate::sys::common::small_c_string::run_with_cstr; +use crate::sys::helpers::run_with_cstr; static ENV_LOCK: RwLock<()> = RwLock::new(()); diff --git a/library/std/src/sys/env/uefi.rs b/library/std/src/sys/env/uefi.rs index 1561df41cac3f..5fe29a47a2ea1 100644 --- a/library/std/src/sys/env/uefi.rs +++ b/library/std/src/sys/env/uefi.rs @@ -24,7 +24,7 @@ mod uefi_env { use crate::io; use crate::os::uefi::ffi::OsStringExt; use crate::ptr::NonNull; - use crate::sys::{helpers, unsupported_err}; + use crate::sys::pal::{helpers, unsupported_err}; pub(crate) fn get(key: &OsStr) -> Option { let shell = helpers::open_shell()?; diff --git a/library/std/src/sys/env/unix.rs b/library/std/src/sys/env/unix.rs index 78c7af65f9e38..66805ce3fa71e 100644 --- a/library/std/src/sys/env/unix.rs +++ b/library/std/src/sys/env/unix.rs @@ -7,8 +7,8 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::io; use crate::os::unix::prelude::*; use crate::sync::{PoisonError, RwLock}; -use crate::sys::common::small_c_string::run_with_cstr; use crate::sys::cvt; +use crate::sys::helpers::run_with_cstr; // Use `_NSGetEnviron` on Apple platforms. // diff --git a/library/std/src/sys/env/wasi.rs b/library/std/src/sys/env/wasi.rs index 1327cbc3263b8..c970aac182604 100644 --- a/library/std/src/sys/env/wasi.rs +++ b/library/std/src/sys/env/wasi.rs @@ -4,7 +4,7 @@ pub use super::common::Env; use crate::ffi::{CStr, OsStr, OsString}; use crate::io; use crate::os::wasi::prelude::*; -use crate::sys::common::small_c_string::run_with_cstr; +use crate::sys::helpers::run_with_cstr; use crate::sys::pal::os::{cvt, libc}; cfg_select! { diff --git a/library/std/src/sys/fs/common.rs b/library/std/src/sys/fs/common.rs index bfd684d295b89..fbd075d57d617 100644 --- a/library/std/src/sys/fs/common.rs +++ b/library/std/src/sys/fs/common.rs @@ -3,7 +3,7 @@ use crate::fs; use crate::io::{self, Error, ErrorKind}; use crate::path::Path; -use crate::sys_common::ignore_notfound; +use crate::sys::helpers::ignore_notfound; pub(crate) const NOT_FILE_ERROR: Error = io::const_error!( ErrorKind::InvalidInput, diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 0914e4b6c907b..bb0c44d7e9a1e 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -9,9 +9,9 @@ use crate::os::hermit::hermit_abi::{ use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::path::{Path, PathBuf}; use crate::sync::Arc; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::{copy, exists}; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, unsupported, unsupported_err}; use crate::{fmt, mem}; diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index 4a66227ce5f45..fa046cb8e7da0 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -17,7 +17,7 @@ cfg_select! { pub(crate) use unix::debug_assert_fd_is_open; #[cfg(any(target_os = "linux", target_os = "android"))] pub(super) use unix::CachedFileMetadata; - use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path; + use crate::sys::helpers::run_path_with_cstr as with_native_path; } target_os = "windows" => { mod windows; diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index f6d5d3b784d3b..b6d41cc4bc842 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -10,10 +10,10 @@ use crate::os::solid::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sync::Arc; pub use crate::sys::fs::common::exists; +use crate::sys::helpers::ignore_notfound; use crate::sys::pal::{abi, error}; use crate::sys::time::SystemTime; use crate::sys::{unsupported, unsupported_err}; -use crate::sys_common::ignore_notfound; type CIntNotMinusOne = core::num::niche_types::NotAllOnes; diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 8339d835dd1c2..f5530962c5702 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,8 +6,8 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; +use crate::sys::pal::{helpers, unsupported}; use crate::sys::time::SystemTime; -use crate::sys::{helpers, unsupported}; const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; @@ -497,7 +497,7 @@ mod uefi_fs { use crate::os::uefi::ffi::OsStringExt; use crate::path::Path; use crate::ptr::NonNull; - use crate::sys::helpers::{self, UefiBox}; + use crate::sys::pal::helpers::{self, UefiBox}; use crate::sys::time::{self, SystemTime}; pub(crate) struct File { diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 7ac09cbea3daf..1cc2edd0cf474 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -89,9 +89,9 @@ use crate::os::unix::prelude::*; use crate::os::wasi::prelude::*; use crate::path::{Path, PathBuf}; use crate::sync::Arc; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::exists; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; #[cfg(all(target_os = "linux", target_env = "gnu"))] use crate::sys::weak::syscall; @@ -2498,9 +2498,8 @@ mod remove_dir_impl { use crate::ffi::CStr; use crate::io; use crate::path::{Path, PathBuf}; - use crate::sys::common::small_c_string::run_path_with_cstr; + use crate::sys::helpers::{ignore_notfound, run_path_with_cstr}; use crate::sys::{cvt, cvt_r}; - use crate::sys_common::ignore_notfound; pub fn openat_nofollow_dironly(parent_fd: Option, p: &CStr) -> io::Result { let fd = cvt_r(|| unsafe { diff --git a/library/std/src/sys/fs/vexos.rs b/library/std/src/sys/fs/vexos.rs index 381c87c62c688..81083a4fa81d3 100644 --- a/library/std/src/sys/fs/vexos.rs +++ b/library/std/src/sys/fs/vexos.rs @@ -4,7 +4,7 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; use crate::sys::{unsupported, unsupported_err}; diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index c6df9c6b8ae16..256b99dfa9874 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -7,7 +7,7 @@ use crate::mem::MaybeUninit; use crate::net::{ Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, }; -use crate::sys::common::small_c_string::run_with_cstr; +use crate::sys::helpers::run_with_cstr; use crate::sys::net::connection::each_addr; use crate::sys::{AsInner, FromInner}; use crate::time::Duration; diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 1e7e829c85f35..0c8ba08d81493 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -2,7 +2,7 @@ use super::tcp4; use crate::io::{self, IoSlice, IoSliceMut}; use crate::net::SocketAddr; use crate::ptr::NonNull; -use crate::sys::{helpers, unsupported}; +use crate::sys::pal::{helpers, unsupported}; use crate::time::Duration; pub(crate) enum Tcp { diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index d059be010e98b..353702447813b 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -24,7 +24,7 @@ use crate::path::Path; use crate::ptr::NonNull; use crate::slice; use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; -use crate::sys_common::wstr::WStrUnits; +use crate::sys::helpers::WStrUnits; type BootInstallMultipleProtocolInterfaces = unsafe extern "efiapi" fn(_: *mut r_efi::efi::Handle, _: ...) -> r_efi::efi::Status; diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index c0f13de252ed4..3dccd03ff3fc8 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -300,7 +300,7 @@ pub(crate) mod instant_internal { use crate::mem::MaybeUninit; use crate::ptr::NonNull; use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; - use crate::sys_common::mul_div_u64; + use crate::sys::helpers::mul_div_u64; const NS_PER_SEC: u64 = 1_000_000_000; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index edb7b604415b0..ef3b4a02f8ae4 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -10,8 +10,8 @@ use libc::{c_char, c_int, c_void}; use crate::ffi::{CStr, OsStr, OsString}; use crate::os::unix::prelude::*; use crate::path::{self, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; +use crate::sys::helpers::run_path_with_cstr; use crate::{fmt, io, iter, mem, ptr, slice, str}; const TMPBUF_SZ: usize = 128; diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index a3bb329c2c4f9..fee187a8adf3c 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -4,7 +4,7 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::marker::PhantomData; use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::unsupported; use crate::{fmt, io, str}; diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index ecd46c950b5e0..a555b2b546239 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -179,8 +179,8 @@ fn intervals2dur(intervals: u64) -> Duration { mod perf_counter { use super::NANOS_PER_SEC; use crate::sync::atomic::{Atomic, AtomicU64, Ordering}; + use crate::sys::helpers::mul_div_u64; use crate::sys::{c, cvt}; - use crate::sys_common::mul_div_u64; use crate::time::Duration; pub struct PerformanceCounterInstant { diff --git a/library/std/src/sys/path/cygwin.rs b/library/std/src/sys/path/cygwin.rs index 416877a7280d2..75f0de6beaeb5 100644 --- a/library/std/src/sys/path/cygwin.rs +++ b/library/std/src/sys/path/cygwin.rs @@ -1,8 +1,8 @@ use crate::ffi::OsString; use crate::os::unix::ffi::OsStringExt; use crate::path::{Path, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; +use crate::sys::helpers::run_path_with_cstr; use crate::{io, ptr}; #[inline] diff --git a/library/std/src/sys/path/uefi.rs b/library/std/src/sys/path/uefi.rs index 6b8258685aa0f..84d634af93cf1 100644 --- a/library/std/src/sys/path/uefi.rs +++ b/library/std/src/sys/path/uefi.rs @@ -2,7 +2,8 @@ use crate::ffi::OsStr; use crate::io; use crate::path::{Path, PathBuf, Prefix}; -use crate::sys::{helpers, unsupported_err}; +use crate::sys::pal::helpers; +use crate::sys::unsupported_err; const FORWARD_SLASH: u8 = b'/'; const COLON: u8 = b':'; diff --git a/library/std/src/sys/platform_version/darwin/core_foundation.rs b/library/std/src/sys/platform_version/darwin/core_foundation.rs index 1e0d15fcf661d..de2b57ea755b7 100644 --- a/library/std/src/sys/platform_version/darwin/core_foundation.rs +++ b/library/std/src/sys/platform_version/darwin/core_foundation.rs @@ -3,7 +3,7 @@ use super::root_relative; use crate::ffi::{CStr, c_char, c_void}; use crate::ptr::null_mut; -use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::helpers::run_path_with_cstr; // MacTypes.h pub(super) type Boolean = u8; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 0e10bc02a0b90..d627a477dc1ab 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -377,8 +377,8 @@ mod uefi_command_internal { use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::ptr::NonNull; use crate::slice; + use crate::sys::helpers::WStrUnits; use crate::sys::pal::helpers::{self, OwnedTable}; - use crate::sys_common::wstr::WStrUnits; pub struct Image { handle: NonNull, From d8489c1ea02d9af8035d8aca5d4ee16056051eeb Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 21:19:40 +0100 Subject: [PATCH 06/10] std: remove outdated documentation in `sys` --- library/std/src/sys/configure_builtins.rs | 4 ++++ library/std/src/sys/mod.rs | 12 ++-------- .../src/sys/net/connection/socket/hermit.rs | 1 - .../src/sys/net/connection/socket/solid.rs | 1 - .../std/src/sys/net/connection/socket/unix.rs | 1 - .../src/sys/net/connection/socket/windows.rs | 1 - library/std/src/sys/pal/mod.rs | 23 ++----------------- src/tools/tidy/src/pal.rs | 1 - 8 files changed, 8 insertions(+), 36 deletions(-) diff --git a/library/std/src/sys/configure_builtins.rs b/library/std/src/sys/configure_builtins.rs index f569ec0f51298..7cdf04ebb8899 100644 --- a/library/std/src/sys/configure_builtins.rs +++ b/library/std/src/sys/configure_builtins.rs @@ -1,3 +1,7 @@ +//! The configure builtins provides runtime support compiler-builtin features +//! which require dynamic initialization to work as expected, e.g. aarch64 +//! outline-atomics. + /// Enable LSE atomic operations at startup, if supported. /// /// Linker sections are based on what [`ctor`] does, with priorities to run slightly before user diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index bfdbc6ee5d1ee..c9035938cfdd3 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -1,17 +1,9 @@ #![allow(unsafe_op_in_unsafe_fn)] -/// The configure builtins provides runtime support compiler-builtin features -/// which require dynamic initialization to work as expected, e.g. aarch64 -/// outline-atomics. -mod configure_builtins; - -/// The PAL (platform abstraction layer) contains platform-specific abstractions -/// for implementing the features in the other submodules, e.g. UNIX file -/// descriptors. -mod pal; - mod alloc; +mod configure_builtins; mod helpers; +mod pal; mod personality; pub mod args; diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index c32f8dcc8de86..d57a075eb42d5 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -300,7 +300,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index 673d75046d3f2..e20a3fbb76b72 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -353,7 +353,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This method is used by sys_common code to abstract over targets. pub fn as_raw(&self) -> c_int { self.as_raw_fd() } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 6d06a8d86bf16..d09ba97cfe012 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -614,7 +614,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> RawFd { self.as_raw_fd() } diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 7355f0ce6bf5e..3f99249efc47f 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -439,7 +439,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> c::SOCKET { debug_assert_eq!(size_of::(), size_of::()); debug_assert_eq!(align_of::(), align_of::()); diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index c039c28948773..88d9d42059900 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -1,24 +1,5 @@ -//! Platform-dependent platform abstraction. -//! -//! The `std::sys` module is the abstracted interface through which -//! `std` talks to the underlying operating system. It has different -//! implementations for different operating system families, today -//! just Unix and Windows, and initial support for Redox. -//! -//! The centralization of platform-specific code in this module is -//! enforced by the "platform abstraction layer" tidy script in -//! `tools/tidy/src/pal.rs`. -//! -//! This module is closely related to the platform-independent system -//! integration code in `std::sys_common`. See that module's -//! documentation for details. -//! -//! In the future it would be desirable for the independent -//! implementations of this module to be extracted to their own crates -//! that `std` can link to, thus enabling their implementation -//! out-of-tree via crate replacement. Though due to the complex -//! inter-dependencies within `std` that will be a challenging goal to -//! achieve. +//! The PAL (platform abstraction layer) contains platform-specific abstractions +//! for implementing the features in the other submodules, such as e.g. bindings. #![allow(missing_debug_implementations)] diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index e5945a72d32a0..e6423aeeba995 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -24,7 +24,6 @@ //! - `sys/` //! - `os/` //! -//! `std/sys_common` should _not_ contain platform-specific code. //! Finally, because std contains tests with platform-specific //! `ignore` attributes, once the parser encounters `mod tests`, //! platform-specific cfgs are allowed. Not sure yet how to deal with From fc9f0fbf565eb8ff20a67870b6be41919251f53c Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 29 Dec 2025 10:07:16 +0100 Subject: [PATCH 07/10] bless UI test referencing outdated paths --- .../miri/tests/fail/shims/fs/isolated_file.stderr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index af55ccfe5e679..09501f98a9aa0 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -15,12 +15,12 @@ LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode a at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC 3: std::sys::fs::PLATFORM::File::open::{closure#0} at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC - 4: std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack - at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - 5: std::sys::pal::PLATFORM::small_c_string::run_with_cstr - at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - 6: std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr - at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + 4: std::sys::helpers::small_c_string::run_with_cstr_stack + at RUSTLIB/std/src/sys/helpers/small_c_string.rs:LL:CC + 5: std::sys::helpers::small_c_string::run_with_cstr + at RUSTLIB/std/src/sys/helpers/small_c_string.rs:LL:CC + 6: std::sys::helpers::small_c_string::run_path_with_cstr + at RUSTLIB/std/src/sys/helpers/small_c_string.rs:LL:CC 7: std::sys::fs::PLATFORM::File::open at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC 8: std::fs::OpenOptions::_open From 7834c43ea6913f2ccf28373fffa321a495ab2f7c Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 29 Dec 2025 10:09:57 +0100 Subject: [PATCH 08/10] beautify comment in `sys::helpers` --- library/std/src/sys/helpers/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/helpers/mod.rs b/library/std/src/sys/helpers/mod.rs index c29d9d2ce2d1c..a6236799caea6 100644 --- a/library/std/src/sys/helpers/mod.rs +++ b/library/std/src/sys/helpers/mod.rs @@ -16,8 +16,9 @@ pub use small_c_string::{run_path_with_cstr, run_with_cstr}; #[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. pub use wstr::WStrUnits; -// Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the -// overall result fit into i64 (which is the case for our time conversions). +/// Computes `(value*numerator)/denom` without overflow, as long as both +/// `numerator*denom` and the overall result fit into `u64` (which is the case +/// for our time conversions). #[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. pub fn mul_div_u64(value: u64, numerator: u64, denom: u64) -> u64 { let q = value / denom; From ac453d34d21bc4817dd41df0a4eeac88a541b9ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 Jan 2026 20:21:00 +0100 Subject: [PATCH 09/10] Update `browser-ui-test` version to `0.23.0` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 007e2c116321d..ef74853b77a53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "browser-ui-test": "^0.22.2", + "browser-ui-test": "^0.23.0", "es-check": "^9.4.4", "eslint": "^8.57.1", "typescript": "^5.8.3" From 665781513e6a8d6a63ed9fab5b98f919ad3f627c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 Jan 2026 20:21:44 +0100 Subject: [PATCH 10/10] Fix changes coming from `browser-ui-test` version update --- tests/rustdoc-gui/anchors.goml | 8 ++++---- tests/rustdoc-gui/links-color.goml | 2 +- tests/rustdoc-gui/sidebar-mobile.goml | 2 +- tests/rustdoc-gui/sidebar-source-code-display.goml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml index 3168c8e17c52f..0e8c834a7a779 100644 --- a/tests/rustdoc-gui/anchors.goml +++ b/tests/rustdoc-gui/anchors.goml @@ -15,7 +15,7 @@ define-function: ( assert-css: (".main-heading h1 span", {"color": |main_heading_type_color|}) assert-css: ( ".rightside a.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "none"}, ALL, ) compare-elements-css: ( @@ -32,17 +32,17 @@ define-function: ( move-cursor-to: ".main-heading a.src" assert-css: ( ".main-heading a.src", - {"color": |src_link_color|, "text-decoration": "underline solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "underline"}, ) move-cursor-to: ".impl-items .rightside a.src" assert-css: ( ".impl-items .rightside a.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "none"}, ) move-cursor-to: ".impl-items a.rightside.src" assert-css: ( ".impl-items a.rightside.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "none"}, ) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index a363175c1ddbb..ae1509c6fa4ff 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -41,7 +41,7 @@ define-function: ( move-cursor-to: "dd a[href='long_code_block_link/index.html']" assert-css: ( "dd a[href='long_code_block_link/index.html']", - {"text-decoration": "underline solid " + |mod|}, + {"text-decoration": "underline"}, ) }, ) diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index f828516d76246..1fa5521baac97 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -49,7 +49,7 @@ assert-property: ("rustdoc-topbar", {"clientHeight": "45"}) // so the target is not obscured by the topbar. click: ".sidebar-menu-toggle" click: ".sidebar-elems section .block li > a" -assert-position: ("#method\.must_use", {"y": 46}) +assert-position: ("#method\.must_use", {"y": 45}) // Check that the bottom-most item on the sidebar menu can be scrolled fully into view. click: ".sidebar-menu-toggle" diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 99810cd786335..d2b667b498bc6 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -141,7 +141,7 @@ click: "#sidebar-button" wait-for-css: (".src .sidebar > *", {"visibility": "hidden"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' -store-value: (y_offset, "2567") +store-value: (y_offset, "2568") assert-window-property: {"pageYOffset": |y_offset|} // Expanding the sidebar... click: "#sidebar-button"