Files
sdk/pkg
Paul Berry 83bea5cfbb Do an extra round of type inference before resolving deferred closures.
The order of operations for type inference of a generic invocation is
now:

1. Create some constraints on type parameters by trying to match the
   return type of the invocation target as a subtype of the incoming
   type context.  (For a constructor invocation, the return type of
   the invocation target is considered the raw uninstantiated type of
   the class enclosing the constructor declaration.)

2. Downwards inference: partially solve the set of type constraints
   accumulated in step 1, to produce a preliminary mapping of type
   parameters to type schemas.

3. Recursively infer all arguments to the invocation, except that if
   experimental feature `inference-update-1` is enabled, skip any
   arguments that are function literals (a.k.a. "closures").  Obtain
   the type contexts for the recursive inference by substituting the
   preliminary mapping (from step 2) into the corresponding parameter
   types of the invocation target.  For each argument that is
   recursively inferred, create additional constraints on type
   parameters using the resulting static type.

4. If no arguments were skipped during step 3, go to step 7 (this
   always happens if `inference-update-1` is disabled).

5. Horizontal inference: partially solve the set of type constraints
   accumulated so far, to produce an updated preliminary mapping of
   type parameters to type schemas.

6. Recursively infer all of the invocation arguments that were
   previously skipped.  As in step 3, obtain the type contexts for the
   recursive inference by substituting the preliminary mapping (this
   time from step 5) into the corresponding parameter types of the
   invocation target.  Again, for each argument that is recursively
   inferred, create additional constraints on type parameters using
   the resulting static type.

7. Upwards inference: solve the set of type constraints accumulated so
   far, to produce a final mapping of type parameters to types.  Check
   that each type is a subtype of the bound of its corresponding type
   parameter.

8. Check that the static type of each argument is assignable to the
   type obtained by substituting the final mapping (from step 7) into
   the corresponding parameter type of the invocation target.

9. Finally, obtain the static type of the invocation by substituting
   the final mapping (from step 7) into the return type of the
   invocation target.

This addresses simpler cases of
https://github.com/dart-lang/language/issues/731.  Note that if
experimental flag `inference-update-1` is disabled, the behavior is
unchanged.

Note that steps 2 and 5 use the same algorithm as each other (they
only differ in how many type constraints have been accumulated so
far), so I've renamed the function that performs it from
`downwardsInfer` to `partialInfer`.

Change-Id: I10d3288d4f4ba9e2b6bc18409186ddc67ca2ee9d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238881
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2022-03-25 22:07:50 +00:00
..
2022-03-09 11:53:34 +00:00
2022-03-18 19:55:51 +00:00
2022-03-17 23:41:27 +00:00
2022-03-17 23:41:27 +00:00

Package validation

The packages in pkg/ are automatically validated on the LUCI CI bots. The validation is largely done by the tools/package_deps package; it can be tested locally via:

dart tools/package_deps/bin/package_deps.dart

Packages which are published

There are several packages developed in pkg/ which are published to pub. Validation of these packages is particularly important because the pub tools are not used for these packages during development; we get our dependency versions from the DEPS file. Its very easy for the dependencies specified in a package's pubspec file to get out of date wrt the packages and versions actually used.

In order to better ensure we're publishing correct packages, we validate some properties of the pubspec files on our CI system. These validations include:

  • that the dependencies listed in the pubspec are used in the package
  • that all the packages used by the source are listed in the pubspec
  • that we don't use relative path deps to pkg/ or third_party/ packages

Packages which are not published

For packages in pkg/ which we do not intend to be published, we put the following comment in the pubspec.yaml file:

# This package is not intended for consumption on pub.dev. DO NOT publish.
publish_to: none

These pubspecs are still validated by the package validation tool. The contents are more informational as the pubspecs for these packages are not consumed by the pub tool or ecosystem.

We validate:

  • that the dependencies listed in the pubspec are used in the package
  • that all the packages used by the source are listed in the pubspec
  • that a reference to a pkg/ package is done via a relative path dependency