Make tps invariant for now. Fixes #1973.
This commit is contained in:
parent
9de288c35f
commit
586b072eef
@ -534,8 +534,13 @@ fn flds(a: ty::field, b: ty::field) -> ures {
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
21
src/test/compile-fail/tps-invariant-class.rs
Normal file
21
src/test/compile-fail/tps-invariant-class.rs
Normal 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);
|
||||
}
|
18
src/test/compile-fail/tps-invariant-enum.rs
Normal file
18
src/test/compile-fail/tps-invariant-enum.rs
Normal 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);
|
||||
}
|
29
src/test/compile-fail/tps-invariant-iface.rs
Normal file
29
src/test/compile-fail/tps-invariant-iface.rs
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user