Skip to content
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

Analyzer error message is unclear when a generic function is used as a type argument #34741

Closed
iarkh opened this issue Oct 10, 2018 · 4 comments
Assignees
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Milestone

Comments

@iarkh
Copy link
Contributor

iarkh commented Oct 10, 2018

Dart SDK Version: 2.1.0-dev.6.0
OS: Windows 10

Analyzer doesn't allow function to use type parameter '<Instance of 'TypeParameterMember'>' as a type argument whereas dart does allow this.

Here is a sample code example:

Type typeOf<X>() => X;

typedef G = Function<X extends num>();
typedef G1<X> = Function();

main() {
  print(typeOf<G>());
  print(typeOf<G1>());
}

Dart passes both with G and G1, sample output is:

() => dynamic
() => dynamic

Analyzer passes with G1 and fails with G. Here is a sample output:

error - Generic function has type parameters '', so it may not be used as a type argument at test.dart:7:16 - generic_function_cannot_be_type_argument
1 error found.

I believe analyzer and dart should behave in the same manner, i.e. both should not (or maybe both should) throw a compile error here.

@eernstg
Copy link
Member

eernstg commented Oct 10, 2018

It doesn't make sense to say Generic function has type parameters, because every generic function has that. It might be a bug that the type parameters are ''. ;-)

However, it is true that it is a compile-time error to pass a generic function type as a type argument so generic_function_cannot_be_type_argument is more on track than the full message.

The output from dart doesn't show that G is a generic function type, so I suspect that the front end somehow forgets that, which would be a bug in its own right.

So we have considerations about the analyzer as well as the front end here.

It's inconvenient that we cannot pass any term that denotes a generic function type as a type argument to typeOf, but it shouldn't be a real problem: We can use print(G) and test for G == SomeOtherType etc. to check that G denotes the type that we want it to denote at run time, and that would work for every term T that denotes a generic function type, also when T is not an expression. For instance, consider the situation where we want to check that the dynamic value of F is void Function<X extends num>(Map<String, X>):

typedef F<X extends num> = ... some generic function type that we want to test ...;
typedef F_expected = void Function<Y extends num>(Map<String, Y>);

main() {
  print(F == F_expected);
}

I think it might be helpful to report the issues separately: (1) the front end drops the type argument from the function type (at least when it's printed), and (2) the front end doesn't prevent G from being an actual type argument to typeOf, and (3) the analyzer error message could just say 'A generic function type cannot be a type argument', and the stuff about exactly which type parameters it has is irrelevant.

@mit-mit mit-mit added area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. area-front-end Use area-front-end for front end / CFE / kernel format related issues. labels Oct 10, 2018
@bwilkerson bwilkerson added this to the Dart2.2 milestone Oct 10, 2018
@stereotype441
Copy link
Member

Regarding the last paragraph of @eernstg's comment, agreed. I'm going to file a separate bug for issues (1) and (2), and let this bug represent issue (3).

@stereotype441
Copy link
Member

Regarding (1), I'm either unable to reproduce this bug, or I'm not understanding it. When I try running this code in the VM:

typedef G = Function<X extends num>();
typedef G1<X> = Function();
main() {
  print(G);
  print(G1);
}

The output I get is:

<X extends num>() => dynamic
() => dynamic

...which I believe is correct. @eernstg, I suspect I'm not understanding what you're getting at. Would you mind filing a separate issue under area-front-end to track the problem you're seeing?

Regarding (2), there is already a bug filed for this: #30931

I'm going to re-title this bug now so that it represents (3) (unclear analyzer error message) and update its labels accordingly.

@stereotype441 stereotype441 changed the title Analyzer doesn't allow function to use type parameter '<Instance of 'TypeParameterMember'>' as a type argument whereas dart does allow this. Analyzer error message is unclear when a generic function is used as a type argument Oct 10, 2018
@stereotype441 stereotype441 added type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed area-front-end Use area-front-end for front end / CFE / kernel format related issues. labels Oct 10, 2018
@eernstg
Copy link
Member

eernstg commented Oct 11, 2018

unable to reproduce this bug

I did not reproduce that behavior here, I just commented on the reported behavior. So, having #30931 for (2) and this one for (3), we're done! ;)

@scheglov scheglov self-assigned this Nov 9, 2018
dart-bot pushed a commit that referenced this issue Nov 12, 2018
R=brianwilkerson@google.com

Bug: #34741
Change-Id: If766d0aad5d87578a578849f269746a64430a68b
Reviewed-on: https://dart-review.googlesource.com/c/84100
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

6 participants