Consider the following code:
void f<T extends void Function(int)>(List<T> x) {
x.first(0);
}
While analyzing the expression `x.first(0)`, the analyzer has to do two things:
- Convert the AST representation from a MethodInvocation (which is
what was initially parsed) to a FunctionExpressionInvocation
targeting a PrefixedIdentifier. This reflects the fact that the
invocation isn't a method invocation after all; it's a function call
invocation applied to a property get.
- Convert the static type of `x.first` from `T` to its bound, `void
Function(int)`, in order to type check the invocation. This is done
using the `TypeSystemImpl.resolveToBound` method.
Previously, `TypeSystemImpl.resolveToBound` was called as part of
converting the AST representation, and the resolved bound (`void
Function(int)` in this example) was stored as the static type of the
FunctionExpressionInvocation target. This led to some minor
inaccuracies in the AST representation (since the type returned by
`TypeSystemImpl.resolveToBound` is *not* the correct type of the
FunctionExpressionInvocation target).
With this change, the call to `TypeSystemImpl.resolveToBound` happens
during resolution of the FunctionExpressionInvocation instead,
allowing the target of the FunctionExpressionInvocation to retain its
correct static type.
I'm in the middle of a larger arc of work trying to introduce a new,
simpler mechanism for flow analysis to be told about the static types
of property gets, and part of that arc of work will involve
introducing a temporary check to verify that the old and new
mechanisms see the same static types. Fixing this incorrect type will
allow the temporary check to pass.
This change also has the side effect of fixing
https://github.com/dart-lang/sdk/issues/56907 (Analyzer fails to
propery type check invocations of complex expressions whose type is a
type parameter). This bug was happening in circumstances where a
FunctionExpressionInvocation arises directly from parsing (rather than
being created from a MethodInvocation), and the static type of the
target is a type variable. Previously, the analyzer was failing to
convert the static type to its bound when analyzing the
FunctionExpressionInvocation, so it was failing to type check the
invocation. Moving the call to `TypeSystemImpl.resolveToBound` into
FunctionExpressionInvocation resolution ensures that the type is
properly resolved to its bound in _all_ circumstances where a
FunctionExpressionInvocation occurs.
Fixes https://github.com/dart-lang/sdk/issues/56907.
Bug: https://github.com/dart-lang/sdk/issues/56907
Change-Id: Id648d5289a6cabe95b8410abd19898acb97fc5e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390661
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Today, most tests that touch on a behavior variation end up
skipping expectations or the entirety of a test for some
testing configurations. Moving forward, we'd like skip less
and try to account for the behavior variations if that's
reasonable.
This CL shows an approach to improve our test coverage for
behavior variations. We introduce two new methods to
[Expect] that allow us to conditionally check that a
function throws, depending on variation predicates.
The CL changes expectations for errors that don't occur
when dart2js omits parameter type checks or implicit
downcasts.
Note: originally I had the intention to introduce a name
parameter to `Expect.throws` and `Expect.throwsTypeError` to
avoid introducing a new API. However, because these APIs are
used for testing core language features, such as function
parameters themselves, we decided to keep the use of
features in these APIs as simple as it can be.
CoreLibraryReviewExempt: no public library semantic change - only improving test coverage under variations
Change-Id: I531657622655778491eaca8b37ba69ffaab559fc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/351340
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
This updates tests to start using `checkedParamters` and
`checkedImplicitDowncasts` instead of `dart2jsProductionMode`
CoreLibraryReviewExempt: no semantic changes - only updates to use new pkg/expect variations properties
Change-Id: Ie717b4fd44590ff1f977142cf5802c4aace34dea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346910
Reviewed-by: Mayank Patke <fishythefish@google.com>
Language spec does not require that evaluations of the same function
literal should create distinct objects. Remove the parts in `Function`
documentation to reflect that.
Also fixes formatting of markdown.
Invalid test file (with Dart 2 and 3 versions) removed: the tests assume
function literals won't be lifted to top-level.
Change-Id: Ib7a9464ad992cf461e77ef2d8ef336c7b0f4875a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/269721
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Marks `Function` as an extensible type so that DDC knows to use the
symbolized version of the equals operator.
The `Function` class at runtime already has its equals method attached
as the "symbolized" version. Consider `a == b`. When DDC knows `a` is
statically a raw `Function` and non-nullable (more likely with sound
null safety) the generated code should call the symbolized equals
member ex: `a[$_equals](b)`. Without this change the generated code
would be `a.equals(b)` and fail at runtime because the method does
not exist.
With this change co19_2/LibTest/core/Function/operator_eq_A01_t01
starts passing.
Change-Id: I80dd2abbbb04f1b7ab7e21dd14561a45f6e81459
Fixes: https://github.com/dart-lang/sdk/issues/45601
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194204
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>