@@ -104,9 +104,6 @@ enum CItemKind {
104
104
ExportedStatic ,
105
105
/// `extern "C"` function pointers -> IMPROPER_C_CALLBACKS,
106
106
Callback ,
107
- /// `repr(C)` structs/enums/unions -> IMPROPER_CTYPE_DEFINITIONS
108
- #[ allow( unused) ]
109
- AdtDef ,
110
107
}
111
108
112
109
#[ derive( Clone , Debug ) ]
@@ -446,8 +443,6 @@ enum CTypesVisitorState {
446
443
// uses bitflags from CTypesVisitorStateFlags
447
444
StaticTy = CTypesVisitorStateFlags :: STATIC ,
448
445
ExportedStaticTy = CTypesVisitorStateFlags :: STATIC | CTypesVisitorStateFlags :: FN_DEFINED ,
449
- #[ allow( unused) ]
450
- AdtDef = CTypesVisitorStateFlags :: THEORETICAL ,
451
446
ArgumentTyInDefinition = CTypesVisitorStateFlags :: FUNC | CTypesVisitorStateFlags :: FN_DEFINED ,
452
447
ReturnTyInDefinition = CTypesVisitorStateFlags :: FUNC
453
448
| CTypesVisitorStateFlags :: FN_RETURN
@@ -507,11 +502,6 @@ impl CTypesVisitorState {
507
502
( ( self as u8 ) & THEORETICAL ) != 0 && self . is_in_function ( )
508
503
}
509
504
510
- /// whether the type is currently being defined
511
- fn is_being_defined ( self ) -> bool {
512
- self == Self :: AdtDef
513
- }
514
-
515
505
/// whether we can expect type parameters and co in a given type
516
506
fn can_expect_ty_params ( self ) -> bool {
517
507
use CTypesVisitorStateFlags :: * ;
@@ -526,11 +516,7 @@ impl CTypesVisitorState {
526
516
/// whether the value for that type might come from the non-rust side of a FFI boundary
527
517
/// this is particularly useful for non-raw pointers, since rust assume they are non-null
528
518
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 ( ) {
534
520
// FIXME: this is evidently untrue for non-mut static variables
535
521
// (assuming the cross-FFI code respects this)
536
522
true
@@ -645,9 +631,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
645
631
outer_ty : Option < Ty < ' tcx > > ,
646
632
ty : Ty < ' tcx > ,
647
633
) -> 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 ( ..) ) )
651
636
{
652
637
FfiResult :: FfiSafe
653
638
} else {
@@ -842,7 +827,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
842
827
& self ,
843
828
state : CTypesVisitorState ,
844
829
ty : Ty < ' tcx > ,
845
- def : ty :: AdtDef < ' tcx > ,
830
+ def : AdtDef < ' tcx > ,
846
831
variant : & ty:: VariantDef ,
847
832
args : GenericArgsRef < ' tcx > ,
848
833
) -> FfiResult < ' tcx > {
@@ -996,9 +981,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
996
981
fn visit_struct_or_union (
997
982
& self ,
998
983
state : CTypesVisitorState ,
999
- outer_ty : Option < Ty < ' tcx > > ,
1000
984
ty : Ty < ' tcx > ,
1001
- def : ty :: AdtDef < ' tcx > ,
985
+ def : AdtDef < ' tcx > ,
1002
986
args : GenericArgsRef < ' tcx > ,
1003
987
) -> FfiResult < ' tcx > {
1004
988
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
@@ -1059,20 +1043,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1059
1043
// which is partly why we keep the details as to why that struct is FFI-unsafe)
1060
1044
// - if the struct is from another crate, then there's not much that can be done anyways
1061
1045
//
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,
1063
1047
// 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) )
1068
1049
}
1069
1050
1070
1051
fn visit_enum (
1071
1052
& self ,
1072
1053
state : CTypesVisitorState ,
1073
1054
outer_ty : Option < Ty < ' tcx > > ,
1074
1055
ty : Ty < ' tcx > ,
1075
- def : ty :: AdtDef < ' tcx > ,
1056
+ def : AdtDef < ' tcx > ,
1076
1057
args : GenericArgsRef < ' tcx > ,
1077
1058
) -> FfiResult < ' tcx > {
1078
1059
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Enum ) ) ;
@@ -1155,12 +1136,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1155
1136
ffires += variants_uninhabited_ffires. into_iter ( ) . reduce ( |r1, r2| r1 + r2) . unwrap ( ) ;
1156
1137
}
1157
1138
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,
1159
1140
// so we override the "cause type" of the lint
1160
1141
// (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) )
1164
1143
}
1165
1144
}
1166
1145
@@ -1205,7 +1184,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1205
1184
{
1206
1185
return self . visit_cstr ( outer_ty, ty) ;
1207
1186
}
1208
- self . visit_struct_or_union ( state, outer_ty , ty, def, args)
1187
+ self . visit_struct_or_union ( state, ty, def, args)
1209
1188
}
1210
1189
AdtKind :: Enum => self . visit_enum ( state, outer_ty, ty, def, args) ,
1211
1190
}
@@ -1272,7 +1251,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1272
1251
ty:: Slice ( inner_ty) => {
1273
1252
// ty::Slice is used for !Sized arrays, since they are the pointee for actual slices
1274
1253
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 ( ) ,
1276
1255
// this should have been caught a layer up, in visit_indirection
1277
1256
Some ( ty:: Ref ( ..) | ty:: RawPtr ( ..) ) => false ,
1278
1257
Some ( ty:: Adt ( ..) ) => ty. boxed_ty ( ) . is_none ( ) ,
@@ -1514,71 +1493,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1514
1493
}
1515
1494
}
1516
1495
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
-
1582
1496
fn check_arg_for_power_alignment ( & self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
1583
1497
let tcx = cx. tcx ;
1584
1498
assert ! ( tcx. sess. target. os == "aix" ) ;
@@ -1740,12 +1654,7 @@ impl ImproperCTypesLint {
1740
1654
}
1741
1655
1742
1656
/// 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 ) {
1749
1658
let ty = cx. tcx . type_of ( id) . instantiate_identity ( ) ;
1750
1659
let visitor = ImproperCTypesVisitor :: new ( cx) ;
1751
1660
let ffi_res = visitor. check_for_type ( CTypesVisitorState :: ExportedStaticTy , ty) ;
@@ -1861,15 +1770,13 @@ impl ImproperCTypesLint {
1861
1770
CItemKind :: ImportedExtern => IMPROPER_CTYPES ,
1862
1771
CItemKind :: ExportedFunction => IMPROPER_C_FN_DEFINITIONS ,
1863
1772
CItemKind :: ExportedStatic => IMPROPER_C_VAR_DEFINITIONS ,
1864
- CItemKind :: AdtDef => IMPROPER_CTYPE_DEFINITIONS ,
1865
1773
CItemKind :: Callback => IMPROPER_C_CALLBACKS ,
1866
1774
} ;
1867
1775
let desc = match fn_mode {
1868
1776
CItemKind :: ImportedExtern => "`extern` block" ,
1869
1777
CItemKind :: ExportedFunction => "`extern` fn" ,
1870
1778
CItemKind :: ExportedStatic => "foreign-code-reachable static" ,
1871
1779
CItemKind :: Callback => "`extern` callback" ,
1872
- CItemKind :: AdtDef => "`repr(C)` type" ,
1873
1780
} ;
1874
1781
for reason in reasons. iter_mut ( ) {
1875
1782
reason. span_note = if let ty:: Adt ( def, _) = reason. ty . kind ( )
@@ -1899,9 +1806,6 @@ impl ImproperCTypesLint {
1899
1806
/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
1900
1807
/// This only matters if `<abi>` is external (e.g. `C`).
1901
1808
///
1902
- /// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1903
- /// assuming they are to have a fully C-compatible layout.
1904
- ///
1905
1809
/// and now combinatorics for pointees
1906
1810
impl < ' tcx > LateLintPass < ' tcx > for ImproperCTypesLint {
1907
1811
fn check_foreign_item ( & mut self , cx : & LateContext < ' tcx > , it : & hir:: ForeignItem < ' tcx > ) {
@@ -2170,33 +2074,6 @@ declare_lint! {
2170
2074
"proper use of libc types in foreign-code-compatible callbacks"
2171
2075
}
2172
2076
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
-
2200
2077
declare_lint ! {
2201
2078
/// The `uses_power_alignment` lint detects specific `repr(C)`
2202
2079
/// aggregates on AIX.
@@ -2257,6 +2134,5 @@ declare_lint_pass!(ImproperCTypesLint => [
2257
2134
IMPROPER_C_FN_DEFINITIONS ,
2258
2135
IMPROPER_C_VAR_DEFINITIONS ,
2259
2136
IMPROPER_C_CALLBACKS ,
2260
- IMPROPER_CTYPE_DEFINITIONS ,
2261
2137
USES_POWER_ALIGNMENT ,
2262
2138
] ) ;
0 commit comments