Skip to content

generic methods should be able to override non-generic ones. #27334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jmesserly opened this issue Sep 13, 2016 · 4 comments
Closed

generic methods should be able to override non-generic ones. #27334

jmesserly opened this issue Sep 13, 2016 · 4 comments

Comments

@jmesserly
Copy link

From @jmesserly on February 22, 2016 17:33

Split from dart-archive/dev_compiler#301. Something like this should be supported (or we need to explicitly disallow it):

class B {
  Iterable map(f(x)); // (* -> *) -> Iterable<*>
}
class D extends B {
  Iterable<T> map<T>(T f(x)); // <T>(* -> T) -> Iterable<T>
}

See comments starting from dart-archive/dev_compiler#301 (comment).

Normally the subtyping relation is fine, because implicit instantiation can be generated as an explicit instantiation in the generated JavaScript. However for a method override, we don't have any way to express that. It'd be a little unfortunate if all generic method calls used a different calling convention, but perhaps it's unavoidable.

Copied from original issue: dart-archive/dev_compiler#459

@jmesserly
Copy link
Author

From @Andersmholmgren on February 22, 2016 19:39

I am already hitting this in the wild. As the annotations are missing on the Iterable methods of the collections package, those methods are not considered to be overriding those in the core dart package. So I get warnings for them

@jmesserly
Copy link
Author

Ah, that sounds like the reverse problem:

class B {
  Iterable<T> map<T>(T f(x));// <T>(* -> T) -> Iterable<T>
}
class D extends B {
  Iterable map(f(x)); 
}

Having a non-generic override a generic is not allowed in either strong or normal mode. If you think about it, it's kind of like optional arguments. You can add optional parameters in a subtype, but you can't take parameters away:

class B {
  m(x, y) { ... }
}
class D extends B {
  m(x) { ... } // error
}

The short term fix is to annotate the collections package.

We've discussed doing inference. Given my first example, we could conclude that D.map needs a type parameter, which would make it D.map<T>. However the return type of Iterable<dynamic> is also problematic, unless we can conclude it too should be Iterable<T>. But we're unsure if this kind of inference is a good idea, as it's sort of analogous to inferring a missing function parameter :)

@vsmenon
Copy link
Member

vsmenon commented Jan 9, 2017

@leafpetersen @jmesserly - I think we're explicitly disallowing this now statically. Can we close?

@jmesserly
Copy link
Author

yup, good catch. this was restricted in the type system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants