Skip to content

Analyzer: New functions types and inference failures #30758

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
matanlurey opened this issue Sep 15, 2017 · 2 comments
Closed

Analyzer: New functions types and inference failures #30758

matanlurey opened this issue Sep 15, 2017 · 2 comments
Labels
closed-as-intended Closed as the reported issue is expected behavior legacy-area-analyzer Use area-devexp instead. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@matanlurey
Copy link
Contributor

DartPad shows this nicely (make sure to enable Strong Mode to see the errors):
https://dartpad.dartlang.org/039f886163201de475206b011b71b540

This also occurs as latest as:

$ dart --version
> Dart VM version: 1.25.0-dev.16.4 (Wed Sep 13 01:47:12 2017) on "macos_x64"

New function type (inline)

Incorrectly infers as dynamic

class GraphVisitor1 {
	T _find<T>(T Function<T>(int example) fn) => null;
  
  void doThing() {
    _find((e) => e.abs());
    // ^^^^^ No auto-complete, 'e' is inferred as dynamic by the analyzer.
  }
}

Old function type

Correctly infers as int

class GraphVisitor2 {
  void _find(void fn(int example)) => null;
  
  void doThing() {
    _find((e) => e.abs());
    // ^^^^^ Auto-complete, yay! 'e' is inferred as int.
  }
}

Old typedef

Correctly infers as int

typedef void OnIntA(int example);

class GraphVisitor3 {
  void _find(OnIntA fn) => null;
  
  void doThing() {
    _find((e) => e.abs());
    // ^^^^^ Auto-complete, yay! 'e' is inferred as int.
  }
}

New typedef

Incorrectly infers as dynamic

typedef OnIntB = T Function<T>(int example);

class GraphVisitor4 {
  T _find<T>(OnIntB fn) => null;
  
  void doThing() {
    _find((e) => e.abs());
    // ^^^^^ No auto-complete, 'e' is inferred as dynamic by the analyzer.
  }
}
@bwilkerson bwilkerson added legacy-area-analyzer Use area-devexp instead. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Sep 15, 2017
@jmesserly
Copy link

So this is working as intended. The "new" examples are not equivalent to the "old", they're declaring generic function types. A generic function type is one like <T>(T) -> T ... that means "for any type T, this function takes a parameter of type T and returns a value of type T".

You cannot pass a normal function expression like (e) => e.abs() to a generic function. That should be a compile error. You could pass something like <T>(e) => e.abs() but you'll get an error that T does not support .abs() ... that illustrates the problem. Your lambda doesn't work for all T, it only works for int specifically. The problem here is the type signature of _find is not equivalent to the "old" syntax.

Here's a version of the "new" examples that are equivalent to the "old" examples:

class GraphVisitor1 {
	T _find<T>(T Function(int example) fn) => null;
  
  void doThing() {
    _find((e) => e.abs()); // infers int -> int
  }
}

and

typedef OnIntB<T> = T Function(int example);

class GraphVisitor4 {
  T _find<T>(OnIntB<T> fn) => null;
  
  void doThing() {
    _find((e) => e.abs()); // infers int -> int
  }
}

both of those work

@jmesserly jmesserly added the closed-as-intended Closed as the reported issue is expected behavior label Sep 15, 2017
@matanlurey
Copy link
Contributor Author

Thanks make perfect sense, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-as-intended Closed as the reported issue is expected behavior legacy-area-analyzer Use area-devexp instead. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

3 participants