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

FutureOr as type bound causes incorrect static errors (lib_2/async/future_or_type_test fails) #37395

Open
rakudrama opened this issue Jun 28, 2019 · 2 comments
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. language-discussion type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@rakudrama
Copy link
Member

rakudrama commented Jun 28, 2019

lib_2/async/future_or_type_test appears to be suppressed on most targets

tests/lib_2/async/future_or_type_test.dart: Error: Type argument 'T' doesn't conform to the bound 'FutureOr<num>' of the type variable 'T' on 'C' in the return type.
 - 'FutureOr' is from 'dart:async'.
Try changing type arguments so that they conform to the bounds.
tests/lib_2/async/future_or_type_test.dart:252:9: Context: This is the type variable whose bound isn't conformed to.
class C<T extends FutureOr<num>> {
        ^

I don't understand the error because T is not used in a return position, and the error occurs regardless of whether class C is used.

// FutureOr used as type parameter bound.
class C<T extends FutureOr<num>> {
  bool isCheck(Object o) => o is T;
}

@lrhn @leafpetersen

  • Is this program a static error?
    • If in error, can the test be fixed, or removed if superseded by other tests
    • If not it error, can the test be split to regain coverage of the other tests
@rakudrama rakudrama added area-front-end Use area-front-end for front end / CFE / kernel format related issues. language-discussion labels Jun 28, 2019
@eernstg
Copy link
Member

eernstg commented Jun 28, 2019

The following minimal program which causes the error to be reported from the front end does not have a compile-time error:

import 'dart:async';
class C<T extends FutureOr<num>> {}
main() {}

FutureOr is a generic type, it has no bounds (so FutureOr<...> is always regular-bounded, hence well-bounded), and all we require for a bound to be accepted is that (1) it is a type, (2) if raw, it must have simple bounds (but it's not raw here). That type must not itself be an error, and when checking its type arguments the subtype relationships introduced by the full list of formal type parameters are assumed (but FutureOr<num> doesn't contain any type variables). So no errors.

It's surprising that the location of the error is not reported (so there's presumably one bug already), it only reports the location of the type variable declaration. It must also be a bug that a bound violation is reported at all, because there is no location in the program where an actual type argument is passed to C (explicitly or by inference).

So the first step in handling this test would be to make sure that the front end does not get off track when a type of the form FutureOr<...> is used as a bound at all.

Apart from co19_2, there are no other tests under sdk/tests where FutureOr<...> is used as the bound of a formal type parameter, but adding the above snippet as a new test could be useful (maybe named 'regression_something'?).

In co19_2/src/LanguageFeatures/Simple-bounds there are about 17 usages, and in .../Instantiate-to-bound there are about 20, so that's one place to look for tests that do use this feature.

The test lib_2/async/future_or_type_test.dart runs successfully with a several configurations using the front end after deleting the bound:

class C<T> {
  bool isCheck(Object o) => o is T;
}

That bound is actually never significant for the test: No code in C relies on the bound for type correctness or for any semantic effects, and no code outside C relies on the bound other than by having actual type arguments that satisfy the bound. So the test (in its original form where the bound is present) does give rise to a number of standard subtype checks at compile-time, but that's all.

I believe that lib_2/async/future_or_type_test.dart has no errors, and the bug concerned with having FutureOr or FutureOr<...> as a bound is the only thing that prevents it from succeeding. It is already accepted by the analyzer.

So I don't see a need to split the test up, but it is important to make it a goal to handle FutureOr as a bound. With that, the test will just work.

@rakudrama rakudrama changed the title lib_2/async/future_or_type_test fails FutureOr as type bound causes incorrect static errors (lib_2/async/future_or_type_test fails) Jun 28, 2019
@leafpetersen
Copy link
Member

Yeah, that's a bug. That code should be fine.

@fishythefish fishythefish added the type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) label Sep 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. language-discussion type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

4 participants