Skip to content

Commit d23e205

Browse files
committed
Support interface casting in the typechecker
Issue #1437
1 parent d214e3d commit d23e205

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

src/comp/middle/resolve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1892,7 +1892,7 @@ fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, sc: iscopes,
18921892

18931893
fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) {
18941894
alt x.node {
1895-
ast::expr_field(_, _, _) | ast::expr_path(_) {
1895+
ast::expr_field(_, _, _) | ast::expr_path(_) | ast::expr_cast(_, _) {
18961896
e.impl_map.insert(x.id, sc);
18971897
}
18981898
_ {}

src/comp/middle/typeck.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ tag method_origin {
2525
method_static(ast::def_id);
2626
// iface id, method num, param num, bound num
2727
method_param(ast::def_id, uint, uint, uint);
28+
method_iface;
2829
}
2930
type method_map = hashmap<ast::node_id, method_origin>;
3031

@@ -1572,6 +1573,16 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
15721573
}
15731574
ret none;
15741575
}
1576+
ty::ty_iface(did, tps) {
1577+
for m in *ty::iface_methods(tcx, did) {
1578+
if m.ident == name {
1579+
ret some({method_ty: ty::mk_fn(tcx, m.fty),
1580+
n_tps: vec::len(*m.tps),
1581+
substs: tps,
1582+
origin: method_iface});
1583+
}
1584+
}
1585+
}
15751586
_ {}
15761587
}
15771588

@@ -2192,13 +2203,18 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
21922203
ty_to_str(tcx, t_1));
21932204
}
21942205

2195-
// FIXME there are more forms of cast to support, eventually.
2196-
if !( type_is_scalar(fcx, expr.span, t_e)
2197-
&& type_is_scalar(fcx, expr.span, t_1)) {
2198-
tcx.sess.span_err(expr.span,
2199-
"non-scalar cast: " +
2206+
alt ty::struct(tcx, t_1) {
2207+
// This will be looked up later on
2208+
ty::ty_iface(_, _) {}
2209+
_ {
2210+
// FIXME there are more forms of cast to support, eventually.
2211+
if !( type_is_scalar(fcx, expr.span, t_e)
2212+
&& type_is_scalar(fcx, expr.span, t_1)) {
2213+
tcx.sess.span_err(expr.span, "non-scalar cast: " +
22002214
ty_to_str(tcx, t_e) + " as " +
22012215
ty_to_str(tcx, t_1));
2216+
}
2217+
}
22022218
}
22032219
write::ty_only_fixup(fcx, id, t_1);
22042220
}
@@ -3019,6 +3035,18 @@ mod dict {
30193035
_ {}
30203036
}
30213037
}
3038+
ast::expr_cast(src, _) {
3039+
let target_ty = expr_ty(cx.tcx, ex);
3040+
alt ty::struct(cx.tcx, target_ty) {
3041+
ty::ty_iface(_, _) {
3042+
let impls = cx.impl_map.get(ex.id);
3043+
let dict = lookup_dict(fcx, impls, ex.span,
3044+
expr_ty(cx.tcx, src), target_ty);
3045+
cx.dict_map.insert(ex.id, @[dict]);
3046+
}
3047+
_ {}
3048+
}
3049+
}
30223050
ast::expr_fn(ast::proto_block., _, _, _) {}
30233051
ast::expr_fn(_, _, _, _) { ret; }
30243052
_ {}

0 commit comments

Comments
 (0)