@@ -105,9 +105,6 @@ enum CItemKind {
105105 ExportedStatic ,
106106 /// `extern "C"` function pointers -> IMPROPER_C_CALLBACKS,
107107 Callback ,
108- /// `repr(C)` structs/enums/unions -> IMPROPER_CTYPE_DEFINITIONS
109- #[ allow( unused) ]
110- AdtDef ,
111108}
112109
113110#[ derive( Clone , Debug ) ]
@@ -447,8 +444,6 @@ enum CTypesVisitorState {
447444 // uses bitflags from CTypesVisitorStateFlags
448445 StaticTy = CTypesVisitorStateFlags :: STATIC ,
449446 ExportedStaticTy = CTypesVisitorStateFlags :: STATIC | CTypesVisitorStateFlags :: FN_DEFINED ,
450- #[ allow( unused) ]
451- AdtDef = CTypesVisitorStateFlags :: THEORETICAL ,
452447 ArgumentTyInDefinition = CTypesVisitorStateFlags :: FUNC | CTypesVisitorStateFlags :: FN_DEFINED ,
453448 ReturnTyInDefinition = CTypesVisitorStateFlags :: FUNC
454449 | CTypesVisitorStateFlags :: FN_RETURN
@@ -508,11 +503,6 @@ impl CTypesVisitorState {
508503 ( ( self as u8 ) & THEORETICAL ) != 0 && self . is_in_function ( )
509504 }
510505
511- /// whether the type is currently being defined
512- fn is_being_defined ( self ) -> bool {
513- self == Self :: AdtDef
514- }
515-
516506 /// whether we can expect type parameters and co in a given type
517507 fn can_expect_ty_params ( self ) -> bool {
518508 use CTypesVisitorStateFlags :: * ;
@@ -527,11 +517,7 @@ impl CTypesVisitorState {
527517 /// whether the value for that type might come from the non-rust side of a FFI boundary
528518 /// this is particularly useful for non-raw pointers, since rust assume they are non-null
529519 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 ( ) {
535521 // FIXME: this is evidently untrue for non-mut static variables
536522 // (assuming the cross-FFI code respects this)
537523 true
@@ -646,9 +632,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
646632 outer_ty : Option < Ty < ' tcx > > ,
647633 ty : Ty < ' tcx > ,
648634 ) -> 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 ( ..) ) )
652637 {
653638 FfiResult :: FfiSafe
654639 } else {
@@ -846,7 +831,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
846831 & self ,
847832 state : CTypesVisitorState ,
848833 ty : Ty < ' tcx > ,
849- def : ty :: AdtDef < ' tcx > ,
834+ def : AdtDef < ' tcx > ,
850835 variant : & ty:: VariantDef ,
851836 args : GenericArgsRef < ' tcx > ,
852837 ) -> FfiResult < ' tcx > {
@@ -1000,9 +985,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1000985 fn visit_struct_or_union (
1001986 & self ,
1002987 state : CTypesVisitorState ,
1003- outer_ty : Option < Ty < ' tcx > > ,
1004988 ty : Ty < ' tcx > ,
1005- def : ty :: AdtDef < ' tcx > ,
989+ def : AdtDef < ' tcx > ,
1006990 args : GenericArgsRef < ' tcx > ,
1007991 ) -> FfiResult < ' tcx > {
1008992 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
@@ -1063,20 +1047,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10631047 // which is partly why we keep the details as to why that struct is FFI-unsafe)
10641048 // - if the struct is from another crate, then there's not much that can be done anyways
10651049 //
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,
10671051 // 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) )
10721053 }
10731054
10741055 fn visit_enum (
10751056 & self ,
10761057 state : CTypesVisitorState ,
10771058 outer_ty : Option < Ty < ' tcx > > ,
10781059 ty : Ty < ' tcx > ,
1079- def : ty :: AdtDef < ' tcx > ,
1060+ def : AdtDef < ' tcx > ,
10801061 args : GenericArgsRef < ' tcx > ,
10811062 ) -> FfiResult < ' tcx > {
10821063 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Enum ) ) ;
@@ -1163,12 +1144,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11631144 ffires += variants_uninhabited_ffires. into_iter ( ) . reduce ( |r1, r2| r1 + r2) . unwrap ( ) ;
11641145 }
11651146
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,
11671148 // so we override the "cause type" of the lint
11681149 // (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) )
11721151 }
11731152 }
11741153
@@ -1213,7 +1192,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12131192 {
12141193 return self . visit_cstr ( outer_ty, ty) ;
12151194 }
1216- self . visit_struct_or_union ( state, outer_ty , ty, def, args)
1195+ self . visit_struct_or_union ( state, ty, def, args)
12171196 }
12181197 AdtKind :: Enum => self . visit_enum ( state, outer_ty, ty, def, args) ,
12191198 }
@@ -1280,7 +1259,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12801259 ty:: Slice ( inner_ty) => {
12811260 // ty::Slice is used for !Sized arrays, since they are the pointee for actual slices
12821261 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 ( ) ,
12841263 // this should have been caught a layer up, in visit_indirection
12851264 Some ( ty:: Ref ( ..) | ty:: RawPtr ( ..) ) => false ,
12861265 Some ( ty:: Adt ( ..) ) => ty. boxed_ty ( ) . is_none ( ) ,
@@ -1522,71 +1501,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15221501 }
15231502 }
15241503
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-
15901504 fn check_arg_for_power_alignment ( & self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
15911505 let tcx = cx. tcx ;
15921506 assert ! ( tcx. sess. target. os == "aix" ) ;
@@ -1748,12 +1662,7 @@ impl ImproperCTypesLint {
17481662 }
17491663
17501664 /// 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 ) {
17571666 let ty = cx. tcx . type_of ( id) . instantiate_identity ( ) ;
17581667 let visitor = ImproperCTypesVisitor :: new ( cx) ;
17591668 let ffi_res = visitor. check_for_type ( CTypesVisitorState :: ExportedStaticTy , ty) ;
@@ -1869,15 +1778,13 @@ impl ImproperCTypesLint {
18691778 CItemKind :: ImportedExtern => IMPROPER_CTYPES ,
18701779 CItemKind :: ExportedFunction => IMPROPER_C_FN_DEFINITIONS ,
18711780 CItemKind :: ExportedStatic => IMPROPER_C_VAR_DEFINITIONS ,
1872- CItemKind :: AdtDef => IMPROPER_CTYPE_DEFINITIONS ,
18731781 CItemKind :: Callback => IMPROPER_C_CALLBACKS ,
18741782 } ;
18751783 let desc = match fn_mode {
18761784 CItemKind :: ImportedExtern => "`extern` block" ,
18771785 CItemKind :: ExportedFunction => "`extern` fn" ,
18781786 CItemKind :: ExportedStatic => "foreign-code-reachable static" ,
18791787 CItemKind :: Callback => "`extern` callback" ,
1880- CItemKind :: AdtDef => "`repr(C)` type" ,
18811788 } ;
18821789 for reason in reasons. iter_mut ( ) {
18831790 reason. span_note = if let ty:: Adt ( def, _) = reason. ty . kind ( )
@@ -1907,9 +1814,6 @@ impl ImproperCTypesLint {
19071814/// In other words, `extern "<abi>" fn` definitions and trait-method declarations.
19081815/// This only matters if `<abi>` is external (e.g. `C`).
19091816///
1910- /// `IMPROPER_CTYPE_DEFINITIONS` checks structs/enums/unions marked with `repr(C)`,
1911- /// assuming they are to have a fully C-compatible layout.
1912- ///
19131817/// and now combinatorics for pointees
19141818impl < ' tcx > LateLintPass < ' tcx > for ImproperCTypesLint {
19151819 fn check_foreign_item ( & mut self , cx : & LateContext < ' tcx > , it : & hir:: ForeignItem < ' tcx > ) {
@@ -2178,33 +2082,6 @@ declare_lint! {
21782082 "proper use of libc types in foreign-code-compatible callbacks"
21792083}
21802084
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-
22082085declare_lint ! {
22092086 /// The `uses_power_alignment` lint detects specific `repr(C)`
22102087 /// aggregates on AIX.
@@ -2265,6 +2142,5 @@ declare_lint_pass!(ImproperCTypesLint => [
22652142 IMPROPER_C_FN_DEFINITIONS ,
22662143 IMPROPER_C_VAR_DEFINITIONS ,
22672144 IMPROPER_C_CALLBACKS ,
2268- IMPROPER_CTYPE_DEFINITIONS ,
22692145 USES_POWER_ALIGNMENT ,
22702146] ) ;
0 commit comments