@@ -105,9 +105,6 @@ enum CItemKind {
105
105
ExportedStatic ,
106
106
/// `extern "C"` function pointers -> IMPROPER_C_CALLBACKS,
107
107
Callback ,
108
- /// `repr(C)` structs/enums/unions -> IMPROPER_CTYPE_DEFINITIONS
109
- #[ allow( unused) ]
110
- AdtDef ,
111
108
}
112
109
113
110
#[ derive( Clone , Debug ) ]
@@ -447,8 +444,6 @@ enum CTypesVisitorState {
447
444
// uses bitflags from CTypesVisitorStateFlags
448
445
StaticTy = CTypesVisitorStateFlags :: STATIC ,
449
446
ExportedStaticTy = CTypesVisitorStateFlags :: STATIC | CTypesVisitorStateFlags :: FN_DEFINED ,
450
- #[ allow( unused) ]
451
- AdtDef = CTypesVisitorStateFlags :: THEORETICAL ,
452
447
ArgumentTyInDefinition = CTypesVisitorStateFlags :: FUNC | CTypesVisitorStateFlags :: FN_DEFINED ,
453
448
ReturnTyInDefinition = CTypesVisitorStateFlags :: FUNC
454
449
| CTypesVisitorStateFlags :: FN_RETURN
@@ -508,11 +503,6 @@ impl CTypesVisitorState {
508
503
( ( self as u8 ) & THEORETICAL ) != 0 && self . is_in_function ( )
509
504
}
510
505
511
- /// whether the type is currently being defined
512
- fn is_being_defined ( self ) -> bool {
513
- self == Self :: AdtDef
514
- }
515
-
516
506
/// whether we can expect type parameters and co in a given type
517
507
fn can_expect_ty_params ( self ) -> bool {
518
508
use CTypesVisitorStateFlags :: * ;
@@ -527,11 +517,7 @@ impl CTypesVisitorState {
527
517
/// whether the value for that type might come from the non-rust side of a FFI boundary
528
518
/// this is particularly useful for non-raw pointers, since rust assume they are non-null
529
519
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 ( ) {
535
521
// FIXME: this is evidently untrue for non-mut static variables
536
522
// (assuming the cross-FFI code respects this)
537
523
true
@@ -646,9 +632,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
646
632
outer_ty : Option < Ty < ' tcx > > ,
647
633
ty : Ty < ' tcx > ,
648
634
) -> 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 ( ..) ) )
652
637
{
653
638
FfiResult :: FfiSafe
654
639
} else {
@@ -846,7 +831,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
846
831
& self ,
847
832
state : CTypesVisitorState ,
848
833
ty : Ty < ' tcx > ,
849
- def : ty :: AdtDef < ' tcx > ,
834
+ def : AdtDef < ' tcx > ,
850
835
variant : & ty:: VariantDef ,
851
836
args : GenericArgsRef < ' tcx > ,
852
837
) -> FfiResult < ' tcx > {
@@ -1000,9 +985,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1000
985
fn visit_struct_or_union (
1001
986
& self ,
1002
987
state : CTypesVisitorState ,
1003
- outer_ty : Option < Ty < ' tcx > > ,
1004
988
ty : Ty < ' tcx > ,
1005
- def : ty :: AdtDef < ' tcx > ,
989
+ def : AdtDef < ' tcx > ,
1006
990
args : GenericArgsRef < ' tcx > ,
1007
991
) -> FfiResult < ' tcx > {
1008
992
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
@@ -1063,20 +1047,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1063
1047
// which is partly why we keep the details as to why that struct is FFI-unsafe)
1064
1048
// - if the struct is from another crate, then there's not much that can be done anyways
1065
1049
//
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,
1067
1051
// 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) )
1072
1053
}
1073
1054
1074
1055
fn visit_enum (
1075
1056
& self ,
1076
1057
state : CTypesVisitorState ,
1077
1058
outer_ty : Option < Ty < ' tcx > > ,
1078
1059
ty : Ty < ' tcx > ,
1079
- def : ty :: AdtDef < ' tcx > ,
1060
+ def : AdtDef < ' tcx > ,
1080
1061
args : GenericArgsRef < ' tcx > ,
1081
1062
) -> FfiResult < ' tcx > {
1082
1063
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Enum ) ) ;
@@ -1163,12 +1144,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1163
1144
ffires += variants_uninhabited_ffires. into_iter ( ) . reduce ( |r1, r2| r1 + r2) . unwrap ( ) ;
1164
1145
}
1165
1146
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,
1167
1148
// so we override the "cause type" of the lint
1168
1149
// (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) )
1172
1151
}
1173
1152
}
1174
1153
@@ -1213,7 +1192,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1213
1192
{
1214
1193
return self . visit_cstr ( outer_ty, ty) ;
1215
1194
}
1216
- self . visit_struct_or_union ( state, outer_ty , ty, def, args)
1195
+ self . visit_struct_or_union ( state, ty, def, args)
1217
1196
}
1218
1197
AdtKind :: Enum => self . visit_enum ( state, outer_ty, ty, def, args) ,
1219
1198
}
@@ -1280,7 +1259,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1280
1259
ty:: Slice ( inner_ty) => {
1281
1260
// ty::Slice is used for !Sized arrays, since they are the pointee for actual slices
1282
1261
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 ( ) ,
1284
1263
// this should have been caught a layer up, in visit_indirection
1285
1264
Some ( ty:: Ref ( ..) | ty:: RawPtr ( ..) ) => false ,
1286
1265
Some ( ty:: Adt ( ..) ) => ty. boxed_ty ( ) . is_none ( ) ,
@@ -1522,71 +1501,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1522
1501
}
1523
1502
}
1524
1503
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
-
1590
1504
fn check_arg_for_power_alignment ( & self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
1591
1505
let tcx = cx. tcx ;
1592
1506
assert ! ( tcx. sess. target. os == "aix" ) ;
@@ -1748,12 +1662,7 @@ impl ImproperCTypesLint {
1748
1662
}
1749
1663
1750
1664
/// 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 ) {
1757
1666
let ty = cx. tcx . type_of ( id) . instantiate_identity ( ) ;
1758
1667
let visitor = ImproperCTypesVisitor :: new ( cx) ;
1759
1668
let ffi_res = visitor. check_for_type ( CTypesVisitorState :: ExportedStaticTy , ty) ;
@@ -1869,15 +1778,13 @@ impl ImproperCTypesLint {
1869
1778
CItemKind :: ImportedExtern => IMPROPER_CTYPES ,
1870
1779
CItemKind :: ExportedFunction => IMPROPER_C_FN_DEFINITIONS ,
1871
1780
CItemKind :: ExportedStatic => IMPROPER_C_VAR_DEFINITIONS ,
1872
- CItemKind :: AdtDef => IMPROPER_CTYPE_DEFINITIONS ,
1873
1781
CItemKind :: Callback => IMPROPER_C_CALLBACKS ,
1874
1782
} ;
1875
1783
let desc = match fn_mode {
1876
1784
CItemKind :: ImportedExtern => "`extern` block" ,
1877
1785
CItemKind :: ExportedFunction => "`extern` fn" ,
1878
1786
CItemKind :: ExportedStatic => "foreign-code-reachable static" ,
1879
1787
CItemKind :: Callback => "`extern` callback" ,
1880
- CItemKind :: AdtDef => "`repr(C)` type" ,
1881
1788
} ;
1882
1789
for reason in reasons. iter_mut ( ) {
1883
1790
reason. span_note = if let ty:: Adt ( def, _) = reason. ty . kind ( )
@@ -1907,9 +1814,6 @@ impl ImproperCTypesLint {
1907
1814
/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
1908
1815
/// This only matters if `<abi>` is external (e.g. `C`).
1909
1816
///
1910
- /// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1911
- /// assuming they are to have a fully C-compatible layout.
1912
- ///
1913
1817
/// and now combinatorics for pointees
1914
1818
impl < ' tcx > LateLintPass < ' tcx > for ImproperCTypesLint {
1915
1819
fn check_foreign_item ( & mut self , cx : & LateContext < ' tcx > , it : & hir:: ForeignItem < ' tcx > ) {
@@ -2178,33 +2082,6 @@ declare_lint! {
2178
2082
"proper use of libc types in foreign-code-compatible callbacks"
2179
2083
}
2180
2084
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
-
2208
2085
declare_lint ! {
2209
2086
/// The `uses_power_alignment` lint detects specific `repr(C)`
2210
2087
/// aggregates on AIX.
@@ -2265,6 +2142,5 @@ declare_lint_pass!(ImproperCTypesLint => [
2265
2142
IMPROPER_C_FN_DEFINITIONS ,
2266
2143
IMPROPER_C_VAR_DEFINITIONS ,
2267
2144
IMPROPER_C_CALLBACKS ,
2268
- IMPROPER_CTYPE_DEFINITIONS ,
2269
2145
USES_POWER_ALIGNMENT ,
2270
2146
] ) ;
0 commit comments