@@ -215,7 +215,6 @@ impl<'tcx> FfiResult<'tcx> {
215215 /// For instance, if we have a repr(C) struct in a function's argument, FFI unsafeties inside the struct
216216 /// are to be blamed on the struct and not the members.
217217 /// This is where we use this wrapper, to tell "all FFI-unsafeties in there are caused by this `ty`"
218- #[ expect( unused) ]
219218 fn with_overrides ( mut self , override_cause_ty : Option < Ty < ' tcx > > ) -> FfiResult < ' tcx > {
220219 use FfiResult :: * ;
221220
@@ -737,7 +736,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
737736 // `()` fields are FFI-safe!
738737 //FfiUnsafe { ty, .. } if ty.is_unit() => false, // TODO get back here
739738 FfiPhantom ( ..) => true ,
740- r @ FfiUnsafe { .. } => return r,
739+ r @ FfiUnsafe { .. } => {
740+ return r. wrap_all (
741+ ty,
742+ fluent:: lint_improper_ctypes_struct_dueto,
743+ None ,
744+ ) ;
745+ }
741746 }
742747 }
743748
@@ -788,7 +793,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
788793 ) ;
789794 }
790795
791- if def. non_enum_variant ( ) . fields . is_empty ( ) {
796+ let ffires = if def. non_enum_variant ( ) . fields . is_empty ( ) {
792797 FfiResult :: new_with_reason (
793798 ty,
794799 if def. is_struct ( ) {
@@ -804,7 +809,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
804809 )
805810 } else {
806811 self . visit_variant_fields ( state, ty, def, def. non_enum_variant ( ) , args)
807- }
812+ } ;
813+
814+ // from now on in the function, we lint the actual insides of the struct/union: if something is wrong,
815+ // then the "fault" comes from inside the struct itself.
816+ // even if we add more details to the lint, the initial line must specify that the FFI-unsafety is because of the struct
817+ // - if the struct is from the same crate, there is another warning on its definition anyway
818+ // (unless it's about Boxes and references without Option<_>
819+ // which is partly why we keep the details as to why that struct is FFI-unsafe)
820+ // - if the struct is from another crate, then there's not much that can be done anyways
821+ //
822+ // this enum is visited in the middle of another lint,
823+ // so we override the "cause type" of the lint
824+ ffires. with_overrides ( Some ( ty) )
808825 }
809826
810827 fn visit_enum (
@@ -851,10 +868,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
851868 }
852869 } ) ;
853870 if let ControlFlow :: Break ( result) = ret {
854- return result;
871+ // this enum is visited in the middle of another lint,
872+ // so we override the "cause type" of the lint
873+ // (for more detail, see comment in ``visit_struct_union`` before its call to ``result.with_overrides``)
874+ result. with_overrides ( Some ( ty) )
875+ } else {
876+ FfiSafe
855877 }
856-
857- FfiSafe
858878 }
859879
860880 /// Checks if the given type is "ffi-safe" (has a stable, well-defined
0 commit comments