@@ -215,7 +215,6 @@ impl<'tcx> FfiResult<'tcx> {
215
215
/// For instance, if we have a repr(C) struct in a function's argument, FFI unsafeties inside the struct
216
216
/// are to be blamed on the struct and not the members.
217
217
/// This is where we use this wrapper, to tell "all FFI-unsafeties in there are caused by this `ty`"
218
- #[ expect( unused) ]
219
218
fn with_overrides ( mut self , override_cause_ty : Option < Ty < ' tcx > > ) -> FfiResult < ' tcx > {
220
219
use FfiResult :: * ;
221
220
@@ -737,7 +736,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
737
736
// `()` fields are FFI-safe!
738
737
//FfiUnsafe { ty, .. } if ty.is_unit() => false, // TODO get back here
739
738
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
+ }
741
746
}
742
747
}
743
748
@@ -788,7 +793,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
788
793
) ;
789
794
}
790
795
791
- if def. non_enum_variant ( ) . fields . is_empty ( ) {
796
+ let ffires = if def. non_enum_variant ( ) . fields . is_empty ( ) {
792
797
FfiResult :: new_with_reason (
793
798
ty,
794
799
if def. is_struct ( ) {
@@ -804,7 +809,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
804
809
)
805
810
} else {
806
811
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) )
808
825
}
809
826
810
827
fn visit_enum (
@@ -851,10 +868,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
851
868
}
852
869
} ) ;
853
870
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
855
877
}
856
-
857
- FfiSafe
858
878
}
859
879
860
880
/// Checks if the given type is "ffi-safe" (has a stable, well-defined
0 commit comments