Minimal example: struct A struct B end end. This puts both A and B into the global scope, A without constructors and B with a constructor. Why would B be put into global scope even though no global keyword was used?
More extreme example:
struct A struct B struct C struct D end end end end
In this case all four types are put into global scope, with the innermost type, D, being the only one with any constructors.
It seems like it might be good to just disallow struct-within-struct constructs, if the inner types are just going to end up in the global scope anyway. If that’s possible without breaking backwards compatibility, that is.
I think that’s as intended, although there’s perhaps a kludgy feel to it. The idea is that whenever one defines any method, there is no automatic generation of constructors. To make this more useful (?), there’s one undocumented/internal (?) feature that I alluded to in the OP: using the global keyword to expose such a “back door” constructor.
I think the global assignment is purely a result from the fact that structs can’t be defined in local scopes; they always fall back to global scopes, because julia does not have a local eval. The “no constructors” thing seems like a bug though.