@@ -362,7 +362,6 @@ impl<'tcx> FfiResult<'tcx> {
362362 /// For instance, if we have a repr(C) struct in a function's argument, FFI unsafeties inside the struct
363363 /// are to be blamed on the struct and not the members.
364364 /// This is where we use this wrapper, to tell "all FFI-unsafeties in there are caused by this `ty`"
365- #[ expect( unused) ]
366365 fn with_overrides ( mut self , override_cause_ty : Option < Ty < ' tcx > > ) -> FfiResult < ' tcx > {
367366 use FfiResult :: * ;
368367
@@ -889,7 +888,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
889888 FfiSafe => false ,
890889 // `()` fields are FFI-safe!
891890 FfiPhantom ( ..) => true ,
892- r @ FfiUnsafe { .. } => return r,
891+ r @ FfiUnsafe { .. } => {
892+ return r. wrap_all (
893+ ty,
894+ fluent:: lint_improper_ctypes_struct_dueto,
895+ None ,
896+ ) ;
897+ }
893898 }
894899 }
895900
@@ -940,7 +945,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
940945 ) ;
941946 }
942947
943- if def. non_enum_variant ( ) . fields . is_empty ( ) {
948+ let ffires = if def. non_enum_variant ( ) . fields . is_empty ( ) {
944949 FfiResult :: new_with_reason (
945950 ty,
946951 if def. is_struct ( ) {
@@ -956,7 +961,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
956961 )
957962 } else {
958963 self . visit_variant_fields ( state, ty, def, def. non_enum_variant ( ) , args)
959- }
964+ } ;
965+
966+ // from now on in the function, we lint the actual insides of the struct/union: if something is wrong,
967+ // then the "fault" comes from inside the struct itself.
968+ // even if we add more details to the lint, the initial line must specify that the FFI-unsafety is because of the struct
969+ // - if the struct is from the same crate, there is another warning on its definition anyway
970+ // (unless it's about Boxes and references without Option<_>
971+ // which is partly why we keep the details as to why that struct is FFI-unsafe)
972+ // - if the struct is from another crate, then there's not much that can be done anyways
973+ //
974+ // this enum is visited in the middle of another lint,
975+ // so we override the "cause type" of the lint
976+ ffires. with_overrides ( Some ( ty) )
960977 }
961978
962979 fn visit_enum (
@@ -1003,10 +1020,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10031020 }
10041021 } ) ;
10051022 if let ControlFlow :: Break ( result) = ret {
1006- return result;
1023+ // this enum is visited in the middle of another lint,
1024+ // so we override the "cause type" of the lint
1025+ // (for more detail, see comment in ``visit_struct_union`` before its call to ``result.with_overrides``)
1026+ result. with_overrides ( Some ( ty) )
1027+ } else {
1028+ FfiSafe
10071029 }
1008-
1009- FfiSafe
10101030 }
10111031
10121032 /// Checks if the given type is "ffi-safe" (has a stable, well-defined
0 commit comments