In this dart snippet:
// The value 'null' can't be returned from a function with return type 'T'
// because 'T' is not nullable.
T func1<T>() {
return null;
}
void func2<T>(T x) {
print(x);
}
void main() {
String? s = func1();
func2(null);
}
Both functions use generic T; one tries to treat T as nullable within the function body and fails, the other's caller tries to treat T as nullable and succeeds. I understand the second one, but I am confused by this difference. In both cases, I would argue that T should be nullable because dart docs says that the default type is T extends Object?. The error remains the same even if I change the func1's signature to make T inherit explicitly from nullable object using func1<T extends Object?>.
I can get it to compile by changing the return type to T?, but then why would the docs say that the default is T extends Object?. Is this requirement to specify the type as T? before you can return null just a syntax rule to make it clear to the callers that the return value may be null?
If that is the case, dart allows me to override that rule; even if I keep the return type as T, I can get func1 to return null by changing it to return null as T;. And it runs fine because after all, T extends Object?. This kinda breaks the expectation that a generic function with return type T may not return null. The following code compiles fine, but throws a runtime error as T resolves to String during runtime causing the casting to fail. I understand why that's happening, but why isn't there a way to catch this at compile time?
T func3<T>() {
return null as T;
}
void main() {
String s = func3();
}
I am sure I am missing something basic about generic functions, and/or how they should be implemented in dart. But I couldn't find any official documentation other than the one I linked. So any input regarding this would be much appreciated.