From 0f4ec281558a40645b125fda43f36d7006180e54 Mon Sep 17 00:00:00 2001 From: SATVIKsynopsis Date: Sun, 7 Dec 2025 16:58:31 +0530 Subject: [PATCH] lint: treat unsafe binders in improper_ctypes instead of ICE Replaced _binder with _ --- compiler/rustc_lint/messages.ftl | 2 ++ compiler/rustc_lint/src/types/improper_ctypes.rs | 4 +++- .../lint/improper-ctypes/unsafe-binder-basic.rs | 10 ++++++++++ .../improper-ctypes/unsafe-binder-basic.stderr | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs create mode 100644 tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 1bcdda96e13a2..a90a9c91ef13c 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -416,6 +416,8 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re lint_improper_ctypes_union_layout_reason = this union has unspecified layout 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_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 diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 9e38ea6b685bd..38094c67c34a0 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -669,7 +669,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiSafe } - ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + ty::UnsafeBinder(_) => { + FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_unsafe_binder, help: None } + } ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) diff --git a/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs new file mode 100644 index 0000000000000..5d4279fc834d1 --- /dev/null +++ b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs @@ -0,0 +1,10 @@ +#![feature(unsafe_binders)] +#![expect(incomplete_features)] +#![deny(improper_ctypes)] + +extern "C" { + fn exit_2(x: unsafe<'a> &'a ()); + //~^ ERROR `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe +} + +fn main() {} diff --git a/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr new file mode 100644 index 0000000000000..4b8d51690f1a0 --- /dev/null +++ b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr @@ -0,0 +1,15 @@ +error: `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe + --> $DIR/unsafe-binder-basic.rs:6:18 + | +LL | fn exit_2(x: unsafe<'a> &'a ()); + | ^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: unsafe binders are incompatible with foreign function interfaces +note: the lint level is defined here + --> $DIR/unsafe-binder-basic.rs:3:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +