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

SIP-56: Better foundations for match types #18262

Merged
merged 17 commits into from
Dec 18, 2023

Commits on Dec 18, 2023

  1. Introduce MatchTypeCaseSpec to categorize match type cases.

    For now, we only have `SubTypeTest` and `LegacyPatMat`.
    
    * `SubTypeTest` is used when there is no type capture.
    * `LegacyPatMat` is used when there are captures.
    
    In the match type reduction algorithm, we already have a simpler
    path for `SubTypeTest`.
    
    The `LegacyPatMat` path is basically the same as before, but with
    static knowledge that we have an `HKTypeLambda`.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    c96d847 View commit details
    Browse the repository at this point in the history
  2. Use new specced match types for class type constructors.

    This is the first step in using the new specified algorithm for
    match type reduction. When the pattern of a case satisfies
    elibility conditions, we use the new algorithm. Otherwise, we fall
    back on the legacy algorithm.
    
    To be eligible, a pattern with at least one capture must be:
    an applied *class* type constructor whose arguments are all:
    - either a type capture,
    - or a fully defined type that contains no inner capture,
    - or the argument must be in covariant position and recursively
      qualify to the elibility conditions.
    
    With those criteria, all the type captures can be *computed* using
    `baseType`, instead of inferred through the full `TypeComparer`
    machinery.
    
    The new algorithm directly handles preventing widening abstract
    types, when doing so leads to captures being under-defined. With
    the legacy algorithm, this prevention is scattered elsewhere in
    the type comparer. Making it centralized improves the error
    messages in those situations; it seems they were previously
    entirely misleading (see changed check files).
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    5260c60 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    cc41d48 View commit details
    Browse the repository at this point in the history
  4. Short-circuit match type cases with missing captures in their patterns.

    So that they do not fall into the legacy fallback.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    067b828 View commit details
    Browse the repository at this point in the history
  5. Use the specced match types for abstract tycons in patterns.

    An abstract tycon can be matched if it is exactly equal to the
    scrutinee's tycon.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    aa8d348 View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    97725d7 View commit details
    Browse the repository at this point in the history
  7. Report a compile error on illegal match types.

    The error can be silenced with `-source:3.3`. In that case,
    illegal match types are reduced using the legacy matching
    algorithm, as before.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    7ab7b0f View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    ec94ff5 View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    1b2a16e View commit details
    Browse the repository at this point in the history
  10. Be more specific about higher-kinded types in provablyDisjoint.

    Previously the disjointnessBoundary of HKTypeLambda's was
    implicitly their `resultType`, through the use of
    `superTypeNormalized`. This was fine as long as both sides of
    `provablyDisjoint` ended up being HKTypeLambda's at the same time,
    but this may not always be the case (notably with any-kinded types).
    
    It is safer to consider type lambdas as boundaries themselves, and
    explicitly recurse on the result types when arities match.
    
    This change surfaced a weird case in `TypeTestsCasts`, which called
    `provablyDisjoint` with ill-kinded types. We now explicitly apply
    what I suspect are partially-erased types to wildcards to recover
    appropriate kinds.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    f432d08 View commit details
    Browse the repository at this point in the history
  11. Do not use provablyEmpty anymore; use S <: T + provablyDisjoint(S, T)…

    … instead.
    
    Fundamentally, the `provablyEmpty(scrut)` test was meant to prevent
    situations where both `scrut <: pattern` and
    `provablyDisjoint(scrut, pattern)` are true. That is a problem
    because it allows a match type to reduce in two different ways
    depending on the context.
    
    Instead, we basically use that combination of `scrut <: pattern`
    and `provablydisjoint(scrut, pattern)` as the *definition* for
    `provablyEmpty`. When both those conditions arise together, we
    refuse to reduce the match type.
    
    This allows one example to pass that did not pass before, but that
    particular example does not seem to cause unsoundness. In a sense,
    `provablyEmpty` was too strong here.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    c653793 View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    16cf4f2 View commit details
    Browse the repository at this point in the history
  13. Under -source:3.3 and below, always use the legacy match type algorithm.

    This should improve consistency with the actual earlier compilers,
    since it means the matching algorithm will be intact.
    
    Note that the new behavior of `provablyDisjoint` is always applied,
    even under `-source:3.3`. This includes using `provablyDisjoint`
    instead of `provablyEmpty`. So it is still possible that something
    behaves differently than the actual earlier compilers.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    c8b4da8 View commit details
    Browse the repository at this point in the history
  14. In type assigner for Apply, carry ErrorType's from the fn.

    This was already done for `TypeApply` in
    cecfb61. We apply the same logic
    for `Apply` nodes.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    2dd9f45 View commit details
    Browse the repository at this point in the history
  15. Fix 1 cause of infinite recursion in the new provablyDisjoint.

    And add an additional test for another cause of infinite recursion
    that was fixed earlier.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    ec097a9 View commit details
    Browse the repository at this point in the history
  16. Demonstrate more potential unsoundness with a CCE reproducer.

    This additional test demonstrates that relaxing the `isConcrete`
    in a particular way around `AndType`s would also cause unsoundness.
    
    This justifies new failures in the Open Community Build.
    sjrd committed Dec 18, 2023
    Configuration menu
    Copy the full SHA
    b5a4ca5 View commit details
    Browse the repository at this point in the history
  17. Configuration menu
    Copy the full SHA
    c3b9d9b View commit details
    Browse the repository at this point in the history