@@ -431,7 +431,6 @@ impl<'tcx> FfiResult<'tcx> {
431431 /// For instance, if we have a repr(C) struct in a function's argument, FFI unsafeties inside the struct
432432 /// are to be blamed on the struct and not the members.
433433 /// This is where we use this wrapper, to tell "all FFI-unsafeties in there are caused by this `ty`"
434- #[ expect( unused) ]
435434 fn with_overrides ( mut self , override_cause_ty : Option < Ty < ' tcx > > ) -> FfiResult < ' tcx > {
436435 use FfiResult :: * ;
437436
@@ -1024,7 +1023,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10241023 all_phantom &= match self . visit_type ( state. get_next ( ty) , field_ty) {
10251024 FfiSafe => false ,
10261025 FfiPhantom ( ..) => true ,
1027- r @ FfiUnsafe { .. } => return r,
1026+ r @ FfiUnsafe { .. } => {
1027+ return r. wrap_all ( ty, fluent:: lint_improper_ctypes_struct_dueto, None ) ;
1028+ }
10281029 }
10291030 }
10301031
@@ -1075,7 +1076,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10751076 ) ;
10761077 }
10771078
1078- if def. non_enum_variant ( ) . fields . is_empty ( ) {
1079+ let ffires = if def. non_enum_variant ( ) . fields . is_empty ( ) {
10791080 FfiResult :: new_with_reason (
10801081 ty,
10811082 if def. is_struct ( ) {
@@ -1091,7 +1092,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10911092 )
10921093 } else {
10931094 self . visit_variant_fields ( state, ty, def, def. non_enum_variant ( ) , args)
1094- }
1095+ } ;
1096+
1097+ // from now on in the function, we lint the actual insides of the struct/union: if something is wrong,
1098+ // then the "fault" comes from inside the struct itself.
1099+ // even if we add more details to the lint, the initial line must specify that the FFI-unsafety is because of the struct
1100+ // - if the struct is from the same crate, there is another warning on its definition anyway
1101+ // (unless it's about Boxes and references without Option<_>
1102+ // which is partly why we keep the details as to why that struct is FFI-unsafe)
1103+ // - if the struct is from another crate, then there's not much that can be done anyways
1104+ //
1105+ // this enum is visited in the middle of another lint,
1106+ // so we override the "cause type" of the lint
1107+ ffires. with_overrides ( Some ( ty) )
10951108 }
10961109
10971110 fn visit_enum (
@@ -1138,10 +1151,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11381151 }
11391152 } ) ;
11401153 if let ControlFlow :: Break ( result) = ret {
1141- return result;
1154+ // this enum is visited in the middle of another lint,
1155+ // so we override the "cause type" of the lint
1156+ // (for more detail, see comment in ``visit_struct_union`` before its call to ``result.with_overrides``)
1157+ result. with_overrides ( Some ( ty) )
1158+ } else {
1159+ FfiSafe
11421160 }
1143-
1144- FfiSafe
11451161 }
11461162
11471163 /// Checks if the given type is "ffi-safe" (has a stable, well-defined
0 commit comments