Conversation
This reverts commit 0b571fe.
ArquintL
left a comment
There was a problem hiding this comment.
Looks overall good to me but I've left some requests for small changes
| // (João) Conditional termination measures are a very rarely used feature. They allow defining termination measures | ||
| // case-per-case. However, for pure or ghost functions and methods, we need to show that all conditions provided |
There was a problem hiding this comment.
| // (João) Conditional termination measures are a very rarely used feature. They allow defining termination measures | |
| // case-per-case. However, for pure or ghost functions and methods, we need to show that all conditions provided | |
| // (João) Conditional termination measures are a very rarely used feature. They allow defining termination measures | |
| // case-by-case. However, for pure or ghost functions and methods, we need to show that all conditions provided |
| val hasConditionalTerminationMeasureErrors = { | ||
| val conditionalMeasure = spec.terminationMeasures.find(_.isConditional) | ||
| conditionalMeasure match { | ||
| case Some(n) => error(n, "Conditional termination measures are not allowed in pure members.") |
There was a problem hiding this comment.
| case Some(n) => error(n, "Conditional termination measures are not allowed in pure members.") | |
| case Some(n) => error(n, "Conditional termination measures are not allowed for pure or ghost functions and methods.") |
| } | ||
|
|
||
| private[typing] def wellDefIfPureMethod(member: PMethodDecl): Messages = { | ||
| if (member.spec.isPure) { |
There was a problem hiding this comment.
this if condition is redundant
| @@ -61,15 +74,23 @@ trait GhostMemberTyping extends BaseTyping { this: TypeInfoImpl => | |||
|
|
|||
| private[typing] def wellDefIfPureFunction(member: PFunctionDecl): Messages = { | |||
| if (member.spec.isPure) { | |||
There was a problem hiding this comment.
this if condition is redundant
| // spec must come from a ghost or pure function | ||
| private[typing] def wellFoundedIfNeeded(spec: PFunctionSpec): Messages = { |
There was a problem hiding this comment.
three comments:
- can we change the behavior such that this function can be called for any spec and internally checks whether it's a spec for a ghost or pure function / method? That's the intuition I have for these
wellFoundedIf...functions. Alternatively, please add a require stmt that checks this assumption - Maybe I'm missing something but isn't this function only called for explicitly ghost functions and methods? To me, it seems like we do not call this function for actual pure functions and methods
- can we rename this function? Without looking at its implementation, I do not have any clue what
Neededis supposed to do. What aboutwellFoundedIfGhostOrPure?
| //:: ExpectedOutput(type_error) | ||
| decreases _ if b |
There was a problem hiding this comment.
| //:: ExpectedOutput(type_error) | |
| decreases _ if b | |
| //:: ExpectedOutput(type_error) | |
| decreases _ if b // we syntactically disallow conditional termination measures for members that must terminate |
| // Type error, pure function does not have termination measures. | ||
| //:: ExpectedOutput(type_error) | ||
| pure | ||
| // Type error, pure function cannot have variadic parameters. | ||
| //:: ExpectedOutput(type_error) | ||
| M(a ...int) int |
There was a problem hiding this comment.
I'd split the errors into separate interface functions. Furthermore, I find it a bit funny that one error occurs at the pure keyword whereas the other errors occur at the parameter declaration site but that's just an artifact of how we type-check. We could consider making the following declarations one-liners such that the testcases are not overly restrictive (should we ever indicate missing termination measures, e.g., at the function name
| // Type error, pure function does not have termination measures. | |
| //:: ExpectedOutput(type_error) | |
| pure | |
| // Type error, pure function cannot have variadic parameters. | |
| //:: ExpectedOutput(type_error) | |
| M(a ...int) int | |
| // Type error, pure function does not have termination measures. | |
| //:: ExpectedOutput(type_error) | |
| pure | |
| M1(a int) int | |
| // Type error, we do not permit conditional termination measures for members that must terminate | |
| //:: ExpectedOutput(type_error) | |
| decreases if a == 42 | |
| pure | |
| M2(a int) int | |
| decreases | |
| pure | |
| // Type error, pure function cannot have variadic parameters. | |
| //:: ExpectedOutput(type_error) | |
| M3(a ...int) int | |
| decreases | |
| pure | |
| // Type error, pure function must have exactly one return parameter | |
| //:: ExpectedOutput(type_error) | |
| M4(a int) |
This PR fixes issue #841 and applies the following changes: