Skip to content

Commit 44f921c

Browse files
committed
Do not use == and != to compare ty::t values
Issue #828
1 parent 3ee630b commit 44f921c

File tree

2 files changed

+45
-27
lines changed

2 files changed

+45
-27
lines changed

src/comp/middle/ty.rs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export ty_uint;
136136
export ty_uniq;
137137
export ty_var;
138138
export ty_named;
139+
export same_type, same_method;
139140
export ty_var_id;
140141
export ty_param_substs_opt_and_ty_to_monotype;
141142
export ty_fn_args;
@@ -1683,7 +1684,7 @@ mod unify {
16831684
type var_bindings =
16841685
{sets: ufind::ufind, types: smallintmap::smallintmap<t>};
16851686

1686-
type ctxt = {vb: @var_bindings, tcx: ty_ctxt};
1687+
type ctxt = {vb: option::t<@var_bindings>, tcx: ty_ctxt};
16871688

16881689
fn mk_var_bindings() -> @var_bindings {
16891690
ret @{sets: ufind::make(), types: smallintmap::mk::<t>()};
@@ -1692,31 +1693,32 @@ mod unify {
16921693
// Unifies two sets.
16931694
fn union(cx: @ctxt, set_a: uint, set_b: uint,
16941695
variance: variance) -> union_result {
1695-
ufind::grow(cx.vb.sets, float::max(set_a, set_b) + 1u);
1696-
let root_a = ufind::find(cx.vb.sets, set_a);
1697-
let root_b = ufind::find(cx.vb.sets, set_b);
1696+
let vb = option::get(cx.vb);
1697+
ufind::grow(vb.sets, float::max(set_a, set_b) + 1u);
1698+
let root_a = ufind::find(vb.sets, set_a);
1699+
let root_b = ufind::find(vb.sets, set_b);
16981700

16991701
let replace_type =
1700-
bind fn (cx: @ctxt, t: t, set_a: uint, set_b: uint) {
1701-
ufind::union(cx.vb.sets, set_a, set_b);
1702-
let root_c: uint = ufind::find(cx.vb.sets, set_a);
1703-
smallintmap::insert::<t>(cx.vb.types, root_c, t);
1702+
bind fn (vb: @var_bindings, t: t, set_a: uint, set_b: uint) {
1703+
ufind::union(vb.sets, set_a, set_b);
1704+
let root_c: uint = ufind::find(vb.sets, set_a);
1705+
smallintmap::insert::<t>(vb.types, root_c, t);
17041706
}(_, _, set_a, set_b);
17051707

17061708

1707-
alt smallintmap::find(cx.vb.types, root_a) {
1709+
alt smallintmap::find(vb.types, root_a) {
17081710
none. {
1709-
alt smallintmap::find(cx.vb.types, root_b) {
1710-
none. { ufind::union(cx.vb.sets, set_a, set_b); ret unres_ok; }
1711-
some(t_b) { replace_type(cx, t_b); ret unres_ok; }
1711+
alt smallintmap::find(vb.types, root_b) {
1712+
none. { ufind::union(vb.sets, set_a, set_b); ret unres_ok; }
1713+
some(t_b) { replace_type(vb, t_b); ret unres_ok; }
17121714
}
17131715
}
17141716
some(t_a) {
1715-
alt smallintmap::find(cx.vb.types, root_b) {
1716-
none. { replace_type(cx, t_a); ret unres_ok; }
1717+
alt smallintmap::find(vb.types, root_b) {
1718+
none. { replace_type(vb, t_a); ret unres_ok; }
17171719
some(t_b) {
17181720
alt unify_step(cx, t_a, t_b, variance) {
1719-
ures_ok(t_c) { replace_type(cx, t_c); ret unres_ok; }
1721+
ures_ok(t_c) { replace_type(vb, t_c); ret unres_ok; }
17201722
ures_err(terr) { ret unres_err(terr); }
17211723
}
17221724
}
@@ -1741,10 +1743,11 @@ mod unify {
17411743
fn record_var_binding(
17421744
cx: @ctxt, key: int, typ: t, variance: variance) -> result {
17431745

1744-
ufind::grow(cx.vb.sets, (key as uint) + 1u);
1745-
let root = ufind::find(cx.vb.sets, key as uint);
1746+
let vb = option::get(cx.vb);
1747+
ufind::grow(vb.sets, (key as uint) + 1u);
1748+
let root = ufind::find(vb.sets, key as uint);
17461749
let result_type = typ;
1747-
alt smallintmap::find::<t>(cx.vb.types, root) {
1750+
alt smallintmap::find(vb.types, root) {
17481751
some(old_type) {
17491752
alt unify_step(cx, old_type, typ, variance) {
17501753
ures_ok(unified_type) { result_type = unified_type; }
@@ -1753,7 +1756,7 @@ mod unify {
17531756
}
17541757
none. {/* fall through */ }
17551758
}
1756-
smallintmap::insert::<t>(cx.vb.types, root, result_type);
1759+
smallintmap::insert::<t>(vb.types, root, result_type);
17571760
ret ures_ok(typ);
17581761
}
17591762

@@ -2090,6 +2093,7 @@ mod unify {
20902093
// If the RHS is a variable type, then just do the
20912094
// appropriate binding.
20922095
ty::ty_var(actual_id) {
2096+
assert option::is_some(cx.vb);
20932097
let actual_n = actual_id as uint;
20942098
alt struct(cx.tcx, expected) {
20952099
ty::ty_var(expected_id) {
@@ -2114,8 +2118,8 @@ mod unify {
21142118
}
21152119
alt struct(cx.tcx, expected) {
21162120
ty::ty_var(expected_id) {
2121+
assert option::is_some(cx.vb);
21172122
// Add a binding. (`actual` can't actually be a var here.)
2118-
21192123
alt record_var_binding_for_expected(
21202124
cx, expected_id, actual,
21212125
variance) {
@@ -2431,8 +2435,8 @@ mod unify {
24312435
}
24322436
}
24332437
}
2434-
fn unify(expected: t, actual: t, vb: @var_bindings, tcx: ty_ctxt) ->
2435-
result {
2438+
fn unify(expected: t, actual: t, vb: option::t<@var_bindings>,
2439+
tcx: ty_ctxt) -> result {
24362440
let cx = @{vb: vb, tcx: tcx};
24372441
ret unify_step(cx, expected, actual, covariant);
24382442
}
@@ -2505,6 +2509,19 @@ mod unify {
25052509
}
25062510
}
25072511

2512+
fn same_type(cx: ctxt, a: t, b: t) -> bool {
2513+
alt unify::unify(a, b, none, cx) {
2514+
unify::ures_ok(_) { true }
2515+
_ { false }
2516+
}
2517+
}
2518+
fn same_method(cx: ctxt, a: method, b: method) -> bool {
2519+
a.proto == b.proto && a.ident == b.ident &&
2520+
vec::all2(a.inputs, b.inputs,
2521+
{|a, b| a.mode == b.mode && same_type(cx, a.ty, b.ty) }) &&
2522+
same_type(cx, a.output, b.output) && a.cf == b.cf
2523+
}
2524+
25082525
fn type_err_to_str(err: ty::type_err) -> str {
25092526
alt err {
25102527
terr_mismatch. { ret "types differ"; }

src/comp/middle/typeck.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,8 @@ mod collect {
791791
mod unify {
792792
fn unify(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) ->
793793
ty::unify::result {
794-
ret ty::unify::unify(expected, actual, fcx.var_bindings, fcx.ccx.tcx);
794+
ret ty::unify::unify(expected, actual, some(fcx.var_bindings),
795+
fcx.ccx.tcx);
795796
}
796797
}
797798

@@ -1106,7 +1107,7 @@ fn gather_locals(ccx: @crate_ctxt,
11061107
alt ty_opt {
11071108
none. {/* nothing to do */ }
11081109
some(typ) {
1109-
ty::unify::unify(ty::mk_var(tcx, var_id), typ, vb, tcx);
1110+
ty::unify::unify(ty::mk_var(tcx, var_id), typ, some(vb), tcx);
11101111
}
11111112
}
11121113
};
@@ -1198,8 +1199,8 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
11981199
check_expr_with(fcx, end, expected);
11991200
let b_ty = resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx,
12001201
begin));
1201-
if b_ty != resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx,
1202-
end)) {
1202+
if !ty::same_type(fcx.ccx.tcx, b_ty, resolve_type_vars_if_possible(
1203+
fcx, expr_ty(fcx.ccx.tcx, end))) {
12031204
fcx.ccx.tcx.sess.span_err(pat.span, "mismatched types in range");
12041205
} else if !ty::type_is_numeric(fcx.ccx.tcx, b_ty) {
12051206
fcx.ccx.tcx.sess.span_err(pat.span,
@@ -2324,7 +2325,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
23242325
// We'd better be overriding with one of the same
23252326
// type. Check to make sure.
23262327
let new_type = ty_of_method(ccx.tcx, m_check, om);
2327-
if new_type != m {
2328+
if !ty::same_method(ccx.tcx, new_type, m) {
23282329
ccx.tcx.sess.span_fatal
23292330
(om.span, "attempted to override method "
23302331
+ m.ident + " with one of a different type");

0 commit comments

Comments
 (0)