Skip to content

Analyzer rejects tests/language_2/generic_methods_generic_function_result_test.dart #30207

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

Open
crelier opened this issue Jul 19, 2017 · 15 comments
Labels
analyzer-test area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Milestone

Comments

@crelier
Copy link
Contributor

crelier commented Jul 19, 2017

The errors reported by the analyzer for tests/language_2/generic_methods_generic_function_result_test.dart does not look correct.

ERROR|STATIC_WARNING|LIST_ELEMENT_TYPE_NOT_ASSIGNABLE|/b/build/slave/azrs-be/build/sdk/tests/language_2/generic_methods_generic_function_result_test.dart|14|44|3|The element type '(int, T) → T' can't be assigned to the list type '(S, T) → T'.
ERROR|STATIC_WARNING|LIST_ELEMENT_TYPE_NOT_ASSIGNABLE|/b/build/slave/azrs-be/build/sdk/tests/language_2/generic_methods_generic_function_result_test.dart|14|49|3|The element type '(int, T) → T' can't be assigned to the list type '(S, T) → T'.
ERROR|STATIC_WARNING|ARGUMENT_TYPE_NOT_ASSIGNABLE|/b/build/slave/azrs-be/build/sdk/tests/language_2/generic_methods_generic_function_result_test.dart|21|35|3|The argument type 'int' can't be assigned to the parameter type 'S'.

@crelier crelier added the legacy-area-analyzer Use area-devexp instead. label Jul 19, 2017
@bwilkerson
Copy link
Member

@leafpetersen Can you confirm that this is an error?

@bwilkerson bwilkerson added 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 Jul 20, 2017
@leafpetersen
Copy link
Member

leafpetersen commented Jul 20, 2017

The first error is correct, at least that it is an error. To put foo into the list, we need to show that it's type is a subtype of T Function<T extends num>(S, T). That is,

T foo<T extends num>(int i, T t) <: T Function<T extends num>(S, T)

Note that all of the T occurrences here refer to the bound T in the types, not the outer T from the enclosing context.

To show this, we must show that T <: T which is true, and that S <: int which is not true (since all we know is that S <: num.

The error doesn't print the generic parameters on the types though, which doesn't seem ideal.

@leafpetersen
Copy link
Member

The second error is, I believe a repeat of the first for the second occurence of foo, so also correct.

@leafpetersen
Copy link
Member

The third error looks incorrect. The inferred type of list should be List<T Function<T extends num>(int, T)> , so list[1] should have type T Function<T extends num>(int, T), so list[1]<int> should have type int Function(int, int) and the application should be fine.

At the point of the application of list[1], S should have been substituted away, and shouldn't appear in the error anyway, even if it was an error.

@crelier
Copy link
Contributor Author

crelier commented Jul 20, 2017

Thanks Leaf!
I guess I should change the upper bound of S from num to int to satisfy static analysis in strong mode.
Of course, S cannot take many different type values then, but the goal of this test is to verify proper resolution of S, which is unrelated to these analysis errors.
The 3rd error remains, which does not invalidate this bug report even if I correct the test.

I also realize that the comment is wrong. It should be
// "<T extends num>(int, T) => T" when reifying generic functions.

@leafpetersen
Copy link
Member

cc @jmesserly

@jmesserly
Copy link

fyi #29778 is a possibly related substitution problem

@eernstg
Copy link
Member

eernstg commented Jul 21, 2017

The test should actually be rejected at compile-time because it uses a generic function type as an actual type argument (at all), not because of any particular missing subtype relationships.

We have the following in the informal spec of the new inline function types, which is the construct that introduces support for specifying the type of a generic function: 'It is a compile-time error if a generic function type is used as a bound for a formal type parameter of a class or a function. It is a compile-time error if a generic function type is used as an actual type argument'. Issue #29484 provides more background.

@crelier
Copy link
Contributor Author

crelier commented Jul 21, 2017

I do not think any of these restrictions apply to this test. No generic function type is used as bound or as type argument. Here is the source of the test to avoid confusion:

import "package:expect/expect.dart";

T foo<T extends num>(int i, T t) => i + t;

List<T Function<T extends num>(S, T)> bar<S extends int>() {
  return <T Function<T extends num>(S, T)>[foo, foo];
}

void main() {
  var list = bar<int>();
  print(list[0]
      .runtimeType); // "<T extends num>(int, T) => T" when reifying generic functions.
  Expect.equals(123, list[1]<int>(100, 23));
}

@leafpetersen
Copy link
Member

Ah, right, I completely missed that. @eernstg is correct - we have a predicativity restriction: " It is a compile-time error if a generic function type is used as an actual type argument", so List<T Function<T extends num>(S, T)> should be an error.

@crelier
Copy link
Contributor Author

crelier commented Jul 21, 2017

Oops, sorry, I see it now. The type argument of List in the return type is a generic function type.
The VM should reject it and obviously does not.
I will make this test a negative sub-test of a multi-test, with another simpler sub-test actually testing the proper resolution of S in the result type as was intended.

@crelier
Copy link
Contributor Author

crelier commented Jul 21, 2017

The test has been updated, but the analyzer fails to report a compile time error in non-strong mode (multi test '01') and wrongly reports a compile time error in strong mode (multi test 'none').

@jmesserly
Copy link

merging this into #29778

@jmesserly jmesserly added the closed-duplicate Closed in favor of an existing report label Sep 25, 2017
@MichaelRFairhurst
Copy link
Contributor

Reopening this. The analyzer correctly reports an error where it should, but, as Leaf had said:

The third error looks incorrect. ... At the point of the application of list[1], S should have been substituted away, and shouldn't appear in the error anyway, even if it was an error.

This is still an issue in the test

@MichaelRFairhurst MichaelRFairhurst added P3 A lower priority bug or feature request and removed analyzer-strong-mode closed-duplicate Closed in favor of an existing report P2 A bug or feature request we're likely to work on labels Aug 31, 2018
@bwilkerson bwilkerson added this to the Dart2.1 milestone Sep 4, 2018
@bwilkerson bwilkerson modified the milestones: Dart2.1, PostDart2.1 Sep 4, 2018
@jmesserly jmesserly removed their assignment Feb 16, 2019
@aadilmaan aadilmaan modified the milestones: Future, D25 Release Jun 4, 2019
@srawlins
Copy link
Member

SG

@johnniwinther johnniwinther added area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. and removed legacy-area-analyzer Use area-devexp instead. labels Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-test area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

10 participants