Change:
The windows-rs crate is getting a whole bunch of spurious FFI-safe warnings: See: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
cc which introduced the recursion limit.
Repro:
Anyways I'll put up a revert PR claim

Discussion:
lint_improper_ctypes_pat_help = consider using the base type instead lint_improper_ctypes_pat_reason = pattern types have no C equivalent <del> lint_improper_ctypes_recursion_limit_reached = type is infinitely recursive </del> lint_improper_ctypes_slice_help = consider using a raw pointer instead lint_improper_ctypes_slice_reason = slices have no C equivalent

/// The original type being checked, before we recursed /// to any other types it contains. base_ty: Ty<'tcx>, <del> /// Number of times we recursed while checking the type recursion_depth: usize, </del> } enum FfiResult<'tcx> {

// Protect against infinite recursion, for example // `struct S(*mut S);`. <ins> // FIXME: A recursion limit is necessary as well, for irregular // recursive types. </ins> if !acc.cache.insert(ty) { return FfiSafe; } <del> // Additional recursion check for more complex types like // `struct A<T> { v: *const A<A<T>>, ... }` for which the // cache check above won't be enough (fixes #130310) if !tcx.recursion_limit().value_within_limit(acc.recursion_depth) { return FfiUnsafe { ty: acc.base_ty, reason: fluent::lint_improper_ctypes_recursion_limit_reached, help: None, }; } acc.recursion_depth += 1; </del> match *ty.kind() { ty::Adt(def, args) => { if let Some(boxed) = ty.boxed_ty()

return; } <del> let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty, recursion_depth: 0 }; </del> <ins> let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty }; </ins> match self.check_type_for_ffi(&mut acc, ty) { FfiResult::FfiSafe => {} FfiResult::FfiPhantom(ty) => {

<ins> //@ known-bug: rust-lang/rust#130310 use std::marker::PhantomData; #[repr(C)] struct A<T> { a: *const A<A<T>>, p: PhantomData<T>, } extern "C" { fn f(a: *const A<()>); } fn main() {} </ins>

<del> // Regression test for #130310 // Tests that we do not fall into infinite // recursion while checking FFI safety of // recursive types like `A<T>` below //@ build-pass use std::marker::PhantomData; #[repr(C)] struct A<T> { a: *const A<A<T>>, // Recursive because of this field p: PhantomData<T>, } extern "C" { fn f(a: *const A<()>); //~^ WARN `extern` block uses type `*const A<()>`, which is not FFI-safe } fn main() {} </del>

<del> warning: `extern` block uses type `*const A<()>`, which is not FFI-safe --> $DIR/improper-types-stack-overflow-130310.rs:16:13 | LL |     fn f(a: *const A<()>); |             ^^^^^^^^^^^^ not FFI-safe | = note: type is infinitely recursive = note: `#[warn(improper_ctypes)]` on by default warning: 1 warning emitted </del>

<ins> //@ check-pass #![recursion_limit = "5"] #![allow(unused)] #![deny(improper_ctypes)] #[repr(C)] struct F1(*const ()); #[repr(C)] struct F2(*const ()); #[repr(C)] struct F3(*const ()); #[repr(C)] struct F4(*const ()); #[repr(C)] struct F5(*const ()); #[repr(C)] struct F6(*const ()); #[repr(C)] struct B { f1: F1, f2: F2, f3: F3, f4: F4, f5: F5, f6: F6, } extern "C" fn foo(_: B) {} fn main() {} </ins>