dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.1k stars 1.56k forks source link

Ternary on generic functions fails to compile for no reason #43759

Open rrousselGit opened 3 years ago

rrousselGit commented 3 years ago

Consider:

void main() {
  void Function<T extends Object>(T) foo;
  foo = foo == null ? foo : foo as void Function<T extends Object>(T);
}

This code does not compile with

lib/main.dart:32:21: Error: A value of type 'void Function(bottom-type)' can't be assigned to a variable of type 'void Function<T extends Object>(T)'.
 - 'Object' is from 'dart:core'.                                        
  foo = foo == null ? foo : foo as void Function<T extends Object>(T); 

This is undesired as the code is valid.

Surprisingly, extracting the raw function type into a typedef makes the code compile:

typedef Typedef = void Function<T extends Object>(T);

void main() {
  Typedef foo;
  foo = foo == null ? foo : foo as Typedef;
}

Dart version:

Dart SDK version: 2.11.0-186.0.dev (dev) (Mon Oct 5 06:44:49 2020 -0700) on "macos_x64"

Note: While there is a known workaround (typedef), the workaround is inapplicable for code-generators (as they do not see typedefs). This is blocking https://github.com/rrousselGit/freezed/issues/258 from being fixed.

lrhn commented 3 years ago

Seems like the LUB of two different, but equivalent, generic function types throws away the genericity.