Difficulties with non-nullable types (part 3)

In the last post on this topic i talked about how it was critical that
by the time a non-null type was used it was provably assigned some
non-null value.  The cases that came up were specifically instance
fields in classes.  In that post i showed how would could change
how types were initialized to ensure that that these non-null
constraints could be met.

However, there is another type of field out there: static
fields.   And it turns out that these fields are  much
harder to deal with than instance fields.  Why?  Well, let's
take a look at a simple example:

 class Person {
    public static string! name;

How do we initialize that field?  Well, we could start with a static constructor like so:

 class Person {
    public static string! name;

    static Person() {
         a = new Cyrus().name;

class Cyrus {
    public static string! name = "cyrus";

Ok.  Seems like this would work out and you'd end up with all
non-null "name"'s being assigned a value.  However, let's extend
that a little further:

 class Cyrus {
    public static string! name = "cyrus";

    public Cyrus() {
        Cyrus.name = Person.name;

Uh oh.  Now we've got a problem.  Everything looks typesafe,
but when the Person class loads, it will call the 'Cyrus' constructor
which will then access the "Person.name" field before it has been
initialized!  Not good!

As it turns out this is the same problem as the instance-field issue
from the last post.  As i mentioned there, determining the set of
code that is dependent on a constraint is extremely difficult and so we
need a more restrictive set of rules that we can work with in order to
be able to reason about this properly.

In order to support the instance fields case we placed the restriction
that before the "this" pointer could be used, it has to be the case
that all the non-nullable fields had been assigned to.  Can we
extend that idea out to static fields?  Since there is no "this"
pointer we would have to say something like "before you can use the
actual type containing the static field, all fields must be assigned

This is a much more limiting set of circumstances, and far harder to
enforce.  With instance fields you at least have access to a rich
set of inputs to initialize them with.  You can use static data in
the system, or you can use parameters passed into a constructor. 
With static fields things are not so clear cut.  As you can see
above, arbitrary code can't be run as that code might statically access
the type being constructed.  Also, as static constructors don't
take any parameters it's hard to find inputs to assign to these fields.

So what can be done about this?  It's not clear to me what the
best solution is.  The easiest solution is to simply disallow
static non-nullable types.  But that would suck since i think that
people really want them.  The next easiest would be to have
non-nullable static fields, but guard all read/writes to them to check
for null.  That would put the onus on the programmer to ensure
that it's value is set before use, but it means that suddenly accessing
this field could fail at runtime.  Ugh*2.  The final thing
that i can think would be a solution like the following inside the

When loading a type that has non-nullable static fields, start executing the static cosntructor 2. When the static constructor enters, set a bit saying that the type
is currently being constructed.  Then, if a static non-nullable
field in that type is ever accessed by anyone else, throw an exception
saying that this type wasn't fully initialized and it's invalid to
access non-null static state yet. 3. If the code executed in the static constructor then causes something
like the above situation to happen, then you'll immediately fail at
typeload time.

This has the unfortunate outcome that the checking is still done at
runtime.  however, it will most likely occur early on when all
your types are being loaded, and not much later on the first access of
one of these fields.

In essence, what we've done is enforce a quasi ordering on how types
are loaded in the runtime.  As a type loads it can access static
non-nullable fields in any fully loaded type, but not in a type that is
still being loaded.

It's ugly, but i can't think of anything better.  Do you guys have any ideas?