Skip to content

Commit d925d1f

Browse files
authored
Add rules about super and extension types to wildcard spec (#3729)
Add rules about super and extension types to wildcard spec
1 parent bb23c2b commit d925d1f

File tree

1 file changed

+96
-11
lines changed

1 file changed

+96
-11
lines changed

working/wildcards/feature-specification.md

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Author: Bob Nystrom
44

55
Status: In-progress
66

7-
Version 1.0
7+
Version 1.1
88

99
Pattern matching brings a new way to declare variables. Inside patterns, any
1010
variable whose name is `_` is considered a "wildcard". It behaves like a
@@ -99,8 +99,8 @@ A *local declaration* is any of:
9999
* For loop variable declarations.
100100
101101
```dart
102-
for (_ = 0;;) {}
103-
for (_ in list) {}
102+
for (int _ = 0;;) {}
103+
for (var _ in list) {}
104104
```
105105
106106
* Catch clause parameters.
@@ -117,11 +117,12 @@ A *local declaration* is any of:
117117
118118
```dart
119119
class T<_> {}
120+
void genericFunction<_>() {}
120121
121122
takeGenericCallback(<_>() => true);
122123
```
123124
124-
A local declaration whose name is `_` does not bind anything to that name. This
125+
A local declaration whose name is `_` does not bind that name to anything. This
125126
means you can have multiple local declarations named `_` in the same namespace
126127
without a collision error. The initializer, if there is one, is still executed,
127128
but the value is not accessible.
@@ -138,12 +139,12 @@ class C {
138139
var _ = 'bound';
139140
140141
test() {
141-
print(_); // Prints "bounnd".
142+
print(_); // Prints "bound".
142143
}
143144
}
144145
```
145146

146-
Likewise with a top-level named `_`:
147+
Likewise with a top-level declaration named `_`:
147148

148149
```dart
149150
var _ = 'ok';
@@ -207,8 +208,8 @@ quite confusing. In practice, we expect reasonable users will not name fields
207208

208209
### Initializing formals
209210

210-
An initializing formal named `_` does still initialize a field named `_` (and
211-
you can still have a field with that name):
211+
A positional initializing formal named `_` does still initialize a field
212+
named `_` (and you can still have a field with that name):
212213

213214
```dart
214215
class C {
@@ -218,17 +219,29 @@ class C {
218219
}
219220
```
220221

222+
*Note that it is already a compile-time error if a named initializing
223+
formal has the name `_`. This is a special case of the rule that it is an
224+
error for a named formal parameter to have a name that starts with `_`.*
225+
226+
```dart
227+
class C {
228+
var _;
229+
230+
C({this._}); // Error.
231+
}
232+
```
233+
221234
But no *parameter* with that name is bound, which means `_` can't be accessed
222-
inside the initializer list. In the body is fine, since that refers to the
223-
field, not the parameter:
235+
inside the initializer list. The name `_` can be used in the body, but this
236+
is a reference to the field, not the parameter:
224237

225238
```dart
226239
class C {
227240
var _;
228241
var other;
229242
230243
C(this._)
231-
: other = _ { // <-- Error. No "_" in scope.
244+
: other = _ { // <-- Error, cannot access `this`.
232245
print(_); // OK. Prints the field.
233246
}
234247
}
@@ -244,6 +257,68 @@ class C {
244257
}
245258
```
246259

260+
### Super parameters
261+
262+
An occurrence of `super._` as a declaration of a formal parameter in a
263+
constructor is a compile-time error. This error also occurs in the case
264+
where the super parameter has an explicitly declared type and/or default
265+
value.
266+
267+
*`super._` is not an error everywhere: In a method body it could be an
268+
invocation of an inherited getter named `_`.*
269+
270+
```dart
271+
class B {
272+
final _;
273+
B(this._);
274+
}
275+
276+
class C {
277+
C(super._); // Error.
278+
}
279+
```
280+
281+
*The desugared meaning of a super parameter includes a reference to the
282+
parameter in the initializer list of the enclosing constructor declaration,
283+
but such references are not possible when the parameter name is a
284+
wildcard.*
285+
286+
*It may seem inconvenient that `super._` "does not work" in the last
287+
example, but we do not wish to create exceptions about the ability to refer
288+
to a declaration whose name is a wildcard, just so we can support this
289+
particular usage. The advice would be to use a different name than `_` for
290+
the instance variable in `B` in the first place, or using a different name
291+
in `B` and possibly `// ignore` a lint that may warn about the names being
292+
different.*
293+
294+
### Extension types
295+
296+
An extension type declaration has a `<representationDeclaration>`
297+
which is similar to a formal parameter list of a function declaration.
298+
299+
*It always declares exactly one mandatory positional parameter, and the
300+
meaning of this declaration is that it introduces a formal parameter of a
301+
constructor of the enclosing extension type as well as a final instance
302+
variable declaration, also known as the representation variable of the
303+
extension type.*
304+
305+
This parameter can have the declared name `_`. This means that the
306+
representation variable is named `_`, and no formal parameter name is
307+
introduced into any scopes.
308+
309+
```dart
310+
extension type E(int _) {
311+
int get value => _; // OK, the representation variable name is `_`.
312+
int get sameValue => this._; // OK.
313+
}
314+
```
315+
316+
*Currently, the formal parameter introduced by a
317+
`<representationDeclaration>` is not in scope for any code, anyway.
318+
However, future generalizations such as primary constructors could
319+
introduce it into a scope. At that time it does matter that there is no
320+
formal parameter name.*
321+
247322
### Unused variable warnings
248323

249324
Dart tools currently warn if you have an unused local declaration. If the
@@ -319,3 +394,13 @@ public API.
319394
However, this *is* a breaking change. If this ships in the same version as
320395
pattern matching, we can gate it behind a language version and only break code
321396
when it upgrades to that version.
397+
398+
## Changelog
399+
400+
### 1.1
401+
402+
- Add rules about `super._` and about extension types.
403+
404+
### 1.0
405+
406+
- Initial version

0 commit comments

Comments
 (0)