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

Introduce a strict-inference static analysis mode. #508

Closed
srawlins opened this issue Aug 8, 2019 · 0 comments · Fixed by #518
Closed

Introduce a strict-inference static analysis mode. #508

srawlins opened this issue Aug 8, 2019 · 0 comments · Fixed by #518

Comments

@srawlins
Copy link
Member

srawlins commented Aug 8, 2019

The goal is to catch more error-prone code during static analysis; for example, code which is guaranteed to error at runtime. This often two secondary effects: (1) reducing errors in developer understanding of such code, and (2) reducing dynamic dispatch in code where a developer did not think dynamic dispatch was occurring.

Here are some examples of such code:

fn(List<int> strings) => print(strings.first.isEven);

void main() {
  var args = ["one", "two", "three"];
  var useArgs = true;
  fn(useArgs ? args : []);
}

Depending on the value of useArgs, the last line is guaranteed to result in a runtime error. The surprise to the developer is that args was even allowed on that line! The problem here is that the developer thought that inference would infer the type of [] from the type of args. A "strict-inference" mode changes static analysis rules such that inference of [] does not fall back to dynamic, but fails.

Another common example that comes up on mailing lists is inference in Iterable.fold. Note the signature of Iterable<E>#fold<T>:

T fold <T>(T initialValue, T combine(T previousValue, E element))

var a = [1, 2, 3].fold(true, (s, x) => s + x);

There are currently no compile-time errors in this code, but it will fail at runtime. A "strict-inference" mode would fail to infer the callback's type at compile-time. If the developer changes the type of a to an explicit bool, or adds an explicit type annotation to fold, they will then see more clearly the error in their code.

The proposed "strict-inference" mode will report errors (e.g. Hints in analyzer) at the declaration of values whose types cannot be inferred. Here is an inexhaustive list (an exhaustive list will come with a more formal specification):

  • a variable declared without a type (e.g. with var or final) and no initializer.
  • a field declared without a type and no initializer.
  • a function parameter declared without a type, excluding a method parameter whose types are inferred from a parent class (inherited? inferred?).
  • an empty collection literals whose type(s) cannot be inferred from "above."
  • an instantiation of a generic class, where the type argument(s) are neither explicitly provided, nor can be inferred from downwards inference or upwards inference, e.g. var f = Future.error("Boo");
  • an invocation of a generic function,where the type argument(s) are neither explicitly provided, nor can be inferred from downwards inference or upwards inference.

This issue is a continuation of dart-lang/sdk#33749. Thanks to @munificent, @leafpetersen, and @matanlurey for specifying most of the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant