Derived-type-spec (such as type(t)) typically cause the instantiation of a class which is also used to define the offsets of its data components and the size of the class.
Fortran derived types are always "completely" defined (i.e., no incomplete / opaque derived types exist on which we can build a pointer to them like in C/C++) so they can have their offsets always computed.
However, we must be careful not to instantiate a derived type while it is being defined. This can happen due to cycles introduced by forward references, such as the one below.
type t1 type(t2), pointer :: b ! (A) end type t1 type :: t2 ! (B) type(t1), pointer :: a ! (C) end type t2 ! (D)
At (A), flang determines that this is a forward declaration so no instantiation happens.
At (B), flang determines t2 is not a forward declaration anymore, because we are defining it.
At (C), flang chooses to instantiate t1. Instantiation of t1 finds the field b at (A). Now t2 is not a forward declaration anymore, so it can be instantiated. But at this point the field a has not been added to t2, so we compute the size of an empty class. Because this computation is done just once, we end emitting a wrong derived type descriptor with a sizeinbytes field set to 0.
Because these kind of cycles can only happen via forward referenced derived types specifiers, the idea here is to avoid instantiating the derived type being defined (i.e. t2) until (D). Keeping the attribute "is forward reference" on until (D) avoids that.
It is weird to define a lambda with no arguments just so you can call it once. Just use a local variable.