This was broken after
https://dart-review.googlesource.com/c/sdk/+/230948, the example would
be
```dart
class A {
m() sync* {
yield* [1];
}
}
```
Inferred type for expression in `yield*` statement is
`List<FutureOr<dynamic>>` after the above CL, while I'd expect it
to be `List<int>`.
The change modified the behaivor while passing the imposed
return type a bit: `InferenceContext.setType` resets the type to `null`
if it's `dynamic`, while the logic that passes the type down explicitly
doesn't do that. My change restores the behavior of resetting the
imposed type to `null` if it's `dynamic`.
Interestingly enough, this is not a problem for function declarations:
`FunctionExpressionResolver.resolve(FunctionExpressionImpl)`
has special clause that resets the imposed type to null. But
for reasons I don't understand `FunctionExpressionResolver` is
used for function declarations but not for method declaration.
Change-Id: I63cfde01f067c25442afed64843861d09c7474a1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231702
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Ilya Yanok <yanok@google.com>
This avoids the need to refer to context types after resolution is
complete.
This is part of a larger effort to elimiate the use of
InferenceContext.getContext and InferenceContext.setType entirely.
Change-Id: Ia3f15080ad8b6f90525577694fefc172faa93286
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231320
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Now that we only use InferenceContext.setType for expressions, this
change consolidates all the call sites to just two places:
- The method ResolverVisitor.analyzeExpression, which is used when
recursively analyzing subexpressions inside expressions and
statements.
- The method InferenceContext.setTypeFromNode, which is used during
AST rewrites to transfer context information from the original node
to the rewritten node.
This is part of a larger effort to elimiate the use of
InferenceContext.getContext and InferenceContext.setType entirely.
Change-Id: Id236bcb1247c09b740bbbad41cb74ecda301cc86
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231181
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Instead of using InferenceContext.getContext and
InferenceContext.setType to associate type inference information with
VariableDeclaration nodes, we pass the information on the stack using
a new FunctionBodyImpl.resolve method. This should be more efficient
for two reasons: it avoids a map lookup, and it avoids the double
dispatch traditionally associated with calling a visitor. It should
also make the code easier to reason about (since it makes the flow of
data in the type inference process more explicit).
This is part of a larger effort to elimiate the use of
InferenceContext.getContext and InferenceContext.setType entirely.
Change-Id: I8a3f3be940acdcd0a2c4ad8ec37b41bafe25c952
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230948
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Instead of using InferenceContext.getContext and
InferenceContext.setType to associate type inference information with
VariableDeclaration nodes, we directly look up the variable type when
we need it. This should be more efficient (since it avoids a map
lookup), and it should make the code easier to reason about (since it
makes the flow of data in the type inference process more explicit).
This is part of a larger effort to elimiate the use of
InferenceContext.getContext and InferenceContext.setType entirely.
Change-Id: I01262fb3c3e6789ee9da924e731d86d99ce3f4de
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230946
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Instead of using InferenceContext.getContext and
InferenceContext.setType to associate type inference information with
ArgumentList nodes, we pass the contextual information around on the
stack. This should be more efficient (since it avoids a map lookup),
and it should make the code easier to reason about (since it makes the
flow of data in the type inference process more explicit).
This is part of a larger effort to elimiate the use of
InferenceContext.getContext and InferenceContext.setType entirely.
Change-Id: I331792cf6d7289a27fc71edfc6af33cd1af5288c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230942
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Rather than do two passes over each collection literal (one to push
contexts down and a second pass to resolve), we pass the contexts down
on the stack during a single resolve pass.
I decided to create an extra data structure to hold the context
information (so I only had one thing to pass around on the stack
rather than four). The extra allocation will carry a small
performance cost. However, I was able to reduce the number of passes
over the collection literal from two to one, replace a chain of
is-tests with a virtual dispatch, and eliminate a double-dispatch in
some cases, so hopefully the benefit of those improvements will more
than offset the cost.
This is part of a larger effort to elimiate the use of
InferenceContext.getContext and InferenceContext.setType entirely.
Change-Id: I949c2c5ef99fc3395de3d67eaa8f326b7af5b158
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231062
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
When a static property lookup fails, the analyzer's error recovery
logic tries to fall back on looking up an instance member. An
unfortunate consequence of this is that the looked-up member may have
a type that refers to unbound type parameters. For example:
class C<T> {
List<T> t = [];
}
var x = C.t; // (1)
Although the line at (1) has an error, the analyzer continues to
analyze it assuming the reference to `t` is valid, producing a static
type for `x` of `List<T>`. But this isn't a valid type because `T`
has no meaning outside the context of the definition of class C.
To avoid unbound type parameters leaking outside the class, we do an
"instantiate to bounds" operation at the time of the error recovery;
for this example that results in a type `List<dynamic>` instead of
`List<T>`.
Change-Id: I763bf32d16345b0a1a6f9f6893e78a138e85c8c2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230460
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>