@@ -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
@@ -614,9 +600,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
614600 outer_ty : Option < Ty < ' tcx > > ,
615601 ty : Ty < ' tcx > ,
616602 ) -> 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 ( ..) ) )
620605 {
621606 FfiResult :: FfiSafe
622607 } else {
@@ -814,7 +799,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
814799 & mut self ,
815800 state : CTypesVisitorState ,
816801 ty : Ty < ' tcx > ,
817- def : ty :: AdtDef < ' tcx > ,
802+ def : AdtDef < ' tcx > ,
818803 variant : & ty:: VariantDef ,
819804 args : GenericArgsRef < ' tcx > ,
820805 ) -> FfiResult < ' tcx > {
@@ -968,9 +953,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
968953 fn visit_struct_or_union (
969954 & mut self ,
970955 state : CTypesVisitorState ,
971- outer_ty : Option < Ty < ' tcx > > ,
972956 ty : Ty < ' tcx > ,
973- def : ty :: AdtDef < ' tcx > ,
957+ def : AdtDef < ' tcx > ,
974958 args : GenericArgsRef < ' tcx > ,
975959 ) -> FfiResult < ' tcx > {
976960 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
@@ -1031,20 +1015,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10311015 // which is partly why we keep the details as to why that struct is FFI-unsafe)
10321016 // - if the struct is from another crate, then there's not much that can be done anyways
10331017 //
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,
10351019 // 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) )
10401021 }
10411022
10421023 fn visit_enum (
10431024 & mut self ,
10441025 state : CTypesVisitorState ,
10451026 outer_ty : Option < Ty < ' tcx > > ,
10461027 ty : Ty < ' tcx > ,
1047- def : ty :: AdtDef < ' tcx > ,
1028+ def : AdtDef < ' tcx > ,
10481029 args : GenericArgsRef < ' tcx > ,
10491030 ) -> FfiResult < ' tcx > {
10501031 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Enum ) ) ;
@@ -1131,12 +1112,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11311112 ffires += variants_uninhabited_ffires. into_iter ( ) . reduce ( |r1, r2| r1 + r2) . unwrap ( ) ;
11321113 }
11331114
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,
11351116 // so we override the "cause type" of the lint
11361117 // (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) )
11401119 }
11411120 }
11421121
@@ -1185,7 +1164,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11851164 {
11861165 return self . visit_cstr ( outer_ty, ty) ;
11871166 }
1188- self . visit_struct_or_union ( state, outer_ty , ty, def, args)
1167+ self . visit_struct_or_union ( state, ty, def, args)
11891168 }
11901169 AdtKind :: Enum => self . visit_enum ( state, outer_ty, ty, def, args) ,
11911170 }
@@ -1475,71 +1454,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
14751454 }
14761455 }
14771456
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-
15431457 fn check_arg_for_power_alignment ( & self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
15441458 let tcx = cx. tcx ;
15451459 assert ! ( tcx. sess. target. os == "aix" ) ;
@@ -1822,15 +1736,13 @@ impl ImproperCTypesLint {
18221736 CItemKind :: ImportedExtern => IMPROPER_CTYPES ,
18231737 CItemKind :: ExportedFunction => IMPROPER_C_FN_DEFINITIONS ,
18241738 CItemKind :: ExportedStatic => IMPROPER_C_VAR_DEFINITIONS ,
1825- CItemKind :: AdtDef => IMPROPER_CTYPE_DEFINITIONS ,
18261739 CItemKind :: Callback => IMPROPER_C_CALLBACKS ,
18271740 } ;
18281741 let desc = match fn_mode {
18291742 CItemKind :: ImportedExtern => "`extern` block" ,
18301743 CItemKind :: ExportedFunction => "`extern` fn" ,
18311744 CItemKind :: ExportedStatic => "foreign-code-reachable static" ,
18321745 CItemKind :: Callback => "`extern` callback" ,
1833- CItemKind :: AdtDef => "`repr(C)` type" ,
18341746 } ;
18351747 for reason in reasons. iter_mut ( ) {
18361748 reason. span_note = if let ty:: Adt ( def, _) = reason. ty . kind ( )
@@ -1860,9 +1772,6 @@ impl ImproperCTypesLint {
18601772/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
18611773/// This only matters if `<abi>` is external (e.g. `C`).
18621774///
1863- /// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1864- /// assuming they are to have a fully C-compatible layout.
1865- ///
18661775/// and now combinatorics for pointees
18671776impl < ' tcx > LateLintPass < ' tcx > for ImproperCTypesLint {
18681777 fn check_foreign_item ( & mut self , cx : & LateContext < ' tcx > , it : & hir:: ForeignItem < ' tcx > ) {
@@ -2131,33 +2040,6 @@ declare_lint! {
21312040 "proper use of libc types in foreign-code-compatible callbacks"
21322041}
21332042
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-
21612043declare_lint ! {
21622044 /// The `uses_power_alignment` lint detects specific `repr(C)`
21632045 /// aggregates on AIX.
@@ -2218,6 +2100,5 @@ declare_lint_pass!(ImproperCTypesLint => [
22182100 IMPROPER_C_FN_DEFINITIONS ,
22192101 IMPROPER_C_VAR_DEFINITIONS ,
22202102 IMPROPER_C_CALLBACKS ,
2221- IMPROPER_CTYPE_DEFINITIONS ,
22222103 USES_POWER_ALIGNMENT ,
22232104] ) ;
0 commit comments