Skip to content

Commit 51c0835

Browse files
authored
Update proposal-simple-lrhn.md
Fix const `.new`-tear-off requiring the constructor to be constant.
1 parent 9f594ce commit 51c0835

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

working/3616 - enum value shorthand/proposal-simple-lrhn.md

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Dart static access shorthand
22

3-
Author: [email protected]<br>Version: 1.3 (2024-11-29)
3+
Author: [email protected]<br>Version: 1.4 (2025-01-08)
44

55
You can write `.foo` instead of `ContextType.foo` when it makes sense. The rules
66
are fairly simple and easy to explain.
@@ -381,38 +381,48 @@ a static declaration or constructor declaration *S* when looked up on *D*.
381381

382382
* An expression of the form `const .id(arguments)` or `const .new(arguments)`
383383
is a constant expression. It's a compile-time error if *S* does not
384-
declare a constant constructor, and if any expression in `arguments`,
385-
which are all in a constant context, is not a constant expression.
384+
declare a corresponding constant constructor, and if any expression
385+
in `arguments`, which are all in a constant context,
386+
is not a constant expression.
386387
* An expression of the form `.<identifier>` is a constant expression if
387-
*S* declares a constant getter.
388+
*S* declares a corresponding static constant getter.
388389
* An expression of the form `.<identifier>` that is not followed by an
389390
`<argumentPart>`, is a constant expression if `*S* declares
390-
a static method or constructor, and either type inference has not
391-
added type arguments as a generic function instantiation coercion,
391+
a static method or constructor with base name `<identifier>`,
392+
and either type inference has not added type arguments as a
393+
generic function instantiation coercion to the method,
394+
or to the target class for a constructor,
392395
or the added type arguments are constant types.
393396
_Static tear-offs are constant. Instantiated static tear-offs
394-
are constant if the inferred type arguments are._
395-
that is not a constant expression.)_
397+
are constant if the inferred type arguments are. Constructor
398+
tear-offs of generic classes are always on instantiated classes._
396399
* An expression of the form `.new` which is not followed by the
397400
selectors of an `<argumentPart>`, is a constant expression if
398-
*S* declares a constant (unnamed) constructor, and either type
399-
inference has not added type arguments as a generic function
400-
instantiation coercion, or the added type arguments are constant types.
401+
*S* declares an unnamed constructor, and either the target
402+
class is not generic, or type inference has inferred
403+
constant type arguments for the target class.
404+
_It's unlikely that such a tear-off can occur in a constant
405+
context and be type-valid for the context type, but
406+
`const Object o = .new;` is technically valid._
401407
* An expression of the form `.id<typeArguments>` not followed by
402-
and `<arguments>` selector is a constant expression if the type
403-
argument clauses are all constant type expressions.
404-
* (An expression of the form `.new` followed by a `<typeArguments>` is
405-
still a compile-time error.)
408+
an `<arguments>` selector is a constant expression if the type
409+
argument clauses are all constant type expressions, and
410+
*S* declares a corresponding static function. _(It's still a
411+
compile-time error if *S* declares a constructor with the base
412+
name `id`, constructors are not generic.)_
413+
* _(An expression of the form `.new` followed by a `<typeArguments>` is
414+
still a compile-time error.)_
406415
* An expression of `.id(arguments)` or `.new(arguments)` is a
407416
constant expression if (and only if) it occurs in a constant context,
408-
*S* declares a constant constructor, every expression
417+
*S* declares a corresponding constant constructor, every expression
409418
in `arguments` (which then occurs in a constant context too)
410-
is a constant expression, and inferred type arguments, if any,
411-
are all constant types.
419+
is a constant expression, and inferred type arguments to the
420+
target class, if any, are all constant types.
412421
* An expression of `.id(arguments)` or `.id<typeArguments>(arguments)`
413-
where *S* declares a getter or static function is never a constant
414-
expression. _There are no `static` functions whose invocation is
415-
constant, the only non-instance function which can be invoked as
422+
where *S* declares a corresponding getter or static function is
423+
never a constant expression.
424+
_There are no `static` functions whose invocation is constant,
425+
the only non-instance function which can be invoked as
416426
a constant expression is `identical`, which is not inside a static
417427
namespace._
418428

@@ -424,7 +434,7 @@ a constant function.
424434
_The only `.id` selector which can come after a constant expression
425435
and still be constant is `String.length`, and it's very hard to
426436
make that integer satisfy a context type of `String`. The only other
427-
selector which can follow complete constant expression and still be
437+
selector which can follow a complete constant expression and still be
428438
constant is the not-null check `!`, which is rarely useful in
429439
constant expressions._
430440

@@ -702,6 +712,12 @@ not members of `Future`. Primarily to allow people to return values from
702712

703713
## Versions
704714

715+
1.4 (2025-01-08): Update constant rules.
716+
717+
* Doesn't require a constant `.new` tear-off to be a constant constructor.
718+
That was a typo and was never intended.
719+
* Adds more words to constant section.
720+
705721
1.3 (2024-11-29): Fix constant pattern, clean-up, and expansion
706722
of the constant section.
707723

0 commit comments

Comments
 (0)