dart-lang / dart-lang/language

Specify that constant expressions of type `Type` and constant type expressions are canonicalized

Open
#95 5 comments 1 reaction 0 assignees View on GitHub
specification technical-debt
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

In response to #92, about the use of `==` vs. `identical` to detect that two instances of type `Type` reify the same type, we specify that `Type` instances that constantly reify a type are canonicalized.

Similarly, we may perhaps wish to specify that `o.runtimeType` (where `runtimeType` has no overriding declaration, that is, it invokes the implementation in `Object`) must return a canonicalized instance of `Type` in the case where `o` was created by an instance creation expression `e` (possible a constant object expression) as an instance of a non-generic class, or as an instance of a generic class where the type arguments passed in `e` (explicitly, inferred, or obtained via instantiate-to-bound) are constant type expressions. It is not obvious to me whether this will be easy to achieve in terms of implementation effort, or whether it will work well, in terms of performance implications for the language as a whole.

The next case seems more safe to require: We specify that whenever an actual type argument is a constant type expression, any evaluation of the corresponding type variable must return a canonicalized value. For instance, the following must print 'true' for every statement in `main`:

```dart
Type typeOf() => X;

class C {
Type get typeArgument => X;
D dOf() => D();
}

class D {
Type get typeArgument => Y;
}

main() {
print(identical(typeOf>(), typeOf>()));
print(identical(C>().typeArgument, C>().typeArgument));
print(identical(C>().dOf().typeArgument, C>().typeArgument));
}
```

Note that we do _not_ require `identical(C>().dOf().runtimeType, typeOf>>())`, even though the reified type is in both cases `D>`, which is a constant type expression. This is because the given instance was created by evaluating an instance creation expression where the actual type argument was not a constant type expression (it was `X`), so that type argument is not statically known to be canonicalized.

These rules would still not make the test using `identical` safe for any particular pair of instances of `Type`, because it requires developers to follow certain conventions in order to make it known statically that both of those instances were originally obtained by evaluation of a constant expression, and that's not a decidable property for Dart programs in general. But it seems to make the `identical` type test safe in a set of situations that is somewhat less intractable for developers who are willing to go the extra mile in order to get this optimization.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.