/* @flow */

class Bar<K extends {}, V> {
    good (x: number) : $ReadOnlyWeakMap<K, V> {
        return new WeakMap(); // Fine, Invariant in invariant position
    }
}

class FooK<out K extends {}, V> {
    bad (x: number) : $ReadOnlyWeakMap<K, V> { // Error: K in invariant position
        return new WeakMap();
    }
}

class FooV<K extends {}, out V> {
    bad (x: number) : $ReadOnlyWeakMap<K, V> { // Fine, V in covarint position
        return new WeakMap();
    }
}

class BazK<in K extends {}, V> {
    bad (x: number) : $ReadOnlyWeakMap<K, V> {// Error: K in covariant position
        return new WeakMap();
    }
}

class BazV<K extends {}, in V> {
    bad (x: number) : $ReadOnlyWeakMap<K, V> {// Error: V in covariant position
        return new WeakMap();
    }
}


{
    class Bar<K extends {}, V> {
        good (x: number) : ReadonlyWeakMap<K, V> {
            return new WeakMap(); // Fine, Invariant in invariant position
        }
    }

    class FooK<out K extends {}, V> {
        bad (x: number) : ReadonlyWeakMap<K, V> { // Error: K in invariant position
            return new WeakMap();
        }
    }

    class FooV<K extends {}, out V> {
        bad (x: number) : ReadonlyWeakMap<K, V> { // Fine, V in covarint position
            return new WeakMap();
        }
    }

    class BazK<in K extends {}, V> {
        bad (x: number) : ReadonlyWeakMap<K, V> {// Error: K in covariant position
            return new WeakMap();
        }
    }

    class BazV<K extends {}, in V> {
        bad (x: number) : ReadonlyWeakMap<K, V> {// Error: V in covariant position
            return new WeakMap();
        }
    }
}
