Skip to content

Commit 51ab082

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 b501850 commit 51ab082

File tree

114 files changed

+2307
-831
lines changed

Some content is hidden

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

114 files changed

+2307
-831
lines changed

compiler/rustc_codegen_cranelift/example/std_example.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn rust_call_abi() {
209209
#[repr(simd)]
210210
struct I64X2([i64; 2]);
211211

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

+13-11
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than pos
355355
lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
356356
.suggestion = remove the `use<...>` syntax
357357
358-
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
358+
lint_improper_ctypes = {$desc} uses type `{$ty}`, which is not FFI-safe
359359
.label = not FFI-safe
360360
.note = the type is defined here
361361
@@ -405,7 +405,7 @@ lint_improper_ctypes_pat_intrange_reason = integers constrained to a given range
405405
406406
lint_improper_ctypes_ptr_validity_help = consider using a raw pointer, or wrapping `{$ty}` in an `Option<_>`
407407
lint_improper_ctypes_ptr_validity_reason =
408-
boxes and references are assumed to be valid (non-null, non-dangling, aligned) pointers,
408+
boxes, references, and function pointers are assumed to be valid (non-null, non-dangling, aligned) pointers,
409409
which cannot be garanteed if their values are produced by non-rust code
410410
411411
lint_improper_ctypes_sized_ptr_to_unsafe_type =
@@ -417,23 +417,25 @@ lint_improper_ctypes_slice_reason = slices have no C equivalent
417417
lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
418418
lint_improper_ctypes_str_reason = string slices have no C equivalent
419419
420+
lint_improper_ctypes_struct_consider_transparent = `{$ty}` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
420421
lint_improper_ctypes_struct_dueto = this struct/enum/union (`{$ty}`) is FFI-unsafe due to a `{$inner_ty}` field
421-
lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
422422
423-
lint_improper_ctypes_struct_fieldless_reason = this struct has no fields
424-
lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
423+
lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
424+
lint_improper_ctypes_struct_fieldless_reason = `{$ty}` has no fields
425425
426-
lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout
427-
lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive
428-
lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields
426+
lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` (not `#[repr(C,packed)]`) or `#[repr(transparent)]` attribute to `{$ty}`
427+
lint_improper_ctypes_struct_layout_reason = `{$ty}` has unspecified layout
428+
lint_improper_ctypes_struct_non_exhaustive = `{$ty}` is non-exhaustive
429+
lint_improper_ctypes_struct_zst = `{$ty}` contains only zero-sized fields
429430
430431
lint_improper_ctypes_tuple_help = consider using a struct instead
431-
432432
lint_improper_ctypes_tuple_reason = tuples have unspecified layout
433-
lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
434433
434+
435+
lint_improper_ctypes_union_consider_transparent = `{$ty}` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
436+
lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
435437
lint_improper_ctypes_union_fieldless_reason = this union has no fields
436-
lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
438+
lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` attribute to this union
437439
438440
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
439441
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive

compiler/rustc_lint/src/lib.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ late_lint_methods!(
195195
DefaultCouldBeDerived: DefaultCouldBeDerived::default(),
196196
DerefIntoDynSupertrait: DerefIntoDynSupertrait,
197197
DropForgetUseless: DropForgetUseless,
198-
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
199-
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
198+
//ImproperCTypesDeclarations: ImproperCTypesDeclarations,
199+
//ImproperCTypesDefinitions: ImproperCTypesDefinitions,
200+
ImproperCTypesLint: ImproperCTypesLint,
200201
InvalidFromUtf8: InvalidFromUtf8,
201202
VariantSizeDifferences: VariantSizeDifferences,
202203
PathStatements: PathStatements,
@@ -334,6 +335,14 @@ fn register_builtins(store: &mut LintStore) {
334335
REFINING_IMPL_TRAIT_INTERNAL
335336
);
336337

338+
add_lint_group!(
339+
"improper_c_boundaries",
340+
IMPROPER_C_CALLBACKS,
341+
IMPROPER_C_FN_DEFINITIONS,
342+
IMPROPER_CTYPE_DEFINITIONS,
343+
IMPROPER_CTYPES
344+
);
345+
337346
add_lint_group!("deprecated_safe", DEPRECATED_SAFE_2024);
338347

339348
// Register renamed and removed lints.
@@ -352,6 +361,7 @@ fn register_builtins(store: &mut LintStore) {
352361
store.register_renamed("unused_tuple_struct_fields", "dead_code");
353362
store.register_renamed("static_mut_ref", "static_mut_refs");
354363
store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries");
364+
store.register_renamed("improper_ctypes_definitions", "improper_c_fn_definitions");
355365

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

compiler/rustc_lint/src/lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,7 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
19231923
for reason in self.reasons.into_iter() {
19241924
diag.subdiagnostic(reason);
19251925
}
1926+
diag.arg("ty", self.ty); // ?
19261927
}
19271928
}
19281929

compiler/rustc_lint/src/types.rs

+24-1
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,
@@ -688,6 +691,26 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
688691
})
689692
}
690693

694+
/// for a given ADT variant, list which fields are non-1ZST
695+
/// (`repr(transparent)` guarantees that there is at most one)
696+
pub(crate) fn map_non_1zst_fields<'a, 'tcx>(
697+
tcx: TyCtxt<'tcx>,
698+
variant: &'a ty::VariantDef,
699+
) -> Vec<bool> {
700+
let typing_env = ty::TypingEnv::non_body_analysis(tcx, variant.def_id);
701+
variant
702+
.fields
703+
.iter()
704+
.map(|field| {
705+
let field_ty = tcx.type_of(field.did).instantiate_identity();
706+
let is_1zst = tcx
707+
.layout_of(typing_env.as_query_input(field_ty))
708+
.is_ok_and(|layout| layout.is_1zst());
709+
!is_1zst
710+
})
711+
.collect()
712+
}
713+
691714
/// Is type known to be non-null?
692715
fn ty_is_known_nonnull<'tcx>(
693716
tcx: TyCtxt<'tcx>,

0 commit comments

Comments
 (0)