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: Missing check for well-boundedness #41963

Closed
eernstg opened this issue May 19, 2020 · 3 comments
Closed

Analyzer: Missing check for well-boundedness #41963

eernstg opened this issue May 19, 2020 · 3 comments
Labels
analyzer-spec Issues with the analyzer's implementation of the language spec area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion.

Comments

@eernstg
Copy link
Member

eernstg commented May 19, 2020

Consider the following program:

class A<X> {}
typedef F1<X extends A<X>> = X Function(X x);
typedef F2<X extends A<X>> = void Function();

void main() {
  void foo(
    F1 f1, // Error: Instantiation to bound failed.
    F2 f2, // Error: Instantiation to bound failed.
  ) {}
}

The raw types F1 and F2 that are used as parameter types in foo are completed by instantiation to bound, yielding F1<A<dynamic>> and F2<A<dynamic>> respectively.

However, those two types are not well-bounded: The type argument A<dynamic> doesn't satisfy the bound (A<dynamic> is not a subtype of A<A<dynamic>>), so the types are not regular-bounded. They are also not correctly super-bounded, because the type parameter is invariant respectively unused, so the substitution step where extreme types are replaced by the "opposite" type when occurring in a position with the right variance doesn't change anything. So F1 and F2 simply can't be used raw anywhere.

The same type can also not be used explicitly, because it still isn't well-bounded:

class A<X> {}
typedef F1<X extends A<X>> = X Function(X x);
typedef F2<X extends A<X>> = void Function();

void main() {
  void foo(
    F1<A<dynamic>> f1, // Error: Type not well-bounded.
    F2<A<dynamic>> f2, // Error: Type not well-bounded.
  ) {}
}

However, dartanalyzer from commit de3779e does not report any of these errors, so it seems that there is a missing check for such types being well-bounded (or the check occurs, but it replaces dynamic by Null/Never even when it occurs in a position that isn't covariant).

@eernstg eernstg added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label May 19, 2020
@srawlins srawlins added the analyzer-spec Issues with the analyzer's implementation of the language spec label Jun 16, 2020
@srawlins
Copy link
Member

I believe this is a duplicate of #36870

@eernstg
Copy link
Member Author

eernstg commented Jun 21, 2020

Thanks for highlighting this issue. I took a look at #36870, and it is actually quite different. I changed #36870 to indicate the problem there more precisely (it's a missing scope in generic function types).

@eernstg
Copy link
Member Author

eernstg commented Sep 23, 2020

With the spec update in dart-lang/language#1133, in code with null safety, the compile-time errors described above are no longer errors, because invariant and unused type variables are treated the same as covariant type parameters.

At this point we do not introduce breaking changes for code without null safety.

So I'll close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-spec Issues with the analyzer's implementation of the language spec area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion.
Projects
None yet
Development

No branches or pull requests

2 participants