dart-lang / dart-lang/language

Unwanted Object-inference induced type errors #2

Open
#3,274 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

This issue presents a similar issue as the one in https://github.com/dart-lang/language/issues/3156, but one which can't be addressed with statically checked variance.

Consider the following example:

```dart
void main() {
final bar = [
["a"],
["a", "b", "c"],
].map(
(final e) {
if (e.length == 1) {
return e.single;
} else {
return e;
}
},
).toList()..sort();
print(bar);
}
```

The issue here is that the return type of the function passed to `map` is inferred to be `Object`. This, in my opinion, is not very helpful and can lead to accidental runtime exceptions:

```
Unhandled exception:
type 'List' is not a subtype of type 'Comparable' in type cast
#0 ListMixin._compareAny (dart:collection/list.dart:360:50)
#1 Sort._insertionSort (dart:_internal/sort.dart:69:36)
#2 Sort._doSort (dart:_internal/sort.dart:58:7)
#3 Sort.sort (dart:_internal/sort.dart:33:5)
#4 ListMixin.sort (dart:collection/list.dart:356:10)
#5 main (package:humanspec/parser/sine/hele/dart/meta/foo.dart:13:15)
#6 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:297:19)
#7 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)
```

Such mistakes are easy to make, and other languages have made choices that prevent such errors. Consider, for example, Swift, where returning a String and a List leads to an error at compile time.

```swift
let bar = [["a"], ["a", "b", "c"]]
.map { e in
if e.count == 1 {
return e[0]
} else {
return e
}
}
.sorted()
print(bar)
```

```
error: cannot convert return expression of type '[String]' to return type 'String'
```

I've alluded to a separate analysis step analogous to `implicit-dynamic`, but only for `Object`-related-inferences (e.g. `implicit-object`) in https://github.com/dart-lang/language/issues/3156 which could help prevent such errors. I still think that that is worth considering and could be valuable to Dart users.

Contributor guide

Open the contributing guide

Research direction

Start by comparing the example in this issue with the related analysis in dart-lang/language#3156. Investigate how Dart infers the map callback's return type and whether an implicit-object-style analysis should reject this case. Done requires a decided language-design direction and corresponding specification or implementation work, but no files or tests are named here.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.