-
- Notifications
You must be signed in to change notification settings - Fork 1.5k
strict effects #18777
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
strict effects #18777
Conversation
| Interesting, ...so this is like |
| bugs: when defined case6: proc fn(a: int, p1, p2: proc()) {.effectsOf: p1.} = # proc fn(a: int, p1, p2: proc()) = # ditto if a == 7: p1() if a<0: raise newException(ValueError, $a) proc main() {.raises: [ValueError].} = # fn(1, proc() = raise newException(OsError, "foo"), proc()=discard) # ok: can raise an unlisted exception: ref OSError is correct fn(1, proc()=discard, proc() = raise newException(IOError, "foo")) # bug: `can raise an unlisted exception: ref IOError` shouldn't be generated because of `effectsOf: p1` main()also this, slightly different as it involves parent scope: when defined case8: proc bar(a: proc()) = proc baz(b: proc()) {.effectsOf: a.} = a() # not calling b but calling a param from parent scope proc x()=raise newException(ValueError, "") baz(x) proc main(){.raises: [].} = bar(proc()=raise newException(OsError, "")) main()produces incorrect diagnostic (in particular, ValueError is never raised) |
| if r.sym.owner == owner: | ||
| incl r.sym.flags, sfEffectsDelayed | ||
| else: | ||
| localError(c.config, n.info, errGenerated, "parameter cannot be declared as .effectsOf") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this should be legal:
proc bar(a: proc()) = proc baz(b: proc()) {.effectsOf: [a].} = a()
Should be done later as it's much harder to implement. I also doubt this will ever be needed. |
| sfUsedInFinallyOrExcept # symbol is used inside an 'except' or 'finally' | ||
| sfSingleUsedTemp # For temporaries that we know will only be used once | ||
| sfNoalias # 'noalias' annotation, means C's 'restrict' | ||
| sfEffectsDelayed # an 'effectsDelayed' parameter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the bugs i mentioned in #18777 (comment) is still there, it looks like the compiler ignores the effectsOf: p1 annotations and assumes every param is called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your snippet was even added as a test case, it works...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, i was missing {.experimental: "strictEffects".}; however, the problem remains if i remove the explicit annotaton:
when defined case9: {.push warningAsError[Effect]: on.} {.experimental: "strictEffects".} # proc fn(a: int, p1, p2: proc()) {.effectsOf: p1.} = # proc fn(a: int, p1, p2: proc()) {.effectsOf: p2.} = proc fn(a: int, p1, p2: proc()) = if a == 7: p1() if a<0: raise newException(ValueError, $a) proc main() {.raises: [ValueError].} = fn(1, proc()=discard, proc() = raise newException(IOError, "foo")) main() this gives:
t12754.nim(111, 7) Error: fn(1, proc () = discard , proc () = raise
(ref IOError)(msg: "foo", parent: nil)) can raise an unlisted exception: Exception [Effect]
but compiler should infer that this is {.effectsOf: p1.} since only p1 is called, not p2, and then it should not issue any warning since main can't raise anything other than ValueError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no inference for the .effectsOf pragma and there is no plan to add any, it would repeat the mistakes of "sink inference".
| In a follow up PR we should patch |
* fixes nim-lang#17369 * megatest is green for --cpu:arm64 * docgen output includes more tags/raises * implemented 'effectsOf' * algorithm.nim: uses new effectsOf annotation * closes nim-lang#18376 * closes nim-lang#17475 * closes nim-lang#13905 * allow effectsOf: [a, b] * added a test case * parameters that are not ours cannot be declared as .effectsOf * documentation * manual: added the 'sort' example * bootstrap with the new better options
Todo:
Will fix:
CatchableErrorerror reported when adding procedure to table #18376raisestracking broken for... proc types in tables? #17382raisesnot enforced for proc type parameters #17475raisesnot preseved inproctypes, invalid "can raise any" error on compile #13905