dart-lang / language

Design of the Dart language
Other
2.66k stars 205 forks source link

As specified, type inference infers no constraint for Null <: Future<T> #937

Open stereotype441 opened 6 years ago

stereotype441 commented 6 years ago

The local inference informal specification (https://github.com/dart-lang/sdk/pull/29371) says:

The analyzer behavior is slightly different in the case where P is a subtype match for both Future<Q> and Q. (This happens, for instance, if P is Null). In that case, if the attempt to match P against Future<Q> generates zero constraints, but the attempt to match P against Q generates constraints, then the constraints from matching P against Q are propagated.

This has a user visible effect in the analyzer. Consider the code:

void test(Future<int> f) async {
  var t = f.then((int x) {});
  (await t).foo();
}

The analyzer attempts to infer the type argument for then by matching Null <: Future<T>. This causes the type constraint Null <: T to be generated, therefore t has type Future<Null>, and (await t).foo() produces an error. If I change the analyzer to follow the informal specification, it infers a type of Future<dynamic> for t, and no error is issued. Issuing an error seems like a better behavior here.

(Note that the common front end's behavior is different still: it infers a type of dynamic for t, due to dart-lang/sdk#33044.)

@leafpetersen @jmesserly what do you think?

jmesserly commented 6 years ago

I like this idea. Analyzer behavior seems useful here (catches the bug on the next line).