Skip to content

Commit 9dedb0c

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 1e52d90 commit 9dedb0c

File tree

63 files changed

+171
-716
lines changed

Some content is hidden

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

63 files changed

+171
-716
lines changed

compiler/rustc_lint/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,6 @@ fn register_builtins(store: &mut LintStore) {
341341
IMPROPER_C_CALLBACKS,
342342
IMPROPER_C_FN_DEFINITIONS,
343343
IMPROPER_C_VAR_DEFINITIONS,
344-
IMPROPER_CTYPE_DEFINITIONS,
345344
IMPROPER_CTYPES
346345
);
347346

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
@@ -104,9 +104,6 @@ enum CItemKind {
104104
ExportedStatic,
105105
/// `extern "C"` function pointers -> IMPROPER_C_CALLBACKS,
106106
Callback,
107-
/// `repr(C)` structs/enums/unions -> IMPROPER_CTYPE_DEFINITIONS
108-
#[allow(unused)]
109-
AdtDef,
110107
}
111108

112109
#[derive(Clone, Debug)]
@@ -446,8 +443,6 @@ enum CTypesVisitorState {
446443
// uses bitflags from CTypesVisitorStateFlags
447444
StaticTy = CTypesVisitorStateFlags::STATIC,
448445
ExportedStaticTy = CTypesVisitorStateFlags::STATIC | CTypesVisitorStateFlags::FN_DEFINED,
449-
#[allow(unused)]
450-
AdtDef = CTypesVisitorStateFlags::THEORETICAL,
451446
ArgumentTyInDefinition = CTypesVisitorStateFlags::FUNC | CTypesVisitorStateFlags::FN_DEFINED,
452447
ReturnTyInDefinition = CTypesVisitorStateFlags::FUNC
453448
| CTypesVisitorStateFlags::FN_RETURN
@@ -507,11 +502,6 @@ impl CTypesVisitorState {
507502
((self as u8) & THEORETICAL) != 0 && self.is_in_function()
508503
}
509504

510-
/// whether the type is currently being defined
511-
fn is_being_defined(self) -> bool {
512-
self == Self::AdtDef
513-
}
514-
515505
/// whether we can expect type parameters and co in a given type
516506
fn can_expect_ty_params(self) -> bool {
517507
use CTypesVisitorStateFlags::*;
@@ -526,11 +516,7 @@ impl CTypesVisitorState {
526516
/// whether the value for that type might come from the non-rust side of a FFI boundary
527517
/// this is particularly useful for non-raw pointers, since rust assume they are non-null
528518
fn value_may_be_unchecked(self) -> bool {
529-
if self == Self::AdtDef {
530-
// some ADTs are only used to go through the FFI boundary in one direction,
531-
// so let's not make hasty judgement
532-
false
533-
} else if self.is_in_static() {
519+
if self.is_in_static() {
534520
// FIXME: this is evidently untrue for non-mut static variables
535521
// (assuming the cross-FFI code respects this)
536522
true
@@ -645,9 +631,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
645631
outer_ty: Option<Ty<'tcx>>,
646632
ty: Ty<'tcx>,
647633
) -> FfiResult<'tcx> {
648-
if state.is_being_defined()
649-
|| (state.is_in_function_return()
650-
&& matches!(outer_ty.map(|ty| ty.kind()), None | Some(ty::FnPtr(..)),))
634+
if state.is_in_function_return()
635+
&& matches!(outer_ty.map(|ty| ty.kind()), None | Some(ty::FnPtr(..)))
651636
{
652637
FfiResult::FfiSafe
653638
} else {
@@ -842,7 +827,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
842827
&self,
843828
state: CTypesVisitorState,
844829
ty: Ty<'tcx>,
845-
def: ty::AdtDef<'tcx>,
830+
def: AdtDef<'tcx>,
846831
variant: &ty::VariantDef,
847832
args: GenericArgsRef<'tcx>,
848833
) -> FfiResult<'tcx> {
@@ -996,9 +981,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
996981
fn visit_struct_or_union(
997982
&self,
998983
state: CTypesVisitorState,
999-
outer_ty: Option<Ty<'tcx>>,
1000984
ty: Ty<'tcx>,
1001-
def: ty::AdtDef<'tcx>,
985+
def: AdtDef<'tcx>,
1002986
args: GenericArgsRef<'tcx>,
1003987
) -> FfiResult<'tcx> {
1004988
debug_assert!(matches!(def.adt_kind(), AdtKind::Struct | AdtKind::Union));
@@ -1059,20 +1043,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10591043
// which is partly why we keep the details as to why that struct is FFI-unsafe)
10601044
// - if the struct is from another crate, then there's not much that can be done anyways
10611045
//
1062-
// if outer_ty.is_some() || !state.is_being_defined() then this enum is visited in the middle of another lint,
1046+
// this enum is visited in the middle of another lint,
10631047
// so we override the "cause type" of the lint
1064-
let override_cause_ty =
1065-
if state.is_being_defined() { outer_ty.and(Some(ty)) } else { Some(ty) };
1066-
1067-
ffires.with_overrides(override_cause_ty)
1048+
ffires.with_overrides(Some(ty))
10681049
}
10691050

10701051
fn visit_enum(
10711052
&self,
10721053
state: CTypesVisitorState,
10731054
outer_ty: Option<Ty<'tcx>>,
10741055
ty: Ty<'tcx>,
1075-
def: ty::AdtDef<'tcx>,
1056+
def: AdtDef<'tcx>,
10761057
args: GenericArgsRef<'tcx>,
10771058
) -> FfiResult<'tcx> {
10781059
debug_assert!(matches!(def.adt_kind(), AdtKind::Enum));
@@ -1155,12 +1136,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11551136
ffires += variants_uninhabited_ffires.into_iter().reduce(|r1, r2| r1 + r2).unwrap();
11561137
}
11571138

1158-
// if outer_ty.is_some() || !state.is_being_defined() then this enum is visited in the middle of another lint,
1139+
// this enum is visited in the middle of another lint,
11591140
// so we override the "cause type" of the lint
11601141
// (for more detail, see comment in ``visit_struct_union`` before its call to ``ffires.with_overrides``)
1161-
let override_cause_ty =
1162-
if state.is_being_defined() { outer_ty.and(Some(ty)) } else { Some(ty) };
1163-
ffires.with_overrides(override_cause_ty)
1142+
ffires.with_overrides(Some(ty))
11641143
}
11651144
}
11661145

@@ -1205,7 +1184,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12051184
{
12061185
return self.visit_cstr(outer_ty, ty);
12071186
}
1208-
self.visit_struct_or_union(state, outer_ty, ty, def, args)
1187+
self.visit_struct_or_union(state, ty, def, args)
12091188
}
12101189
AdtKind::Enum => self.visit_enum(state, outer_ty, ty, def, args),
12111190
}
@@ -1272,7 +1251,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12721251
ty::Slice(inner_ty) => {
12731252
// ty::Slice is used for !Sized arrays, since they are the pointee for actual slices
12741253
let slice_is_actually_array = match outer_ty.map(|ty| ty.kind()) {
1275-
None => state.is_in_static() || state.is_being_defined(),
1254+
None => state.is_in_static(),
12761255
// this should have been caught a layer up, in visit_indirection
12771256
Some(ty::Ref(..) | ty::RawPtr(..)) => false,
12781257
Some(ty::Adt(..)) => ty.boxed_ty().is_none(),
@@ -1514,71 +1493,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15141493
}
15151494
}
15161495

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

17421656
/// Check that a `#[no_mangle]`/`#[export_name = _]` static variable is of a ffi-safe type
1743-
fn check_exported_static<'tcx>(
1744-
&self,
1745-
cx: &LateContext<'tcx>,
1746-
id: hir::OwnerId,
1747-
span: Span,
1748-
) {
1657+
fn check_exported_static<'tcx>(&self, cx: &LateContext<'tcx>, id: hir::OwnerId, span: Span) {
17491658
let ty = cx.tcx.type_of(id).instantiate_identity();
17501659
let visitor = ImproperCTypesVisitor::new(cx);
17511660
let ffi_res = visitor.check_for_type(CTypesVisitorState::ExportedStaticTy, ty);
@@ -1861,15 +1770,13 @@ impl ImproperCTypesLint {
18611770
CItemKind::ImportedExtern => IMPROPER_CTYPES,
18621771
CItemKind::ExportedFunction => IMPROPER_C_FN_DEFINITIONS,
18631772
CItemKind::ExportedStatic => IMPROPER_C_VAR_DEFINITIONS,
1864-
CItemKind::AdtDef => IMPROPER_CTYPE_DEFINITIONS,
18651773
CItemKind::Callback => IMPROPER_C_CALLBACKS,
18661774
};
18671775
let desc = match fn_mode {
18681776
CItemKind::ImportedExtern => "`extern` block",
18691777
CItemKind::ExportedFunction => "`extern` fn",
18701778
CItemKind::ExportedStatic => "foreign-code-reachable static",
18711779
CItemKind::Callback => "`extern` callback",
1872-
CItemKind::AdtDef => "`repr(C)` type",
18731780
};
18741781
for reason in reasons.iter_mut() {
18751782
reason.span_note = if let ty::Adt(def, _) = reason.ty.kind()
@@ -1899,9 +1806,6 @@ impl ImproperCTypesLint {
18991806
/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
19001807
/// This only matters if `<abi>` is external (e.g. `C`).
19011808
///
1902-
/// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1903-
/// assuming they are to have a fully C-compatible layout.
1904-
///
19051809
/// and now combinatorics for pointees
19061810
impl<'tcx> LateLintPass<'tcx> for ImproperCTypesLint {
19071811
fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) {
@@ -2170,33 +2074,6 @@ declare_lint! {
21702074
"proper use of libc types in foreign-code-compatible callbacks"
21712075
}
21722076

2173-
declare_lint! {
2174-
/// The `improper_ctype_definitions` lint detects incorrect use of types in
2175-
/// foreign-compatible structs, enums, and union definitions.
2176-
///
2177-
/// ### Example
2178-
///
2179-
/// ```rust
2180-
/// repr(C) struct StringWrapper{
2181-
/// length: usize,
2182-
/// strung: &str,
2183-
/// }
2184-
/// ```
2185-
///
2186-
/// {{produces}}
2187-
///
2188-
/// ### Explanation
2189-
///
2190-
/// The compiler has several checks to verify that types designed to be
2191-
/// compatible with foreign interfaces follow certain rules to be safe.
2192-
/// This lint is issued when it detects a probable mistake in a definition.
2193-
/// The lint usually should provide a description of the issue,
2194-
/// along with possibly a hint on how to resolve it.
2195-
pub(crate) IMPROPER_CTYPE_DEFINITIONS,
2196-
Warn,
2197-
"proper use of libc types when defining foreign-code-compatible structs"
2198-
}
2199-
22002077
declare_lint! {
22012078
/// The `uses_power_alignment` lint detects specific `repr(C)`
22022079
/// aggregates on AIX.
@@ -2257,6 +2134,5 @@ declare_lint_pass!(ImproperCTypesLint => [
22572134
IMPROPER_C_FN_DEFINITIONS,
22582135
IMPROPER_C_VAR_DEFINITIONS,
22592136
IMPROPER_C_CALLBACKS,
2260-
IMPROPER_CTYPE_DEFINITIONS,
22612137
USES_POWER_ALIGNMENT,
22622138
]);

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
@@ -643,7 +643,6 @@ fn offset_of_dst() {
643643
trait Trait {}
644644

645645
#[repr(C)]
646-
#[allow(improper_ctype_definitions)]
647646
struct Beta {
648647
x: u8,
649648
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
@@ -29,7 +29,7 @@
2929
asm_experimental_arch,
3030
unboxed_closures
3131
)]
32-
#![allow(unused, improper_ctype_definitions, internal_features)]
32+
#![allow(unused, internal_features)]
3333
#![no_std]
3434
#![no_core]
3535

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)]

0 commit comments

Comments
 (0)