dart-lang / dart-lang/language
Specify that constant expressions of type `Type` and constant type expressions are canonicalized
- 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
Assessment
This issue has not been assessed yet.