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

[FORK] Add runtime type check for function return types #1209

Merged
merged 6 commits into from
May 10, 2023

Conversation

imalsogreg
Copy link
Contributor

@imalsogreg imalsogreg commented Apr 27, 2023

TODO:

  • Benchmarks (in a new PR)

Runtime type checking previously ignored user's type annotations for a function's return type. This repl code would run to completion, even though it is not well typed:

(module m g
  (defcap g () true)

  ;; `foo` declares that it returns a string, but it actually returns integer
  (defun foo:string () 1)

  ;; This function calls `foo`. It fails to `typecheck`, but still succeeds
  ;; at runtime to use `foo`'s integer return value.
  (defun use_foo:integer () (foo) + 2))

(m.use_foo)

This PR adds runtime type checking to function application, ensuring that the body evaluates to a term that has the type declared in the function's type signature.

The typechecking is behind a feature flag in case previous contracts made use of this accidental behavior.

Without the feature flag:

pact> (m.use_foo)
2

With the feature flag:

pact> (env-exec-config ["DisablePact46"])
pact> (m.use_foo)
<interactive>:7:28:Error: Type error: expected string, found integer
 at <interactive>:0:0: (use_foo)

src/Pact/Eval.hs Outdated Show resolved Hide resolved
src/Pact/Eval.hs Outdated
guardRecursion fname mod_ $ appCall fa ai args' $ fmap (gas,) $
reduceBody body

whenExecutionFlagSet FlagDisablePact46 $
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be something like unlessExecutionFlagSet FlagDisablePact47? It seems odd that I would want this 4.7 functionality when I'm disabling 4.6 functionality...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be DisablePact47

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see how the flags are meant to be read now and updated the PR. DisablePact47 is the only flag used.

Type checking happens unless DisablePact47 is set.

The tests first use normal behavior (no flag set, typechecking turned on), then they use the prior behavior (DisablePact47 is set, typechecking turned off).

tests/pact/tc.repl Outdated Show resolved Hide resolved
tests/pact/tc.repl Outdated Show resolved Hide resolved
@sirlensalot
Copy link
Contributor

A general comment/question: one reason in the past this was avoided was that since natives typecheck, and arguments to user functions are typechecked, return-value typechecking would only avoid typechecking for toplevel functions, since any other application would get caught via being computed on elsewhere.

With this change we are thus typechecking intermediate values twice.

Unfortunately, our benchmarks do not cover user function applications which is regrettable. I might suggest we open a separate PR with some user-application benchmarks -- and we'd want to have them with objects and lists since these are the most expensive to typecheck -- get that merged, and then we could compare this PR to master. Thoughts?

@imalsogreg
Copy link
Contributor Author

imalsogreg commented Apr 27, 2023

@sirlensalot Good point about performance. We could either add benchmarking code, measure replay time, or both. Is replay time a good enough metric for now, adding benchmarks as needed if replay results are ambiguous?

After some more discussion, yah I think benchmarking makes sense.

tests/pact/tc.repl Outdated Show resolved Hide resolved
tests/pact/tc.repl Outdated Show resolved Hide resolved
tests/pact/tc.repl Outdated Show resolved Hide resolved
@emilypi
Copy link
Member

emilypi commented May 1, 2023

@imalsogreg if you vendor in the changes in #1212, we should have this PR passing.

@imalsogreg imalsogreg force-pushed the greg/check-function-return-annotations branch from 8a7d09a to 0fcd8c0 Compare May 1, 2023 19:33
@imalsogreg
Copy link
Contributor Author

@emilypi you are correct! So now I just need to add benchmarks and do the replay.

Copy link
Contributor

@sirlensalot sirlensalot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with small spellcheck

tests/pact/tc.repl Outdated Show resolved Hide resolved
imalsogreg and others added 2 commits May 10, 2023 07:34
Co-authored-by: Stuart Popejoy <8353613+sirlensalot@users.noreply.github.com>
@imalsogreg imalsogreg merged commit a33ebb8 into master May 10, 2023
@imalsogreg imalsogreg deleted the greg/check-function-return-annotations branch May 10, 2023 15:43
rsoeldner added a commit that referenced this pull request May 18, 2023
sirlensalot added a commit that referenced this pull request May 20, 2023
* Revert "[FORK] Add runtime type check for function return types (#1209)"

This reverts commit a33ebb8.

* rep 4.7.1 release

* add runtime return tc flag `DisableReturnRTC`

* update CHANGELOG.md

* Reverse direction of feature flag

* fix haddock

* Revert "fix haddock"

This reverts commit 503e083.

* Revert "Reverse direction of feature flag"

This reverts commit 2127f79.

* address comments

* address missing newline

* unambiguous name

* Update tests/pact/tc.repl

Co-authored-by: Stuart Popejoy <8353613+sirlensalot@users.noreply.github.com>

---------

Co-authored-by: Emily Pillmore <emily@kadena.io>
Co-authored-by: Stuart Popejoy <8353613+sirlensalot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants