dart-lang / dart-lang/language

Propagate context types into receivers

Open
#3,523 1 comment 0 reactions 0 assignees View on GitHub
request
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.