Just in case if someone will stumble with the same (or equivalent) problem or if the topic starter is still seeking the solution - this could be solved by converting the
t_typ value in both modules to a function (of type
unit -> t structure typ (alternatively, you can hide it, provide it in some other module, that is not recursive with those two, or provide it only in one module).
The underlying reason is that the compiler needs to ensure, that no elements of the recursive definition are used before initialized. Functions and lazy values are always initialized with default values (that raise exception), thus they are considered safe. All other values may not be used safely. The compiler performs a check that relies only on module types (it doesn’t look into the definition, thus the check is pessimistic - it disallows programs that do not really access unsafe components of other modules but may, as per the type). A module that defines only functions and lazy values is considered a safe module. The check marks the recursive definition as safe if all modules involved in the definition are safe, or if some are unsafe, but they could be initialized before those modules that depend on them.
So in your case, the only value that is unsafe is the
t_typ definition. That is neither used recursively nor is dependent on anything besides the type. The easy solution is just to make it a function, and call it later, to instantiate the C type. You can also factor this type into a separate module.