dart-lang / dart-lang/language
Propagate context types into receivers
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
Consider the following program:
```dart
void main() {
List xs = [1].toList();
xs.add(1.5); // Throws.
}
```
If we use `List xs = [1];` it does not throw. The fact that this kind of code may throw would come as a surprise to many developers, and it would be useful to consider if it can be avoided.
The underlying issue is that the context type `List` which is used during type inference of the initializing expression `[1].toList()` is forgotten when type inference is applied to the list literal `[1]`. Hence, it becomes `[1]` based on the elements in the list. Consequently, the type of `[1].toList()` is also `List`. `List` is assignable to `List`, and hence the developer does not get any hints that anything unusual is going on.
However, with `List xs = [1];`, the context type used during type inference of `[1]` is `List`, and this causes the list literal to become `[1]`, and the addition of 1.5 succeeds.
Similar situations may create other issues, e.g., that type inference fails, or an expression fails to have a type which is assignable to its context, because a nested receiver expression gets the empty context, but it could have succeeded if a suitable context type had been propagated down to that receiver from the enclosing expression. For example:
```dart
class A {}
class B extends A {}
class C extends A {}
void main() {
List> xs = [B(), C()].toList(); // Compile-time error, `List` is not assignable to `List>`.
}
```
Again, `List> xs = [B(), C()];` has no error because the context type is used to turn the list literal into `>[B(), C()]`, which is typable.
It seems that it Could be useful if some context type information could be propagated to subexpressions where we currently do not propagate any information.
@chloestefantsova, you have been working on this kind of enhancement. Could you create a 'feature' issue in response to this one, briefly describing your take on this topic?
Contributor guide
Research direction
Start with the two Dart examples in the issue and compare the inferred types for direct list literals and calls to toList(). Review the existing context-propagation work referenced in the issue, then define the intended inference behavior and its compatibility boundaries before implementation.
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
- Mostly clear
- Newbie friendliness
- 25/100