Skip to content

Commit fdfa977

Browse files
authored
[spec/function] Improve contract docs (#3836)
Move in/out grammar to respective subheadings. Use list for contract expression arguments. Fix grammar for invalid state sentences. Fix wording of postcondition best practice. Mention postcondition identifier is implicitly const. Add anchor for example subheading. Fix Bugzilla 24565 - out contract variable is implicitly const
1 parent c75765a commit fdfa977

File tree

1 file changed

+35
-31
lines changed

1 file changed

+35
-31
lines changed

spec/function.dd

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -179,20 +179,6 @@ $(GNAME InOutContractExpression):
179179
$(GNAME InOutStatement):
180180
$(GLINK InStatement)
181181
$(GLINK OutStatement)
182-
183-
$(GNAME InContractExpression):
184-
$(D in $(LPAREN)) $(GLINK2 expression, AssertArguments) $(D $(RPAREN))
185-
186-
$(GNAME OutContractExpression):
187-
$(D out $(LPAREN) ;) $(GLINK2 expression, AssertArguments) $(D $(RPAREN))
188-
$(D out $(LPAREN)) $(GLINK_LEX Identifier) $(D ;) $(GLINK2 expression, AssertArguments) $(D $(RPAREN))
189-
190-
$(GNAME InStatement):
191-
$(D in) $(GLINK2 statement, BlockStatement)
192-
193-
$(GNAME OutStatement):
194-
$(D out) $(GLINK2 statement, BlockStatement)
195-
$(D out) $(D $(LPAREN)) $(GLINK_LEX Identifier) $(D $(RPAREN)) $(GLINK2 statement, BlockStatement)
196182
)
197183

198184
$(P Function Contracts specify the preconditions and postconditions of a function.
@@ -203,20 +189,27 @@ $(GNAME OutStatement):
203189

204190
$(H3 $(LNAME2 preconditions, Preconditions))
205191

206-
$(P An $(GLINK InContractExpression) is a precondition.)
192+
$(GRAMMAR
193+
$(GNAME InContractExpression):
194+
$(D in $(LPAREN)) $(GLINK2 expression, AssertArguments) $(D $(RPAREN))
207195

208-
$(P The first $(GLINK2 expression, AssignExpression) of the $(GLINK2 expression, AssertArguments)
209-
must evaluate to true. If it does not, the precondition has failed.)
196+
$(GNAME InStatement):
197+
$(D in) $(GLINK2 statement, BlockStatement)
198+
)
210199

211-
$(P The second $(I AssignExpression), if present, must be implicitly convertible to type `const(char)[]`.
212-
)
200+
$(P An $(I InContractExpression) is a precondition.)
201+
202+
* The first $(GLINK2 expression, AssignExpression) of the $(I AssertArguments)
203+
must evaluate to true. If it does not, the precondition has failed.)
204+
205+
* The second $(I AssignExpression), if present, must be implicitly convertible to type `const(char)[]`.
213206

214207
$(P An $(GLINK InStatement) is also a precondition. Any $(GLINK2 expression, AssertExpression) appearing
215208
in an $(I InStatement) will be an $(I InContractExpression).
216209
)
217210

218211
$(P Preconditions must semantically be satisfied before the function starts executing.
219-
If it is not, the program enters an $(I Invalid State).
212+
If a precondition fails, the program enters an $(I Invalid State).
220213
)
221214

222215
$(IMPLEMENTATION_DEFINED Whether the preconditions are actually run or not is implementation defined.
@@ -258,20 +251,29 @@ $(GNAME OutStatement):
258251

259252
$(H3 $(LNAME2 postconditions, Postconditions))
260253

261-
$(P An $(GLINK OutContractExpression) is a postcondition.)
254+
$(GRAMMAR
255+
$(GNAME OutContractExpression):
256+
$(D out $(LPAREN) ;) $(GLINK2 expression, AssertArguments) $(D $(RPAREN))
257+
$(D out $(LPAREN)) $(GLINK_LEX Identifier) $(D ;) $(GLINK2 expression, AssertArguments) $(D $(RPAREN))
262258

263-
$(P The first $(GLINK2 expression, AssignExpression) of the $(GLINK2 expression, AssertArguments)
264-
must evaluate to true. If it does not, the postcondition has failed.)
259+
$(GNAME OutStatement):
260+
$(D out) $(GLINK2 statement, BlockStatement)
261+
$(D out) $(D $(LPAREN)) $(GLINK_LEX Identifier) $(D $(RPAREN)) $(GLINK2 statement, BlockStatement)
262+
)
265263

266-
$(P The second $(I AssignExpression), if present, must be implicitly convertible to type `const(char)[]`.
267-
)
264+
$(P An $(I OutContractExpression) is a postcondition.)
265+
266+
* The first $(GLINK2 expression, AssignExpression) of the $(I AssertArguments)
267+
must evaluate to true. If it does not, the postcondition has failed.
268268

269-
$(P An $(GLINK OutStatement) is also a postcondition. Any $(GLINK2 expression, AssertExpression) appearing
269+
* The second $(I AssignExpression), if present, must be implicitly convertible to type `const(char)[]`.
270+
271+
$(P An $(I OutStatement) is also a postcondition. Any $(GLINK2 expression, AssertExpression) appearing
270272
in an $(I OutStatement) will be an $(I OutContractExpression).
271273
)
272274

273275
$(P Postconditions must semantically be satisfied after the function finishes executing.
274-
If it is not, the program enters an $(I Invalid State).
276+
If a postcondition fails, the program enters an $(I Invalid State).
275277
)
276278

277279
$(IMPLEMENTATION_DEFINED Whether the postconditions are actually run or not is implementation defined.
@@ -281,8 +283,9 @@ $(GNAME OutStatement):
281283
$(I AssignExpression).
282284
)
283285

284-
$(BEST_PRACTICE Use postconditions to validate that the input arguments and return value have values that are
285-
expected by the function.)
286+
$(BEST_PRACTICE Use postconditions to validate that on leaving the function:)
287+
* Any mutable input arguments each have the expected value/range of values.
288+
* Any return value has a correct value/range of values.
286289

287290
$(BEST_PRACTICE Since postconditions may or may not be actually checked at runtime, avoid
288291
using postconditions that have side effects.)
@@ -317,9 +320,10 @@ $(GNAME OutStatement):
317320
---
318321

319322
$(P The optional identifier in either type of postcondition is set to the return value
320-
of the function, and can be accessed from within the postcondition.)
323+
of the function, and can be accessed from within the postcondition.
324+
It is implicitly `const`.)
321325

322-
$(H3 Example)
326+
$(H3 $(LNAME2 example-contracts, Example))
323327

324328
---
325329
int fun(ref int a, int b)

0 commit comments

Comments
 (0)