Skip to content

Analyzer and CFE inference disagreement #32305

Closed
@leafpetersen

Description

@leafpetersen

For this code:

void main() {
  int Function(int) f;
  
  List<num> l;
  var a = l.map(f);
  int x = a;
}

the analyzer infers int as the type argument to map, and with an implicit downcast on the argument to map (from int -> int to num -> int), as witnessed by this error message:

[error] A value of type 'Iterable<int>' can't be assigned to a variable of type 'int'. (../../../tmp/ddctest.dart, line 11, col 11)

The CFE infers dynamic as the type argument to map, with the result that the argument to map is invalid (a cross cast from int -> int to num -> dynamic):

file:///Users/leafp/tmp/ddctest.dart:10:17: Error: A value of type '(dart.core::int) → dart.core::int' can't be assigned to a variable of type '(dart.core::num) → dynamic'.
Try changing the type of the left hand side, or casting the right hand side to '(dart.core::num) → dynamic'.
  var a = l.map(f);
                ^
file:///Users/leafp/tmp/ddctest.dart:11:11: Error: A value of type 'dart.core::Iterable<dynamic>' can't be assigned to a variable of type 'dart.core::int'.
Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
  int x = a;
          ^

I believe that the CFE behavior is correct for Dart 2. We intentionally push the context type down into sub-terms and insert casts to the context type (or to the greatest closure thereof), in order to avoid relying on least upper bound with the pathologies that result (e.g. giving no error message for String x = (b) ? 3 : []).

cc @jmesserly @stereotype441 @vsmenon to check my thinking on this.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions