Here is a repro:
void main() {
findKey(x, 'bar');
}
const x = {'foo': 'bar'};
void findKey(Map<String, dynamic> m, dynamic search) {
print(m.entries
.singleWhere((entry) => entry.value == search, orElse: () => null)
?.key);
}
This prints foo
on all published SDKs, and the current SDK when it’s not built with --nnbd
. When I build the SDK with --nnbd
and run this code I instead get:
Unhandled exception:
type '() => MapEntry<String, dynamic>' is not a subtype of type '(() => MapEntry<String, String>)?' of 'orElse'
#0 Iterable.singleWhere (dart:core/iterable.dart)
#1 findKey (file:///usr/local/google/home/nbosch/projects/dart_repro/foo.dart:9:8)
#2 main (file:///usr/local/google/home/nbosch/projects/dart_repro/foo.dart:2:3)
#3 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:300:19)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:167:12)
So when the runtime is Map<String, String>
, but statically we have Map<String, dynamic>
the orElse
argument gets the wrong time.
This does not require enabling the experiment or turning on strong mode.
Analyzer infers correct static type, I added a new test.