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

def-site variance does not prohibit illegal method declarations for interfaces #4287

Open
susisu opened this Issue Jun 30, 2017 · 0 comments

Comments

Projects
None yet
2 participants
@susisu

susisu commented Jun 30, 2017

The def-site variance (I'm not sure this term is correct, found it is used in 945df4d.) can be used for interface declarations, but it allows illegal method declarations.
This makes the type system unsound.

// @flow

class Animal {}
class Cat extends Animal {
  meow() {
    console.log("meow");
  }
}

interface Foo<+T> {    // declare T as a covariant type parameter
  read(): T;           // this is ok
  write(val: T): void; // this should not be allowed because T is in a contravariant position
}

const foo : Foo<Cat> = {
  val: new Cat(),
  read(): Cat {
    return this.val;
  },
  write(val: Cat) {
    this.val = val;
  }
};

(foo: Foo<Animal>); // this "up-casting" is no longer safe
(foo: Foo<Animal>).write(new Animal());
foo.read().meow(); // -> TypeError: foo.read(...).meow is not a function

In this example, the interface Foo<+T> is declared with a method write(val: T): void which is inconsistent with T's covariance.
Nevertheless, Foo<Cat> can still be up-casted to Foo<Animal>, it can cause a runtime error.

@vkurchatkin vkurchatkin added the bug label Jun 30, 2017

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