Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Flag for error on reified dynamic #365

Closed
2 tasks
vsmenon opened this issue Oct 14, 2015 · 4 comments
Closed
2 tasks

Flag for error on reified dynamic #365

vsmenon opened this issue Oct 14, 2015 · 4 comments

Comments

@vsmenon
Copy link
Contributor

vsmenon commented Oct 14, 2015

Provide an static checking option to throw an error on any code that may instantiate a reified dynamic. E.g.,

typedef int Int2Int(int x);
void foo() {
  var f1 = (x) { ... }; // Error - type is dynamic -> dynamic
  Int2Int f2 = (x) { ... };  // No error - type is int -> int
  ...
  var l1 = [1, 2, 3]; // Error - type is List<dynamic>
  var l2 = <int>[1, 2, 3]; // No error - type is List<int>
}

This depends on:

@vsmenon
Copy link
Contributor Author

vsmenon commented Oct 14, 2015

@leafpetersen

Would this even let us write:

void bar(List l) {
}

? The reified type of bar is List<dynamic> -> void.

@jmesserly
Copy link
Contributor

I'm not sure that would be a problem, as it's just the type annotation. The issue would only come up when you're creating instances of generic types.

@leafpetersen
Copy link
Contributor

We had some discussion offline, but following up with some additional thoughts. In general, yes, there is a problem with using List in the type of a function, if you're trying to avoid reified dynamic with the intention of allowing unconstrained (or less constrained) is and as checks. Consider:

typedef List<int> F();
List foo() {};
var b = foo is F;

The VM will say that b is true, DDC will say it is false. I believe that in principle we could allow contra-variant reified uses of dynamic, since the reified types will only be used for:

  • Instance of checks, in which case the reified function type is on the left side of a subtype check, and hence the argument types will be on the right hand side of the subtype check
  • dsend/dcall checks, in which case the reified argument types will be on the right hand side of the subtype check.

So for example:

typedef void F(List<int);
void bar(List l) {};
var b = bar is F;

Here, the VM and DDC will always agree on the value of b.

I'm not entirely sure that it's worth allowing this level of granularity - it feels a little hard to explain why some uses of List are ok, and others aren't. On the other hand, it is kind of sensible - it's essentially saying that consumers are allowed to be permissive (claim to take any List), but that producers have to be strict (say exactly what they produce).

@jmesserly
Copy link
Contributor

moved to sdk: dart-lang/sdk#24712, dart-lang/sdk#25573

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

3 participants