Description
We encountered some cryptic and hard to solve errors during null safety migration of dwds.
I suspect the issue is related to the variance issue in dart, am I correct (dart-lang/language#524)? Is there a way to annotate the parameter in addFoo
to make sure we get a compilation error on callsite?
Simplified example
This code stops working after null safety migration:
import 'dart:async';
// Code in library being migrated
void main() {
// Should be StreamController<Map<String, Object?>>() after null safety
// migration but it's hard to detect due to absence of compilation errors.
// Runtime error does not help detect the problem.
final controller = StreamController<Map<String, Object>>();
controller.stream.listen(print);
addFoo(controller.sink); // No compilation error here
print('done');
}
// Code in another library, already migrated
void addFoo(StreamSink<Map<String, Object?>> sink) {
sink.add({'foo': 'bar'}); // Runtime type error here
}
Expected
Compilation fails at addFoo(controller.sink);
Actual
No compilation error shown by the analyzer. Runtime error at sink.add({'foo': 'bar'});
:
Uncaught Error: TypeError: Instance of 'JsLinkedHashMap<String, Object?>': type 'JsLinkedHashMap<String, Object?>' is not a subtype of type 'Map<String, Object>'
In our dwds CI (https://github.com/dart-lang/webdev/runs/7622869869?check_suite_focus=true), the error happens far from the creation of the stream controller (another library) and traces look like:
❌ test/handlers/asset_handler_test.dart: Asset handler can read large number of resources simultaneously (failed)
Retry: Asset handler can read large number of resources simultaneously
type '_InternalLinkedHashMap<String, Object?>' is not a subtype of type 'Map<String, Object>' of 'data'
dart:async _StreamSinkWrapper.add
package:vm_service/src/vm_service.dart 1732:21 VmServerConnection._delegateRequest
Dart SDK Version (dart --version
)
version: 2.19.0-36.0.dev