Skip to content

Commit b9199e0

Browse files
committed
lint ImproperCTypes: rm improper_ctype_definitions [...]
for now, let's fully remove this lint. it might be reintroduced later as a way to make the lints ignore the inside of some ADT definitions
1 parent 92408df commit b9199e0

File tree

65 files changed

+180
-726
lines changed

Some content is hidden

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

65 files changed

+180
-726
lines changed

compiler/rustc_lint/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ fn register_builtins(store: &mut LintStore) {
338338
IMPROPER_C_CALLBACKS,
339339
IMPROPER_C_FN_DEFINITIONS,
340340
IMPROPER_C_VAR_DEFINITIONS,
341-
IMPROPER_CTYPE_DEFINITIONS,
342341
IMPROPER_CTYPES
343342
);
344343

compiler/rustc_lint/src/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use {rustc_ast as ast, rustc_hir as hir};
1212

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

1919
use crate::lints::{

compiler/rustc_lint/src/types/improper_ctypes.rs

Lines changed: 13 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ enum CItemKind {
105105
ExportedStatic,
106106
/// `extern "C"` function pointers -> IMPROPER_C_CALLBACKS,
107107
Callback,
108-
/// `repr(C)` structs/enums/unions -> IMPROPER_CTYPE_DEFINITIONS
109-
#[allow(unused)]
110-
AdtDef,
111108
}
112109

113110
#[derive(Clone, Debug)]
@@ -447,8 +444,6 @@ enum CTypesVisitorState {
447444
// uses bitflags from CTypesVisitorStateFlags
448445
StaticTy = CTypesVisitorStateFlags::STATIC,
449446
ExportedStaticTy = CTypesVisitorStateFlags::STATIC | CTypesVisitorStateFlags::FN_DEFINED,
450-
#[allow(unused)]
451-
AdtDef = CTypesVisitorStateFlags::THEORETICAL,
452447
ArgumentTyInDefinition = CTypesVisitorStateFlags::FUNC | CTypesVisitorStateFlags::FN_DEFINED,
453448
ReturnTyInDefinition = CTypesVisitorStateFlags::FUNC
454449
| CTypesVisitorStateFlags::FN_RETURN
@@ -508,11 +503,6 @@ impl CTypesVisitorState {
508503
((self as u8) & THEORETICAL) != 0 && self.is_in_function()
509504
}
510505

511-
/// whether the type is currently being defined
512-
fn is_being_defined(self) -> bool {
513-
self == Self::AdtDef
514-
}
515-
516506
/// whether we can expect type parameters and co in a given type
517507
fn can_expect_ty_params(self) -> bool {
518508
use CTypesVisitorStateFlags::*;
@@ -527,11 +517,7 @@ impl CTypesVisitorState {
527517
/// whether the value for that type might come from the non-rust side of a FFI boundary
528518
/// this is particularly useful for non-raw pointers, since rust assume they are non-null
529519
fn value_may_be_unchecked(self) -> bool {
530-
if self == Self::AdtDef {
531-
// some ADTs are only used to go through the FFI boundary in one direction,
532-
// so let's not make hasty judgement
533-
false
534-
} else if self.is_in_static() {
520+
if self.is_in_static() {
535521
// FIXME: this is evidently untrue for non-mut static variables
536522
// (assuming the cross-FFI code respects this)
537523
true
@@ -646,9 +632,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
646632
outer_ty: Option<Ty<'tcx>>,
647633
ty: Ty<'tcx>,
648634
) -> FfiResult<'tcx> {
649-
if state.is_being_defined()
650-
|| (state.is_in_function_return()
651-
&& matches!(outer_ty.map(|ty| ty.kind()), None | Some(ty::FnPtr(..)),))
635+
if state.is_in_function_return()
636+
&& matches!(outer_ty.map(|ty| ty.kind()), None | Some(ty::FnPtr(..)))
652637
{
653638
FfiResult::FfiSafe
654639
} else {
@@ -846,7 +831,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
846831
&self,
847832
state: CTypesVisitorState,
848833
ty: Ty<'tcx>,
849-
def: ty::AdtDef<'tcx>,
834+
def: AdtDef<'tcx>,
850835
variant: &ty::VariantDef,
851836
args: GenericArgsRef<'tcx>,
852837
) -> FfiResult<'tcx> {
@@ -1000,9 +985,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1000985
fn visit_struct_or_union(
1001986
&self,
1002987
state: CTypesVisitorState,
1003-
outer_ty: Option<Ty<'tcx>>,
1004988
ty: Ty<'tcx>,
1005-
def: ty::AdtDef<'tcx>,
989+
def: AdtDef<'tcx>,
1006990
args: GenericArgsRef<'tcx>,
1007991
) -> FfiResult<'tcx> {
1008992
debug_assert!(matches!(def.adt_kind(), AdtKind::Struct | AdtKind::Union));
@@ -1063,20 +1047,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10631047
// which is partly why we keep the details as to why that struct is FFI-unsafe)
10641048
// - if the struct is from another crate, then there's not much that can be done anyways
10651049
//
1066-
// if outer_ty.is_some() || !state.is_being_defined() then this enum is visited in the middle of another lint,
1050+
// this enum is visited in the middle of another lint,
10671051
// so we override the "cause type" of the lint
1068-
let override_cause_ty =
1069-
if state.is_being_defined() { outer_ty.and(Some(ty)) } else { Some(ty) };
1070-
1071-
ffires.with_overrides(override_cause_ty)
1052+
ffires.with_overrides(Some(ty))
10721053
}
10731054

10741055
fn visit_enum(
10751056
&self,
10761057
state: CTypesVisitorState,
10771058
outer_ty: Option<Ty<'tcx>>,
10781059
ty: Ty<'tcx>,
1079-
def: ty::AdtDef<'tcx>,
1060+
def: AdtDef<'tcx>,
10801061
args: GenericArgsRef<'tcx>,
10811062
) -> FfiResult<'tcx> {
10821063
debug_assert!(matches!(def.adt_kind(), AdtKind::Enum));
@@ -1163,12 +1144,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11631144
ffires += variants_uninhabited_ffires.into_iter().reduce(|r1, r2| r1 + r2).unwrap();
11641145
}
11651146

1166-
// if outer_ty.is_some() || !state.is_being_defined() then this enum is visited in the middle of another lint,
1147+
// this enum is visited in the middle of another lint,
11671148
// so we override the "cause type" of the lint
11681149
// (for more detail, see comment in ``visit_struct_union`` before its call to ``ffires.with_overrides``)
1169-
let override_cause_ty =
1170-
if state.is_being_defined() { outer_ty.and(Some(ty)) } else { Some(ty) };
1171-
ffires.with_overrides(override_cause_ty)
1150+
ffires.with_overrides(Some(ty))
11721151
}
11731152
}
11741153

@@ -1213,7 +1192,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12131192
{
12141193
return self.visit_cstr(outer_ty, ty);
12151194
}
1216-
self.visit_struct_or_union(state, outer_ty, ty, def, args)
1195+
self.visit_struct_or_union(state, ty, def, args)
12171196
}
12181197
AdtKind::Enum => self.visit_enum(state, outer_ty, ty, def, args),
12191198
}
@@ -1280,7 +1259,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12801259
ty::Slice(inner_ty) => {
12811260
// ty::Slice is used for !Sized arrays, since they are the pointee for actual slices
12821261
let slice_is_actually_array = match outer_ty.map(|ty| ty.kind()) {
1283-
None => state.is_in_static() || state.is_being_defined(),
1262+
None => state.is_in_static(),
12841263
// this should have been caught a layer up, in visit_indirection
12851264
Some(ty::Ref(..) | ty::RawPtr(..)) => false,
12861265
Some(ty::Adt(..)) => ty.boxed_ty().is_none(),
@@ -1522,71 +1501,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15221501
}
15231502
}
15241503

1525-
#[allow(unused)]
1526-
fn check_for_adtdef(&mut self, ty: Ty<'tcx>) -> FfiResult<'tcx> {
1527-
use FfiResult::*;
1528-
let ty = erase_and_maybe_normalize(self.cx, ty);
1529-
1530-
let mut ffires = match *ty.kind() {
1531-
ty::Adt(def, args) => {
1532-
if !def.did().is_local() {
1533-
bug!(
1534-
"check_adtdef expected to visit a locally-defined struct/enum/union not {:?}",
1535-
def
1536-
);
1537-
}
1538-
1539-
// question: how does this behave when running for "special" ADTs in the stdlib?
1540-
// answer: none of CStr, CString, Box, and PhantomData are repr(C)
1541-
let state = CTypesVisitorState::AdtDef;
1542-
match def.adt_kind() {
1543-
AdtKind::Struct | AdtKind::Union => {
1544-
self.visit_struct_or_union(state, None, ty, def, args)
1545-
}
1546-
AdtKind::Enum => self.visit_enum(state, None, ty, def, args),
1547-
}
1548-
}
1549-
r @ _ => {
1550-
bug!("expected to inspect the type of an `extern \"ABI\"` FnPtr, not {:?}", r,)
1551-
}
1552-
};
1553-
1554-
match &mut ffires {
1555-
// due to the way type visits work, any unsafeness that comes from the fields inside an ADT
1556-
// is uselessly "prefixed" with the fact that yes, the error occurs in that ADT
1557-
// we remove the prefixes here.
1558-
FfiUnsafe(explanations) => {
1559-
explanations.iter_mut().for_each(|explanation| {
1560-
if let Some(inner_reason) = explanation.reason.inner.take() {
1561-
debug_assert_eq!(explanation.reason.ty, ty);
1562-
debug_assert_eq!(
1563-
explanation.reason.note,
1564-
fluent::lint_improper_ctypes_struct_dueto
1565-
);
1566-
if let Some(help) = &explanation.reason.help {
1567-
// there is an actual help message in the normally useless prefix
1568-
// make sure it gets through
1569-
debug_assert_eq!(
1570-
help,
1571-
&fluent::lint_improper_ctypes_struct_consider_transparent
1572-
);
1573-
explanation.override_cause_ty = Some(inner_reason.ty);
1574-
explanation.reason.inner = Some(inner_reason);
1575-
} else {
1576-
explanation.reason = inner_reason;
1577-
}
1578-
}
1579-
});
1580-
}
1581-
1582-
// also, turn FfiPhantom into FfiSafe: unlike other places we can check, we don't want
1583-
// FfiPhantom to end up emitting a lint
1584-
ffires @ FfiPhantom(_) => *ffires = FfiSafe,
1585-
FfiSafe => {}
1586-
}
1587-
ffires
1588-
}
1589-
15901504
fn check_arg_for_power_alignment(&self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
15911505
let tcx = cx.tcx;
15921506
assert!(tcx.sess.target.os == "aix");
@@ -1748,12 +1662,7 @@ impl ImproperCTypesLint {
17481662
}
17491663

17501664
/// Check that a `#[no_mangle]`/`#[export_name = _]` static variable is of a ffi-safe type
1751-
fn check_exported_static<'tcx>(
1752-
&self,
1753-
cx: &LateContext<'tcx>,
1754-
id: hir::OwnerId,
1755-
span: Span,
1756-
) {
1665+
fn check_exported_static<'tcx>(&self, cx: &LateContext<'tcx>, id: hir::OwnerId, span: Span) {
17571666
let ty = cx.tcx.type_of(id).instantiate_identity();
17581667
let visitor = ImproperCTypesVisitor::new(cx);
17591668
let ffi_res = visitor.check_for_type(CTypesVisitorState::ExportedStaticTy, ty);
@@ -1869,15 +1778,13 @@ impl ImproperCTypesLint {
18691778
CItemKind::ImportedExtern => IMPROPER_CTYPES,
18701779
CItemKind::ExportedFunction => IMPROPER_C_FN_DEFINITIONS,
18711780
CItemKind::ExportedStatic => IMPROPER_C_VAR_DEFINITIONS,
1872-
CItemKind::AdtDef => IMPROPER_CTYPE_DEFINITIONS,
18731781
CItemKind::Callback => IMPROPER_C_CALLBACKS,
18741782
};
18751783
let desc = match fn_mode {
18761784
CItemKind::ImportedExtern => "`extern` block",
18771785
CItemKind::ExportedFunction => "`extern` fn",
18781786
CItemKind::ExportedStatic => "foreign-code-reachable static",
18791787
CItemKind::Callback => "`extern` callback",
1880-
CItemKind::AdtDef => "`repr(C)` type",
18811788
};
18821789
for reason in reasons.iter_mut() {
18831790
reason.span_note = if let ty::Adt(def, _) = reason.ty.kind()
@@ -1907,9 +1814,6 @@ impl ImproperCTypesLint {
19071814
/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
19081815
/// This only matters if `<abi>` is external (e.g. `C`).
19091816
///
1910-
/// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1911-
/// assuming they are to have a fully C-compatible layout.
1912-
///
19131817
/// and now combinatorics for pointees
19141818
impl<'tcx> LateLintPass<'tcx> for ImproperCTypesLint {
19151819
fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) {
@@ -2178,33 +2082,6 @@ declare_lint! {
21782082
"proper use of libc types in foreign-code-compatible callbacks"
21792083
}
21802084

2181-
declare_lint! {
2182-
/// The `improper_ctype_definitions` lint detects incorrect use of types in
2183-
/// foreign-compatible structs, enums, and union definitions.
2184-
///
2185-
/// ### Example
2186-
///
2187-
/// ```rust
2188-
/// repr(C) struct StringWrapper{
2189-
/// length: usize,
2190-
/// strung: &str,
2191-
/// }
2192-
/// ```
2193-
///
2194-
/// {{produces}}
2195-
///
2196-
/// ### Explanation
2197-
///
2198-
/// The compiler has several checks to verify that types designed to be
2199-
/// compatible with foreign interfaces follow certain rules to be safe.
2200-
/// This lint is issued when it detects a probable mistake in a definition.
2201-
/// The lint usually should provide a description of the issue,
2202-
/// along with possibly a hint on how to resolve it.
2203-
pub(crate) IMPROPER_CTYPE_DEFINITIONS,
2204-
Warn,
2205-
"proper use of libc types when defining foreign-code-compatible structs"
2206-
}
2207-
22082085
declare_lint! {
22092086
/// The `uses_power_alignment` lint detects specific `repr(C)`
22102087
/// aggregates on AIX.
@@ -2265,6 +2142,5 @@ declare_lint_pass!(ImproperCTypesLint => [
22652142
IMPROPER_C_FN_DEFINITIONS,
22662143
IMPROPER_C_VAR_DEFINITIONS,
22672144
IMPROPER_C_CALLBACKS,
2268-
IMPROPER_CTYPE_DEFINITIONS,
22692145
USES_POWER_ALIGNMENT,
22702146
]);

library/alloc/src/boxed.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@
9595
//!
9696
//! ```
9797
//! #[repr(C)]
98-
//! #[allow(improper_ctype_definitions)]
9998
//! pub struct Foo;
10099
//!
101100
//! #[unsafe(no_mangle)]

library/coretests/tests/mem.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,6 @@ fn offset_of_dst() {
642642
trait Trait {}
643643

644644
#[repr(C)]
645-
#[allow(improper_ctype_definitions)]
646645
struct Beta {
647646
x: u8,
648647
y: u16,

library/panic_unwind/src/gcc.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ static CANARY: u8 = 0;
5252
// The first two field must be `_Unwind_Exception` and `canary`,
5353
// as it may be accessed by a different version of the std with a different compiler.
5454
#[repr(C)]
55-
#[allow(unknown_lints, renamed_and_removed_lints, improper_ctypes_definitions)] // FIXME delete line once improper_c_fn_definitions exists upstream
56-
#[allow(improper_ctype_definitions)] // Boxed dyn is a fat pointer
5755
struct Exception {
5856
_uwe: uw::_Unwind_Exception,
5957
canary: *const u8,

library/proc_macro/src/bridge/client.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,6 @@ impl Client<(crate::TokenStream, crate::TokenStream), crate::TokenStream> {
358358

359359
#[repr(C)]
360360
#[derive(Copy, Clone)]
361-
#[allow(unknown_lints, renamed_and_removed_lints, improper_ctypes_definitions)] // FIXME delete line once improper_c_fn_definitions exists upstream
362-
#[allow(improper_ctype_definitions)] // so many C-incompatible double-width pointers
363361
pub enum ProcMacro {
364362
CustomDerive {
365363
trait_name: &'static str,

src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -461,15 +461,15 @@ pub const DEFAULT_LINTS: &[Lint] = &[
461461
deny_since: None,
462462
},
463463
Lint {
464-
label: "improper_ctypes",
465-
description: r##"proper use of libc types in foreign modules"##,
464+
label: "improper_c_var_definitions",
465+
description: r##"proper use of libc types when making static variables foreign-code-accessible"##,
466466
default_severity: Severity::Warning,
467467
warn_since: None,
468468
deny_since: None,
469469
},
470470
Lint {
471-
label: "improper_ctype_definitions",
472-
description: r##"proper use of libc types when defining foreign-code-compatible structs"##,
471+
label: "improper_ctypes",
472+
description: r##"proper use of libc types in foreign modules"##,
473473
default_severity: Severity::Warning,
474474
warn_since: None,
475475
deny_since: None,

tests/auxiliary/minicore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
asm_experimental_arch,
2828
unboxed_closures
2929
)]
30-
#![allow(unused, improper_ctype_definitions, internal_features)]
30+
#![allow(unused, internal_features)]
3131
#![no_std]
3232
#![no_core]
3333

tests/ui/abi/abi-sysv64-arg-passing.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
// the sysv64 ABI on Windows.
3434

3535
#[allow(dead_code)]
36-
#[allow(improper_ctypes, improper_ctype_definitions)]
36+
#[allow(improper_ctypes)]
3737

3838
#[cfg(target_arch = "x86_64")]
3939
mod tests {
@@ -72,7 +72,6 @@ mod tests {
7272
}
7373

7474
#[repr(C)]
75-
#[allow(improper_ctype_definitions)]
7675
pub struct Empty;
7776

7877
#[repr(C)]

tests/ui/abi/arm-unadjusted-intrinsic.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ pub struct int8x16_t(pub(crate) [i8; 16]);
2525
impl Copy for int8x16_t {}
2626

2727
#[repr(C)]
28-
#[allow(improper_ctype_definitions)]
2928
pub struct int8x16x4_t(pub int8x16_t, pub int8x16_t, pub int8x16_t, pub int8x16_t);
3029
impl Copy for int8x16x4_t {}
3130

0 commit comments

Comments
 (0)