Make tps invariant for now. Fixes #1973.

This commit is contained in:
Niko Matsakis 2012-04-06 08:16:20 -07:00
parent 9de288c35f
commit 586b072eef
4 changed files with 76 additions and 8 deletions

View file

@ -534,8 +534,13 @@ impl unify_methods for infer_ctxt {
}
fn tps(as: [ty::t], bs: [ty::t]) -> ures {
// Note: type parameters are always treated as *invariant*
// (otherwise the type system would be unsound). In the
// future we could allow type parameters to declare a
// variance. In that case, you would have to change c_tps()
// for LUB/GLB, which currently always returns `as`.
if check vec::same_length(as, bs) {
iter2(as, bs) {|a, b| self.tys(a, b) }
iter2(as, bs) {|a, b| self.eq_tys(a, b) }
} else {
self.uerr(ty::terr_ty_param_size(bs.len(), as.len()))
}
@ -1080,12 +1085,8 @@ fn c_tuptys<C:combine>(self: C, as: [ty::t], bs: [ty::t])
fn c_tps<C:combine>(self: C, _did: ast::def_id, as: [ty::t], bs: [ty::t])
-> cres<[ty::t]> {
// FIXME #1973 lookup the declared variance of the type parameters
// based on did
if check vec::same_length(as, bs) {
map2(as, bs) {|a,b| self.c_tys(a, b) }
} else {
err(ty::terr_ty_param_size(bs.len(), as.len()))
self.infcx().tps(as, bs).then {||
ok(as)
}
}
@ -1228,7 +1229,6 @@ fn c_tys<C:combine>(
(ty::ty_class(a_id, a_tps), ty::ty_class(b_id, b_tps))
if a_id == b_id {
// FIXME variance
c_tps(self, a_id, a_tps, b_tps).chain {|tps|
ok(ty::mk_class(tcx, a_id, tps))
}

View file

@ -0,0 +1,21 @@
class box_impl<T> {
let mut f: T;
new(f: T) {
self.f = f;
}
}
fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
b.f = v;
}
fn main() {
let b = box_impl::<@int>(@3);
set_box_impl(b, @mut 5);
//!^ ERROR values differ in mutability
// No error when type of parameter actually IS @const int
let b = box_impl::<@const int>(@3);
set_box_impl(b, @mut 5);
}

View file

@ -0,0 +1,18 @@
enum box_impl<T> = {
mut f: T
};
fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
b.f = v;
}
fn main() {
let b = box_impl::<@int>({mut f: @3});
set_box_impl(b, @mut 5);
//!^ ERROR values differ in mutability
// No error when type of parameter actually IS @const int
let x: @const int = @3; // only way I could find to upcast
let b = box_impl::<@const int>({mut f: x});
set_box_impl(b, @mut 5);
}

View file

@ -0,0 +1,29 @@
iface box_iface<T> {
fn get() -> T;
fn set(t: T);
}
enum box_impl<T> = {
mut f: T
};
impl<T:copy> of box_iface<T> for box_impl<T> {
fn get() -> T { ret self.f; }
fn set(t: T) { self.f = t; }
}
fn set_box_iface<T>(b: box_iface<@const T>, v: @const T) {
b.set(v);
}
fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
b.set(v);
}
fn main() {
let b = box_impl::<@int>({mut f: @3});
set_box_iface(b as box_iface::<@int>, @mut 5);
//!^ ERROR values differ in mutability
set_box_impl(b, @mut 5);
//!^ ERROR values differ in mutability
}