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

Take exhaustive match into account when checking for field initialization #4006

Merged
merged 1 commit into from
Feb 15, 2022

Conversation

SeanTAllen
Copy link
Member

Previously, exhaustive matches were handled after we verified that an object's fields
were initialized. This lead to the code such as the following not passing compiler
checks:

primitive Foo
  fun apply() : (U32 | None) => 1

type Bar is (U32 | None)

actor Main
  let bar : Bar

  new create(env : Env) =>
      match Foo()
      | let result : U32 =>
          bar = result
      | None =>
          bar = 0
      end

This commit moves field initialization checking to the verify pass so that it
comes after the expression pass when exhaustiveness checking is done. This also
moves code to patchup matches from the refer pass to a new completeness pass
that comes after the expression pass. The new completeness_match code is
identical to refer_match code except that an else clause with a value of
TK_NONE no longer means a clause exists. In the exhaustiveness checks in the
expression pass, any non-exhaustive else clause that was a TK_NONE has since
been replaced with a else None so, by the time we get to completeness,
TK_NONE literally means "there's no else clause".

Closes #3615

@SeanTAllen SeanTAllen requested a review from a team February 14, 2022 20:26
@SeanTAllen SeanTAllen added the changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge label Feb 14, 2022
@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Feb 14, 2022
@SeanTAllen
Copy link
Member Author

Windows failure can be ignored.

…tion

Previously, exhaustive matches were handled after we verified that an object's fields
were initialized. This lead to the code such as the following not passing compiler
checks:

```pony
primitive Foo
  fun apply() : (U32 | None) => 1

type Bar is (U32 | None)

actor Main
  let bar : Bar

  new create(env : Env) =>
      match Foo()
      | let result : U32 =>
          bar = result
      | None =>
          bar = 0
      end
```

This commit moves field initialization checking to the verify pass so that it
comes after the expression pass when exhaustiveness checking is done. This also
moves code to patchup matches from the refer pass to a new completeness pass
that comes after the expression pass. The new `completeness_match` code is
identical to `refer_match` code except that an else clause with a value of
`TK_NONE` no longer means a clause exists. In the exhaustiveness checks in the
expression pass, any non-exhaustive else clause that was a `TK_NONE` has since
been replaced with a `else None` so, by the time we get to completeness,
`TK_NONE` literally means "there's no else clause".

Closes #3615
@SeanTAllen SeanTAllen merged commit b36c9a5 into main Feb 15, 2022
@SeanTAllen SeanTAllen deleted the issue-3615 branch February 15, 2022 20:31
@ponylang-main ponylang-main removed the discuss during sync Should be discussed during an upcoming sync label Feb 15, 2022
github-actions bot pushed a commit that referenced this pull request Feb 15, 2022
github-actions bot pushed a commit that referenced this pull request Feb 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parser does not detect field initialization in a constructor despite exhaustive match clauses
3 participants