@@ -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
@@ -614,9 +600,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
614
600
outer_ty : Option < Ty < ' tcx > > ,
615
601
ty : Ty < ' tcx > ,
616
602
) -> FfiResult < ' tcx > {
617
- if state. is_being_defined ( )
618
- || ( state. is_in_function_return ( )
619
- && matches ! ( outer_ty. map( |ty| ty. kind( ) ) , None | Some ( ty:: FnPtr ( ..) ) , ) )
603
+ if state. is_in_function_return ( )
604
+ && matches ! ( outer_ty. map( |ty| ty. kind( ) ) , None | Some ( ty:: FnPtr ( ..) ) )
620
605
{
621
606
FfiResult :: FfiSafe
622
607
} else {
@@ -814,7 +799,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
814
799
& mut self ,
815
800
state : CTypesVisitorState ,
816
801
ty : Ty < ' tcx > ,
817
- def : ty :: AdtDef < ' tcx > ,
802
+ def : AdtDef < ' tcx > ,
818
803
variant : & ty:: VariantDef ,
819
804
args : GenericArgsRef < ' tcx > ,
820
805
) -> FfiResult < ' tcx > {
@@ -968,9 +953,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
968
953
fn visit_struct_or_union (
969
954
& mut self ,
970
955
state : CTypesVisitorState ,
971
- outer_ty : Option < Ty < ' tcx > > ,
972
956
ty : Ty < ' tcx > ,
973
- def : ty :: AdtDef < ' tcx > ,
957
+ def : AdtDef < ' tcx > ,
974
958
args : GenericArgsRef < ' tcx > ,
975
959
) -> FfiResult < ' tcx > {
976
960
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
@@ -1031,20 +1015,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1031
1015
// which is partly why we keep the details as to why that struct is FFI-unsafe)
1032
1016
// - if the struct is from another crate, then there's not much that can be done anyways
1033
1017
//
1034
- // if outer_ty.is_some() || !state.is_being_defined() then this enum is visited in the middle of another lint,
1018
+ // this enum is visited in the middle of another lint,
1035
1019
// so we override the "cause type" of the lint
1036
- let override_cause_ty =
1037
- if state. is_being_defined ( ) { outer_ty. and ( Some ( ty) ) } else { Some ( ty) } ;
1038
-
1039
- ffires. with_overrides ( override_cause_ty)
1020
+ ffires. with_overrides ( Some ( ty) )
1040
1021
}
1041
1022
1042
1023
fn visit_enum (
1043
1024
& mut self ,
1044
1025
state : CTypesVisitorState ,
1045
1026
outer_ty : Option < Ty < ' tcx > > ,
1046
1027
ty : Ty < ' tcx > ,
1047
- def : ty :: AdtDef < ' tcx > ,
1028
+ def : AdtDef < ' tcx > ,
1048
1029
args : GenericArgsRef < ' tcx > ,
1049
1030
) -> FfiResult < ' tcx > {
1050
1031
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Enum ) ) ;
@@ -1131,12 +1112,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1131
1112
ffires += variants_uninhabited_ffires. into_iter ( ) . reduce ( |r1, r2| r1 + r2) . unwrap ( ) ;
1132
1113
}
1133
1114
1134
- // if outer_ty.is_some() || !state.is_being_defined() then this enum is visited in the middle of another lint,
1115
+ // this enum is visited in the middle of another lint,
1135
1116
// so we override the "cause type" of the lint
1136
1117
// (for more detail, see comment in ``visit_struct_union`` before its call to ``ffires.with_overrides``)
1137
- let override_cause_ty =
1138
- if state. is_being_defined ( ) { outer_ty. and ( Some ( ty) ) } else { Some ( ty) } ;
1139
- ffires. with_overrides ( override_cause_ty)
1118
+ ffires. with_overrides ( Some ( ty) )
1140
1119
}
1141
1120
}
1142
1121
@@ -1185,7 +1164,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1185
1164
{
1186
1165
return self . visit_cstr ( outer_ty, ty) ;
1187
1166
}
1188
- self . visit_struct_or_union ( state, outer_ty , ty, def, args)
1167
+ self . visit_struct_or_union ( state, ty, def, args)
1189
1168
}
1190
1169
AdtKind :: Enum => self . visit_enum ( state, outer_ty, ty, def, args) ,
1191
1170
}
@@ -1475,71 +1454,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1475
1454
}
1476
1455
}
1477
1456
1478
- #[ allow( unused) ]
1479
- fn check_for_adtdef ( & mut self , ty : Ty < ' tcx > ) -> FfiResult < ' tcx > {
1480
- use FfiResult :: * ;
1481
- let ty = erase_and_maybe_normalize ( self . cx , ty) ;
1482
-
1483
- let mut ffires = match * ty. kind ( ) {
1484
- ty:: Adt ( def, args) => {
1485
- if !def. did ( ) . is_local ( ) {
1486
- bug ! (
1487
- "check_adtdef expected to visit a locally-defined struct/enum/union not {:?}" ,
1488
- def
1489
- ) ;
1490
- }
1491
-
1492
- // question: how does this behave when running for "special" ADTs in the stdlib?
1493
- // answer: none of CStr, CString, Box, and PhantomData are repr(C)
1494
- let state = CTypesVisitorState :: AdtDef ;
1495
- match def. adt_kind ( ) {
1496
- AdtKind :: Struct | AdtKind :: Union => {
1497
- self . visit_struct_or_union ( state, None , ty, def, args)
1498
- }
1499
- AdtKind :: Enum => self . visit_enum ( state, None , ty, def, args) ,
1500
- }
1501
- }
1502
- r @ _ => {
1503
- bug ! ( "expected to inspect the type of an `extern \" ABI\" ` FnPtr, not {:?}" , r, )
1504
- }
1505
- } ;
1506
-
1507
- match & mut ffires {
1508
- // due to the way type visits work, any unsafeness that comes from the fields inside an ADT
1509
- // is uselessly "prefixed" with the fact that yes, the error occurs in that ADT
1510
- // we remove the prefixes here.
1511
- FfiUnsafe ( explanations) => {
1512
- explanations. iter_mut ( ) . for_each ( |explanation| {
1513
- if let Some ( inner_reason) = explanation. reason . inner . take ( ) {
1514
- debug_assert_eq ! ( explanation. reason. ty, ty) ;
1515
- debug_assert_eq ! (
1516
- explanation. reason. note,
1517
- fluent:: lint_improper_ctypes_struct_dueto
1518
- ) ;
1519
- if let Some ( help) = & explanation. reason . help {
1520
- // there is an actual help message in the normally useless prefix
1521
- // make sure it gets through
1522
- debug_assert_eq ! (
1523
- help,
1524
- & fluent:: lint_improper_ctypes_struct_consider_transparent
1525
- ) ;
1526
- explanation. override_cause_ty = Some ( inner_reason. ty ) ;
1527
- explanation. reason . inner = Some ( inner_reason) ;
1528
- } else {
1529
- explanation. reason = inner_reason;
1530
- }
1531
- }
1532
- } ) ;
1533
- }
1534
-
1535
- // also, turn FfiPhantom into FfiSafe: unlike other places we can check, we don't want
1536
- // FfiPhantom to end up emitting a lint
1537
- ffires @ FfiPhantom ( _) => * ffires = FfiSafe ,
1538
- FfiSafe => { }
1539
- }
1540
- ffires
1541
- }
1542
-
1543
1457
fn check_arg_for_power_alignment ( & self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
1544
1458
let tcx = cx. tcx ;
1545
1459
assert ! ( tcx. sess. target. os == "aix" ) ;
@@ -1822,15 +1736,13 @@ impl ImproperCTypesLint {
1822
1736
CItemKind :: ImportedExtern => IMPROPER_CTYPES ,
1823
1737
CItemKind :: ExportedFunction => IMPROPER_C_FN_DEFINITIONS ,
1824
1738
CItemKind :: ExportedStatic => IMPROPER_C_VAR_DEFINITIONS ,
1825
- CItemKind :: AdtDef => IMPROPER_CTYPE_DEFINITIONS ,
1826
1739
CItemKind :: Callback => IMPROPER_C_CALLBACKS ,
1827
1740
} ;
1828
1741
let desc = match fn_mode {
1829
1742
CItemKind :: ImportedExtern => "`extern` block" ,
1830
1743
CItemKind :: ExportedFunction => "`extern` fn" ,
1831
1744
CItemKind :: ExportedStatic => "foreign-code-reachable static" ,
1832
1745
CItemKind :: Callback => "`extern` callback" ,
1833
- CItemKind :: AdtDef => "`repr(C)` type" ,
1834
1746
} ;
1835
1747
for reason in reasons. iter_mut ( ) {
1836
1748
reason. span_note = if let ty:: Adt ( def, _) = reason. ty . kind ( )
@@ -1860,9 +1772,6 @@ impl ImproperCTypesLint {
1860
1772
/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
1861
1773
/// This only matters if `<abi>` is external (e.g. `C`).
1862
1774
///
1863
- /// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1864
- /// assuming they are to have a fully C-compatible layout.
1865
- ///
1866
1775
/// and now combinatorics for pointees
1867
1776
impl < ' tcx > LateLintPass < ' tcx > for ImproperCTypesLint {
1868
1777
fn check_foreign_item ( & mut self , cx : & LateContext < ' tcx > , it : & hir:: ForeignItem < ' tcx > ) {
@@ -2131,33 +2040,6 @@ declare_lint! {
2131
2040
"proper use of libc types in foreign-code-compatible callbacks"
2132
2041
}
2133
2042
2134
- declare_lint ! {
2135
- /// The `improper_ctype_definitions` lint detects incorrect use of types in
2136
- /// foreign-compatible structs, enums, and union definitions.
2137
- ///
2138
- /// ### Example
2139
- ///
2140
- /// ```rust
2141
- /// repr(C) struct StringWrapper{
2142
- /// length: usize,
2143
- /// strung: &str,
2144
- /// }
2145
- /// ```
2146
- ///
2147
- /// {{produces}}
2148
- ///
2149
- /// ### Explanation
2150
- ///
2151
- /// The compiler has several checks to verify that types designed to be
2152
- /// compatible with foreign interfaces follow certain rules to be safe.
2153
- /// This lint is issued when it detects a probable mistake in a definition.
2154
- /// The lint usually should provide a description of the issue,
2155
- /// along with possibly a hint on how to resolve it.
2156
- pub ( crate ) IMPROPER_CTYPE_DEFINITIONS ,
2157
- Warn ,
2158
- "proper use of libc types when defining foreign-code-compatible structs"
2159
- }
2160
-
2161
2043
declare_lint ! {
2162
2044
/// The `uses_power_alignment` lint detects specific `repr(C)`
2163
2045
/// aggregates on AIX.
@@ -2218,6 +2100,5 @@ declare_lint_pass!(ImproperCTypesLint => [
2218
2100
IMPROPER_C_FN_DEFINITIONS ,
2219
2101
IMPROPER_C_VAR_DEFINITIONS ,
2220
2102
IMPROPER_C_CALLBACKS ,
2221
- IMPROPER_CTYPE_DEFINITIONS ,
2222
2103
USES_POWER_ALIGNMENT ,
2223
2104
] ) ;
0 commit comments