Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: docs/language/informal/assert-in-initializer-list.md

Issue 2927933002: Add informal specification of asserts in initializer lists. (Closed)
Patch Set: Address comments. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Asserts in Initializer List
2 [lrn@google.com](mailto:lrn@google.com)
3 Version 1.1 (2017-06-08)
4 Status: Accepted, Informally specified
5
6 (See: http://dartbug.com/24841, http://dartbug.com/27141)
7
8 In some cases, you want to validate your inputs before creating an instance, eve n in a const constructor. To allow that, we have tested the possibility of allow ing assert statements in the initializer list of a generative constructor.
9
10 We started by implementing the feature in the VM behind a flag, with at syntax s upport from the analyzer and the formatter.
11
12 This was as successful experiment, and the feature is actively being used by the Flutter project, so now we promote the experimental feature to a language featu re.
13
14 ## Syntax
15
16 The syntax is changed to allow an assert statement without trailing semicolon (j ust the `assert(condition[, message])`) to appear as an item in the initializer list.
17 Example:
18
19 ```dart
20 C(x, y) : this.foo = x, assert(x < y), this.bar = y;
21 ```
22
23 The assert can occur anywhere in the list where an initializing assignment can.
24
25 That is, the grammar changes so that *superCallOrFieldIntitializer* can also pro duce an assert.
26
27 For simplicity, we add a new production for the assert-without-the-semicolon, an d reuse that in both the initializer list and the *assertStatement*.
28
29 > *superCallOrFieldInitializer*:
30 > &nbsp;&nbsp;&nbsp; **super** arguments
31 > &nbsp;&nbsp;| **super** ‘.’ identifier arguments
32 > &nbsp;&nbsp;| fieldInitializer
33 > &nbsp;&nbsp;| assertion
34 > &nbsp;&nbsp;;
35 >
36 > assertion: **assert** ‘(' expression (‘,' expression)? ‘)' ;
37 >
38 > assertStatement: assertion ‘;' ;
39
40 The *superCallOrFieldInitializer* production will probably change name too, perh aps to *initializerListEntry*, but that's not important for the behavior.
41
42 ## Semantics
43
44 The initializer list assert works the same way as an assert statement in a funct ion body (with special treatment for asserts in a const constructor's initialize r list, see next section). The assert expressions are evaluated in the initializ er list scope, which does not have access to `this`, exactly the same way that a n assert statement would be evaluated in the same scope. The runtime behavior is effectively:
45
46 1. evaluate the condition expression (in the initializer list scope) to a resul t, `o`.
47 1. If `o` implements `Function`, call it with zero arguments and let `r` be the return value,
48 1. otherwise let `r` = `o`.
49 1. Perform boolean conversion on `r`. This throws if `r` is not an instance of `bool`.
50 1. if `r` isn't `true`,
51 a. if there is a message expression, evaluate that to a value `m`
52 b. otherwise let `m` be `null`
53 c. then throw an `AssertionError` with `m` as message.
54
55 Statically, like in an assertion statement, it's a warning if the static type of the condition expression isn't assignable to either `bool` or `bool Function()` .
56
57 Here step 2, 4 and 5a may throw before reaching step 5c, in which case that is t he effect of the assert.
58
59
60 The assert statement is evaluated at its position in the initializer list, relat ive to the left-to-right evaluation of initializer list entries.
61
62 As usual, assert statements have no effect unless asserts are enabled (e.g., by running in checked mode).
63
64
65 ## Const Semantics
66
67 If the constructor is a const constructor, the condition and message expressions in the assert must be potentially compile-time constant expressions. If any of them aren't, it is a compile-time error, the same way a non-potentially compile- time constant initializer expression in the initializer list is.
68
69 Further, the condition expression should not evaluate to a function, since we ca n't call functions at compile time. We can't prevent it from evaluating to a fun ction, but the function cannot not be called. To account for this, the behavior above is changed for const constructor initializer list asserts:
70
71 *Step 2 above is dropped for an assert in a const constructor initializer list.*
72
73 The change is entirely syntax driven - an assert inside a const constructor init ializer list does not test whether the expression is a function, not even when t he constructor is invoked using `new`.
74 This change from the current specification is needed because asserts previously couldn't occur in a (potentially) const context[^1].
75
76 During a const constructor invocation (that is, when the const constructor is in voked using the `const` prefix), if the assert fails, either due to boolean conv ersion when `r` is not a boolean value or due to assertion failure when `r` is ` false`, it is treated like any other compile-time throw in a compile-time consta nt expression, and it causes a compile-time error.
77
78
79 ## Revisions
80
81 1.0 (2016-06-23) Initial specification.
82
83 1.1 (2017-06-08) Handle second expression in asserts as well, add grammar rules.
84
85
86 ## Notes
87
88 [^1]:
89 If we ever add "const functions" which can be "called" in a const context, then we may allow them here, but other functions are still compile time errors.
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698