Dart2JS encodes Object and void more expensively than dynamic

Sometimes we want to use Object or void in order to signify that some generic bound is unused or unimportant, and we don’t want to accidentally encourage dynamic calls (via dynamic). For example, we have the following code in AppViewData in AngularDart:

class AppViewData {
  List<dynamic> projectedNodes;
}

In a routine refactor, I went and changed this to:

class AppViewData {
  List<Object> projectedNodes;
}

… but that actually caused a noticeable code-size regression:

- this._compView_0.create$2(0, t1, []);
+ this._compView_0.create$2(0, t1, H.setRuntimeTypeInfo([], [P.Object]));

Can we treat Object (and void) as the “same” type signature as dynamic?

AFAICT, this has no impact on the runtime of the program (here is Dart2JS):

void main() {
  final lDynamic = <dynamic>[];
  final lObject = <Object>[];
  final lVoid = <void>[];
  
  print(lDynamic is List<Object>); // true
  print(lVoid is List<Object>);    // true
  print(lObject is List<dynamic>); // true
  print(lObject is List<void>);    // true
  print(lVoid is List<Object>);    // true
  print(lVoid is List<dynamic>);   // true
}

Can we, at least in a significant enough -oX mode, consider <Object> or <void> a no-op?

/cc @rakudrama @sigmundch

Author: Fantashit

1 thought on “Dart2JS encodes Object and void more expensively than dynamic

  1. Dart 2 is designed so that there need not be any no run-time behavioral difference between void, Object and dynamic. We statically reject uses of void and we statically allow dynamic invocations on objects with static type dynamic, but there is no run-time subtype check or instance type check that can distinguish void, Object and dynamic. You should only need one of the types at run-time, preferably Object, and dynamic and void are just statically flagged variants of Object.

    The only reason to retain a difference is for debugging purposes, so <Object>[].runtimeType and <dynamic>[].runtimeType prints differently, but the specification doesn’t require this, and printing List<Object> in both cases is a valid implementation. The Type objects for List<Object> and List<dynamic> should be == equal (they aren’t currently, but they should be).

Comments are closed.