Description
Pre null-safety, missing a type bound meant that the bound was treated as dynamic
. With NNBD, we weren't sure whether this is the semantics we want. We are worried that doing so might be more breaking than intended. Instead, we were hoping that we could update the semantics to say that the default bound is Object
in opt-out code and Object?
in opt-in code.
In particular, consider these four functions:
// from an opted-out library:
T fo1<T>(T t);
T fo2<T extends Object>(T t); // bound is Object*
// from an opted-in library:
T fi3<T>(T t);
T fi4<T extends Object?>(T t);
Pre-nnbd, fo1.runtimeType == fo2.runtimeType
, post-nnbd this would be false if we continue to use dynamic
as the default bound. It would however mean that fo1.runtimeType == fi3.runtimeType
With the semantics suggested above we'd preserve that fo1.runtimeType == fo2.runtimeType
and have also that fi3.runtimeType == fi4.runtimeType
. Here we no longer get fo1.runtimeType == fi3.runtimeType
, which we think it's ok.
@leafpetersen @eernstg @lrhn @munificent - WDYT?