Skip to content

Least and greatest closures works incorrectly for invariant generic typedef: unexpected compile error appears #44163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
iarkh opened this issue Nov 12, 2020 · 1 comment
Labels
legacy-area-front-end Legacy: Use area-dart-model instead.

Comments

@iarkh
Copy link
Contributor

iarkh commented Nov 12, 2020

Dart SDK version: 2.12.0-29.0.dev (dev) (Mon Nov 9 06:42:00 2020 -0800) on "windows_x64"

Here is a source code example:

Type? _capturedTypeArgument;

X captureTypeArgument<X>() {
  _capturedTypeArgument = X;
  throw "Error";
}

Type? get capturedTypeArgument {
  var result = _capturedTypeArgument;
  _capturedTypeArgument = null;
  return result;
}

typedef F<X> = void Function<Y extends X>();
F<X> toF<X>(X x) => <Y extends X>() {};
Type typeOf<X>() => X;

typedef check<X> = X Function(X x);

void main() {
  void f<X>(check<X> Function() g) => g();
  try { f(() => captureTypeArgument()); } catch(_) {};
  print (typeOf<check>());
  print(capturedTypeArgument);
}

Seems like it should print (Object?) => Object? twice here, however this does not happen and dart throws a compile error instead.

Dart sample output is:

test.dart:22:11: Error: The argument type 'Object? Function(Never) Function()' can't be assigned to the parameter type 'Object? Function(Object?) Function()'.

  • 'Object' is from 'dart:core'.
    try { f(() => captureTypeArgument()); } catch(_) {};
    ^

Related issues against covariant and contravariant cases are: #44161, #44162.

@eernstg
Copy link
Member

eernstg commented Dec 15, 2020

Cf. #44161 for a bit more detail.

This is working as intended.

typeOf<check>() is obtained by applying i2b on the raw type check, and the resulting type is dynamic Function(dynamic). No errors at compile-time here.

capturedTypeArgument is the greatest closure of _ Function(_) with respect to {_}, which is Object? Function(Never). Note that there is no type T such that T Function(T) is this type, or even a supertype of this type, and this means that it is not possible to choose a type argument T to f such that an actual argument of type Object? Function(Never) Function() is type correct, and hence we get the compile-time error as described.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
legacy-area-front-end Legacy: Use area-dart-model instead.
Projects
None yet
Development

No branches or pull requests

3 participants