dart-lang / dart-lang/language

Could horizontal type inference handle this situation?

Open
#3,013 1 comment 0 reactions 0 assignees View on GitHub
type-inference
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

Consider the following program:

```dart
void f(X x, X Function(X) g) {}

void main() {
f(1, (_) => 1.5); // `` works, but inference can't find that solution.
}
```

This program is rejected by the analyzer as well as the CFE because type inference fails to find an actual type argument to the invocation of `f` that satisfies the constraints.

With `f(1, (_) => 1.5)` is accepted with no issues, and `` does indeed yield parameter types such that the expression has no errors (`1` can be typed as `num` immediately, and `(_) => 1.5` can be inferred to have parameter type `num` and return type `num`).

I believe [horizontal type inference](https://github.com/dart-lang/language/blob/master/accepted/2.18/horizontal-inference/feature-specification.md) causes `x` in the first example to be processed in a first phase, thus determining the value of `X` without consideration of anything else than `x` and the actual argument `1`, yielding `X == int`.

In the next phase, type inference can't find a way to annotate the function literal `(_) => 1.5` with a parameter type and return type such that it gets the type `int Function(int)` or a subtype thereof, and inference fails.

As we'd expect, the following variant has no issues (because it doesn't cause horizontal type inference to kick in), and the type argument is inferred as `num`:

```dart
void f(X x, X Function() g) {}

void main() {
f(1, () => 1.5); // OK, uses ``.
}
```

It is not obvious to me how we could improve on this situation. One random idea is that we might be able to generate a "global" constraint (before splitting arguments into phases) that `double <: X <: _`, based on the returned expression of the function literal. But that also seems like a very long shot, e.g., because it may require input from many sources to find the type of a return expression in a function literal.

Contributor guide

Open the contributing guide

Research direction

Start with the horizontal inference feature specification linked in the issue and compare its phased treatment of the two arguments with the provided examples. Determine whether the inference rules should change for the generic invocation and define the expected behavior for both variants. Done means reaching and recording a concrete language-design decision.

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
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.