Skip to content

Commit cde6ad5

Browse files
committed
lint ImproperCTypes: split the two lints into four total [...]
- now the lint scans repr(C) struct/enum/union definitions - it now also scans method declarations in traits - many other changes in the underlying logic - some extra tests
1 parent a37e0c5 commit cde6ad5

File tree

125 files changed

+2279
-866
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+2279
-866
lines changed

compiler/rustc_codegen_cranelift/example/std_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn rust_call_abi() {
209209
struct I64X2([i64; 2]);
210210

211211
#[cfg_attr(target_arch = "s390x", allow(dead_code))]
212-
#[allow(improper_ctypes_definitions)]
212+
#[allow(improper_c_fn_definitions)]
213213
extern "C" fn foo(_a: I64X2) {}
214214

215215
#[cfg(target_arch = "x86_64")]

compiler/rustc_lint/messages.ftl

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dere
368368
.method_def = method calls to `{$method_name}` require a reference
369369
.suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit
370370
371-
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
371+
lint_improper_ctypes = {$desc} uses type `{$ty}`, which is not FFI-safe
372372
.label = not FFI-safe
373373
.note = the type is defined here
374374
@@ -416,35 +416,34 @@ lint_improper_ctypes_pat_intrange_reason = integers constrained to a given range
416416
417417
lint_improper_ctypes_ptr_validity_help = consider using a raw pointer, or wrapping `{$ty}` in an `Option<_>`
418418
lint_improper_ctypes_ptr_validity_reason =
419-
boxes and references are assumed to be valid (non-null, non-dangling, aligned) pointers,
419+
boxes, references, and function pointers are assumed to be valid (non-null, non-dangling, aligned) pointers,
420420
which cannot be garanteed if their values are produced by non-rust code
421421
422-
lint_improper_ctypes_sized_ptr_to_unsafe_type =
423-
this reference (`{$ty}`) is ABI-compatible with a C pointer, but `{$inner_ty}` itself does not have a C layout
424-
425422
lint_improper_ctypes_slice_help = consider using a raw pointer to the slice's first element (and a length) instead
426423
lint_improper_ctypes_slice_reason = slices have no C equivalent
427424
428425
lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
429426
lint_improper_ctypes_str_reason = string slices have no C equivalent
430427
428+
lint_improper_ctypes_struct_consider_transparent = `{$ty}` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
431429
lint_improper_ctypes_struct_dueto = this struct/enum/union (`{$ty}`) is FFI-unsafe due to a `{$inner_ty}` field
432-
lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
433430
434-
lint_improper_ctypes_struct_fieldless_reason = this struct has no fields
435-
lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
431+
lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
432+
lint_improper_ctypes_struct_fieldless_reason = `{$ty}` has no fields
436433
437-
lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout
438-
lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive
439-
lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields
434+
lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` (not `#[repr(C,packed)]`) or `#[repr(transparent)]` attribute to `{$ty}`
435+
lint_improper_ctypes_struct_layout_reason = `{$ty}` has unspecified layout
436+
lint_improper_ctypes_struct_non_exhaustive = `{$ty}` is non-exhaustive
437+
lint_improper_ctypes_struct_zst = `{$ty}` contains only zero-sized fields
440438
441439
lint_improper_ctypes_tuple_help = consider using a struct instead
442-
443440
lint_improper_ctypes_tuple_reason = tuples have unspecified layout
444-
lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
445441
442+
443+
lint_improper_ctypes_union_consider_transparent = `{$ty}` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
444+
lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
446445
lint_improper_ctypes_union_fieldless_reason = this union has no fields
447-
lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
446+
lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` attribute to this union
448447
449448
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
450449
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive

compiler/rustc_lint/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,7 @@ late_lint_methods!(
195195
DefaultCouldBeDerived: DefaultCouldBeDerived::default(),
196196
DerefIntoDynSupertrait: DerefIntoDynSupertrait,
197197
DropForgetUseless: DropForgetUseless,
198-
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
199-
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
198+
ImproperCTypesLint: ImproperCTypesLint,
200199
InvalidFromUtf8: InvalidFromUtf8,
201200
VariantSizeDifferences: VariantSizeDifferences,
202201
PathStatements: PathStatements,
@@ -337,6 +336,14 @@ fn register_builtins(store: &mut LintStore) {
337336
REFINING_IMPL_TRAIT_INTERNAL
338337
);
339338

339+
add_lint_group!(
340+
"improper_c_boundaries",
341+
IMPROPER_C_CALLBACKS,
342+
IMPROPER_C_FN_DEFINITIONS,
343+
IMPROPER_CTYPE_DEFINITIONS,
344+
IMPROPER_CTYPES
345+
);
346+
340347
add_lint_group!("deprecated_safe", DEPRECATED_SAFE_2024);
341348

342349
add_lint_group!(
@@ -364,6 +371,7 @@ fn register_builtins(store: &mut LintStore) {
364371
store.register_renamed("static_mut_ref", "static_mut_refs");
365372
store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries");
366373
store.register_renamed("elided_named_lifetimes", "mismatched_lifetime_syntaxes");
374+
store.register_renamed("improper_ctypes_definitions", "improper_c_fn_definitions");
367375

368376
// These were moved to tool lints, but rustc still sees them when compiling normally, before
369377
// tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use

compiler/rustc_lint/src/types.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use tracing::debug;
1111
use {rustc_ast as ast, rustc_hir as hir};
1212

1313
mod improper_ctypes; // these filed do the implementation for ImproperCTypesDefinitions,ImproperCTypesDeclarations
14-
pub(crate) use improper_ctypes::{ImproperCTypesDeclarations, ImproperCTypesDefinitions};
14+
pub(crate) use improper_ctypes::{
15+
IMPROPER_C_CALLBACKS, IMPROPER_C_FN_DEFINITIONS, IMPROPER_CTYPE_DEFINITIONS, IMPROPER_CTYPES,
16+
ImproperCTypesLint,
17+
};
1518

1619
use crate::lints::{
1720
AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion,
@@ -705,6 +708,26 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
705708
})
706709
}
707710

711+
/// for a given ADT variant, list which fields are non-1ZST
712+
/// (`repr(transparent)` guarantees that there is at most one)
713+
pub(crate) fn map_non_1zst_fields<'a, 'tcx>(
714+
tcx: TyCtxt<'tcx>,
715+
variant: &'a ty::VariantDef,
716+
) -> Vec<bool> {
717+
let typing_env = ty::TypingEnv::non_body_analysis(tcx, variant.def_id);
718+
variant
719+
.fields
720+
.iter()
721+
.map(|field| {
722+
let field_ty = tcx.type_of(field.did).instantiate_identity();
723+
let is_1zst = tcx
724+
.layout_of(typing_env.as_query_input(field_ty))
725+
.is_ok_and(|layout| layout.is_1zst());
726+
!is_1zst
727+
})
728+
.collect()
729+
}
730+
708731
/// Is type known to be non-null?
709732
fn ty_is_known_nonnull<'tcx>(
710733
tcx: TyCtxt<'tcx>,

0 commit comments

Comments
 (0)