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

Add strict-inference specification #518

Merged
merged 5 commits into from
Aug 19, 2019

Conversation

srawlins
Copy link
Member

We need a formal specification for "strict-inference", so that it can be properly implemented and
tested (e.g. two in progress CRs, 112142 and 111740). @leafpetersen wrote that we can land a spec in this language repository.

Fixes #508

Copy link
Member

@bwilkerson bwilkerson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How many of these cases are covered by NNBD? Are there any incompatibilities between this proposal and NNBD?

working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved

A function parameter declared without a type (via `var`, `final` or without a
modifier), which does not inherit a type (in the case of a method), and whose
type cannot be inferred from downwards inference (in the case of a function
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... whose type cannot be inferred from downwards inference ...

I think you intended to say a little more than that (here and elsewhere). Specifically "inferred as something other than dynamic".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even dynamic would be fine. For example:

fn(void callback(dynamic x), dynamic x) { callback(x); }
fn((var x) => print(x));

Strict inference will not report any inference failures; the parameter type on the second line is inferred to be dynamic. The first line is filled with explicit dynamics.

Or the method case:

class C {
  void f2(dynamic a) => print(a);
}

class D extends C {
  @override
  void f2(a) => print(a); // OK; inherits dynamic type
}

working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
@srawlins
Copy link
Member Author

@leafpetersen @munificent I'd love a review from one of you, as you've reviewed previous iterations.

How many of these cases are covered by NNBD?

Do you mean in terms of "Extended Type promotion, Definite Assignment, and Definite Completion"? I don't think these have been specified yet. I see a 9-month old proposal from you and Bob. Should I look at this to see how it would interact?

Are there any incompatibilities between this proposal and NNBD?

I don't think so; not as NNBD is written today, since the type promotion stuff isn't in the spec yet. If, e.g. top-level return types are to be inferred under NNBD, then we could relax that inference failure.

working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
type of `s` (`T`) will be inferred from the type of `initialValue`, and that
static analysis would report any issue with that type. But inference doesn't
flow between parameters like that. Instead, while trying to infer `T`, there
is not enough information from downwards inference (the type of `a`), and there
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't quite an accurate description of what happens. What happens is that the downwards context provides no information. Upwards inference constrains T to be a super type of bool from the first argument. For the second argument, inference assumes that s and x have type dynamic, and hence infers dynamic Function(dynamic, int) as the type of the function literal. This in turn constraints T to be a supertype of dynamic. The LUB of bool and dynamic is dynamic, and so that is what is chosen for T.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK that makes sense. I think I've corrected my paragraph.

I'm hesitant to use the word "assumes" here, as I don't think that's defined :). But I think I understand that this is merely another round of inference, where inference says "I need to know the type of (s, x) => s + x and all I know is ? Function(?, int) so you don't get anything from above" and this new round of inference says "Well garbage in, garbage out, friend; I've got nothing either, so you get dynamic Function(dynamic, int)", and I assume they both have New York accents.

working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
working/0508 - strict-inference/strict-inference.md Outdated Show resolved Hide resolved
@srawlins srawlins merged commit cdf2bd3 into dart-lang:master Aug 19, 2019
@srawlins srawlins deleted the add-strict-inference branch August 19, 2019 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce a strict-inference static analysis mode.
4 participants