Migration could do a better job of Iterable.firstWhere #42382
Labels
area-migration (deprecated)
Deprecated: this label is no longer actively used (was: issues with the `dart migrate` tool).
NNBD
Issues related to NNBD Release
nnbd-migration-correctness-example
Concrete examples of the migration engine producing an incorrect result on a phase 1 package
P2
A bug or feature request we're likely to work on
Given the following code:
Migration produces the result:
It's really not obvious why the type of
foos
gets changed toList<Foo?>
(even using the tool's "trace" functionality). The reason is thatIterable<T>.firstWhere
's signature isT Function(bool Function(T), {T Function() orElse})
, so any value returned byorElse
must be suitable for insertion in the list (even thoughfirstWhere
won't actually try to insert it in the list). In this example,orElse
returnsnull
, so the only way the migration tool can see for that to work is if the list is aList<Foo?>
.It's really unfortunate that the migration tool is changing the type of the list, because that's the sort of thing that can cause nulls to propagate to a large number of other places in the program.
A better migration would be:
But in order to figure out that this is possible, we have to apply the knowledge that
firstWhere
won't try to insert the value returned byorElse
into the list. (And technically, in order for that to be sound, we'd have to look through the entire program to make sure there isn't an override offirstWhere
that does do that). So if we do this at all, it's probably best to do it as a special-case optimization specific toIterable.firstWhere
rather than some general case logic.(Note that this arose concretely when @srawlins was trying to migrate Mockito)
The text was updated successfully, but these errors were encountered: