Under NNBD, are factory constructors (a) always nullable, (b) always non-nullable (which is a breaking change), or (c) extended to allow users to specify their nullability?
Whatever the answer, please consider adding this to the spec.
I believe based on the discussion on #279 that there is general consensus that factory constructors are always non-nullable (and, yes, is a breaking change).
Leaving this open to remind us to encode that design choice somewhere.
Correct. It is the decision, and it is a breaking change.
It affects at least the String.fromEnvironment and int.fromEnvironment constructors.
Making factory constructors always nullable was not viable. Almost every use of a factory constructor would need a ! after it, and you would not be able to change a generative constructor to a factory and vice versa.
The other possible alternative was to allow factory constructors to specify a return type. In that case, you should just use a static function. The only constructors where that is not possible are const factory constructors, which are all redirecting to a generative constructor anyway and therefore not nullable, and a few external const factory constructors that we have magic'ed into the SDK. So, we break those few constructors instead of annoying everybody else.
This isn't really a breaking change in the sense that it breaks existing code, but it's true that in order to conform to it packages (and the SDK) may need to change their contract in breaking ways.
It's not particularly a distinct error:
I'm willing to call this out in the spec though - I'll add commentary.
We're currently migrating DDC patch files and are encountering this issue. I'm migrating with the assumption that factory constructors are non-nullable (against the complaints of the analyzer). This may block steel thread migration eventually, so do we have a timeline for when this change will be actualized in our frontends?
@Markzipan Are you still see this issue? I just tested the code below and see an error in the body of the factory, and none at the use site, which is what I would expect.
class A {
factory A() {
return null;
}
void bar() {}
}
void main() {
A x = new A();
new A().bar();
}
Most helpful comment
I believe based on the discussion on #279 that there is general consensus that factory constructors are always non-nullable (and, yes, is a breaking change).
Leaving this open to remind us to encode that design choice somewhere.