Skip to content

Commit 8423d12

Browse files
lint: treat unsafe binders in improper_ctypes instead of ICE
this replaces an ICE in improper_ctypes with a proper diagnostic and ensures consistent handling of unsafe binders in FFI contexts. updated the diagnostic to display the full unsafe<a> &a() type added a fluent error message for this case adjusted UI test output for consistency
1 parent ba86c04 commit 8423d12

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dere
360360
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
361361
.label = not FFI-safe
362362
.note = the type is defined here
363-
364363
lint_improper_ctypes_array_help = consider passing a pointer to the array
365364
366365
lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
@@ -416,6 +415,8 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
416415
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
417416
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
418417
418+
lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreign function interfaces
419+
419420
lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance
420421
.note = this is dangerous because dereferencing the resulting pointer is undefined behavior
421422
.note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance

compiler/rustc_lint/src/types/improper_ctypes.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
669669
FfiSafe
670670
}
671671

672-
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),
672+
ty::UnsafeBinder(_binder) => {
673+
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_unsafe_binder, help: None }
674+
}
673675

674676
ty::Param(..)
675677
| ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
@@ -1016,7 +1018,6 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesLint {
10161018
| hir::ItemKind::ExternCrate(..) => {}
10171019
}
10181020
}
1019-
10201021
fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::FieldDef<'tcx>) {
10211022
self.check_type_for_external_abi_fnptr(
10221023
cx,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(unsafe_binders)]
2+
#![expect(incomplete_features)]
3+
#![deny(improper_ctypes)]
4+
5+
extern "C" {
6+
fn exit_2(x: unsafe<'a> &'a ());
7+
//~^ ERROR `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe
8+
}
9+
10+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe
2+
--> $DIR/unsafe-binder-basic.rs:6:18
3+
|
4+
LL | fn exit_2(x: unsafe<'a> &'a ());
5+
| ^^^^^^^^^^^^^^^^^ not FFI-safe
6+
|
7+
= note: unsafe binders are incompatible with foreign function interfaces
8+
note: the lint level is defined here
9+
--> $DIR/unsafe-binder-basic.rs:3:9
10+
|
11+
LL | #![deny(improper_ctypes)]
12+
| ^^^^^^^^^^^^^^^
13+
14+
error: aborting due to 1 previous error
15+

0 commit comments

Comments
 (0)