Skip to content

Commit 664a044

Browse files
committed
More resolving and typechecking of bounded type parameters.
Extern interfaces still don't get recognized. Issue #1227
1 parent 40d5f28 commit 664a044

File tree

6 files changed

+211
-55
lines changed

6 files changed

+211
-55
lines changed

src/comp/metadata/csearch.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
7272
let nm = decoder::lookup_item_name(cdata, did.node);
7373
if alt name { some(n) { n == nm } none. { true } } {
7474
result += [@{did: did,
75+
iface_did: none::<ast::def_id>, // FIXME[impl]
7576
ident: nm,
7677
methods: decoder::lookup_impl_methods(
7778
cdata, did.node, did.crate)}];

src/comp/middle/kind.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,14 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
163163
alt substs.substs {
164164
some(ts) {
165165
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
166-
let kinds = vec::map(ty::lookup_item_type(cx.tcx, did).bounds,
167-
{|bs| ty::param_bounds_to_kind(bs)});
166+
let bounds = ty::lookup_item_type(cx.tcx, did).bounds;
168167
let i = 0u;
169168
for ty in ts {
170169
let kind = ty::type_kind(cx.tcx, ty);
171-
if !ty::kind_lteq(kinds[i], kind) {
170+
let p_kind = ty::param_bounds_to_kind(bounds[i]);
171+
if !ty::kind_lteq(p_kind, kind) {
172172
cx.tcx.sess.span_err(e.span, "instantiating a " +
173-
kind_to_str(kinds[i]) +
173+
kind_to_str(p_kind) +
174174
" type parameter with a "
175175
+ kind_to_str(kind) + " type");
176176
}

src/comp/middle/resolve.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,8 @@ fn check_exports(e: @env) {
17011701
// Impl resolution
17021702

17031703
type method_info = {did: def_id, n_tps: uint, ident: ast::ident};
1704-
type _impl = {did: def_id, ident: ast::ident, methods: [@method_info]};
1704+
type _impl = {did: def_id, iface_did: option::t<def_id>,
1705+
ident: ast::ident, methods: [@method_info]};
17051706
type iscopes = list<@[@_impl]>;
17061707

17071708
fn resolve_impls(e: @env, c: @ast::crate) {
@@ -1757,14 +1758,20 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
17571758
}
17581759
}
17591760

1760-
fn find_impls_in_item(i: @ast::item, &impls: [@_impl],
1761+
fn find_impls_in_item(e: env, i: @ast::item, &impls: [@_impl],
17611762
name: option::t<ident>,
17621763
ck_exports: option::t<ast::_mod>) {
17631764
alt i.node {
1764-
ast::item_impl(_, _, _, mthds) {
1765+
ast::item_impl(_, ifce, _, mthds) {
17651766
if alt name { some(n) { n == i.ident } _ { true } } &&
17661767
alt ck_exports { some(m) { is_exported(i.ident, m) } _ { true } } {
17671768
impls += [@{did: local_def(i.id),
1769+
iface_did: alt ifce {
1770+
some(@{node: ast::ty_path(_, id), _}) {
1771+
some(def_id_of_def(e.def_map.get(id)))
1772+
}
1773+
_ { none }
1774+
},
17681775
ident: i.ident,
17691776
methods: vec::map(mthds, {|m|
17701777
@{did: local_def(m.id),
@@ -1788,7 +1795,7 @@ fn find_impls_in_mod(e: env, m: def, &impls: [@_impl],
17881795
cached = if defid.crate == ast::local_crate {
17891796
let tmp = [];
17901797
for i in option::get(e.mod_map.get(defid.node).m).items {
1791-
find_impls_in_item(i, tmp, name, none);
1798+
find_impls_in_item(e, i, tmp, name, none);
17921799
}
17931800
@tmp
17941801
} else {
@@ -1816,7 +1823,7 @@ fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
18161823
for st in b.node.stmts {
18171824
alt st.node {
18181825
ast::stmt_decl(@{node: ast::decl_item(i), _}, _) {
1819-
find_impls_in_item(i, impls, none, none);
1826+
find_impls_in_item(*e, i, impls, none, none);
18201827
}
18211828
_ {}
18221829
}
@@ -1829,13 +1836,15 @@ fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, sc: iscopes,
18291836
v: vt<iscopes>) {
18301837
let impls = [];
18311838
for vi in m.view_items { find_impls_in_view_item(*e, vi, impls, sc); }
1832-
for i in m.items { find_impls_in_item(i, impls, none, none); }
1839+
for i in m.items { find_impls_in_item(*e, i, impls, none, none); }
18331840
visit::visit_mod(m, s, vec::len(impls) > 0u ? cons(@impls, @sc) : sc, v);
18341841
}
18351842

18361843
fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) {
18371844
alt x.node {
1838-
ast::expr_field(_, _, _) { e.impl_map.insert(x.id, sc); }
1845+
ast::expr_field(_, _, _) | ast::expr_path(_) {
1846+
e.impl_map.insert(x.id, sc);
1847+
}
18391848
_ {}
18401849
}
18411850
visit::visit_expr(x, sc, v);

src/comp/middle/trans.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2858,9 +2858,12 @@ fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
28582858
// Lval means this is a record field, so not a method
28592859
if !expr_is_lval(bcx, e) {
28602860
alt bcx_ccx(bcx).method_map.find(e.id) {
2861-
some(did) { // An impl method
2861+
some(typeck::method_static(did)) { // An impl method
28622862
ret trans_method_callee(bcx, e, base, did);
28632863
}
2864+
some(typeck::method_param(_)) {
2865+
fail "not implemented"; // FIXME[impl]
2866+
}
28642867
none. { // An object method
28652868
let of = trans_object_field(bcx, base, ident);
28662869
ret {bcx: of.bcx, val: of.mthptr, kind: owned,

src/comp/middle/ty.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
814814
alt fld { fm_var(folder) { ty = folder(id); } _ {/* no-op */ } }
815815
}
816816
ty_param(id, did) {
817-
alt fld { fm_param(folder) { ty = folder(id, did); } _ {/* no-op */ } }
817+
alt fld { fm_param(folder) { ty = folder(id, did); } _ {} }
818818
}
819819
}
820820

@@ -1731,6 +1731,7 @@ mod unify {
17311731
export ures_ok;
17321732
export ures_err;
17331733
export var_bindings;
1734+
export precise, in_bindings, bind_params;
17341735

17351736
tag result { ures_ok(t); ures_err(type_err); }
17361737
tag union_result { unres_ok; unres_err(type_err); }
@@ -1741,7 +1742,12 @@ mod unify {
17411742
type var_bindings =
17421743
{sets: ufind::ufind, types: smallintmap::smallintmap<t>};
17431744

1744-
type ctxt = {vb: option::t<@var_bindings>, tcx: ty_ctxt};
1745+
tag unify_style {
1746+
precise;
1747+
in_bindings(@var_bindings);
1748+
bind_params(@mutable [mutable option::t<t>]);
1749+
}
1750+
type ctxt = {st: unify_style, tcx: ty_ctxt};
17451751

17461752
fn mk_var_bindings() -> @var_bindings {
17471753
ret @{sets: ufind::make(), types: smallintmap::mk::<t>()};
@@ -1750,7 +1756,9 @@ mod unify {
17501756
// Unifies two sets.
17511757
fn union(cx: @ctxt, set_a: uint, set_b: uint,
17521758
variance: variance) -> union_result {
1753-
let vb = option::get(cx.vb);
1759+
let vb = alt cx.st {
1760+
in_bindings(vb) { vb }
1761+
};
17541762
ufind::grow(vb.sets, float::max(set_a, set_b) + 1u);
17551763
let root_a = ufind::find(vb.sets, set_a);
17561764
let root_b = ufind::find(vb.sets, set_b);
@@ -1800,7 +1808,7 @@ mod unify {
18001808
fn record_var_binding(
18011809
cx: @ctxt, key: int, typ: t, variance: variance) -> result {
18021810

1803-
let vb = option::get(cx.vb);
1811+
let vb = alt cx.st { in_bindings(vb) { vb } };
18041812
ufind::grow(vb.sets, (key as uint) + 1u);
18051813
let root = ufind::find(vb.sets, key as uint);
18061814
let result_type = typ;
@@ -2136,7 +2144,6 @@ mod unify {
21362144
// If the RHS is a variable type, then just do the
21372145
// appropriate binding.
21382146
ty::ty_var(actual_id) {
2139-
assert option::is_some(cx.vb);
21402147
let actual_n = actual_id as uint;
21412148
alt struct(cx.tcx, expected) {
21422149
ty::ty_var(expected_id) {
@@ -2157,11 +2164,20 @@ mod unify {
21572164
}
21582165
ret ures_ok(mk_var(cx.tcx, actual_id));
21592166
}
2167+
ty::ty_param(n, _) {
2168+
alt cx.st {
2169+
bind_params(cell) {
2170+
while vec::len(*cell) < n + 1u { *cell += [mutable none]; }
2171+
cell[n] = some(expected);
2172+
ret ures_ok(expected);
2173+
}
2174+
_ {}
2175+
}
2176+
}
21602177
_ {/* empty */ }
21612178
}
21622179
alt struct(cx.tcx, expected) {
21632180
ty::ty_var(expected_id) {
2164-
assert option::is_some(cx.vb);
21652181
// Add a binding. (`actual` can't actually be a var here.)
21662182
alt record_var_binding_for_expected(
21672183
cx, expected_id, actual,
@@ -2478,9 +2494,9 @@ mod unify {
24782494
}
24792495
}
24802496
}
2481-
fn unify(expected: t, actual: t, vb: option::t<@var_bindings>,
2497+
fn unify(expected: t, actual: t, st: unify_style,
24822498
tcx: ty_ctxt) -> result {
2483-
let cx = @{vb: vb, tcx: tcx};
2499+
let cx = @{st: st, tcx: tcx};
24842500
ret unify_step(cx, expected, actual, covariant);
24852501
}
24862502
fn dump_var_bindings(tcx: ty_ctxt, vb: @var_bindings) {
@@ -2553,7 +2569,7 @@ mod unify {
25532569
}
25542570

25552571
fn same_type(cx: ctxt, a: t, b: t) -> bool {
2556-
alt unify::unify(a, b, none, cx) {
2572+
alt unify::unify(a, b, unify::precise, cx) {
25572573
unify::ures_ok(_) { true }
25582574
_ { false }
25592575
}

0 commit comments

Comments
 (0)