Skip to content

Commit f06bc5a

Browse files
committed
---
yaml --- r: 1551 b: refs/heads/master c: e2f6f19 h: refs/heads/master i: 1549: e5639f3 1547: e7b88ca 1543: 4c0c3a6 1535: aa3059a v: v3
1 parent 77db4b4 commit f06bc5a

File tree

2 files changed

+61
-44
lines changed

2 files changed

+61
-44
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 51be50490e277ce61d156fcf40a5d5b4057eee64
2+
refs/heads/master: e2f6f19fc807e1e9067a5fa6abc188ddf21f775c

trunk/src/comp/middle/typeck.rs

+60-43
Original file line numberDiff line numberDiff line change
@@ -85,59 +85,47 @@ fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
8585
// expression.
8686
fn substitute_ty_params(&@crate_ctxt ccx,
8787
@ty.t typ,
88+
vec[ast.def_id] ty_params,
8889
vec[@ast.ty] supplied,
8990
&span sp) -> @ty.t {
9091
state obj ty_substituter(@crate_ctxt ccx,
91-
@mutable uint i,
92-
vec[@ast.ty] supplied,
93-
@hashmap[int,@ty.t] substs) {
92+
vec[ast.def_id] ty_params,
93+
vec[@ast.ty] supplied) {
9494
fn fold_simple_ty(@ty.t typ) -> @ty.t {
9595
alt (typ.struct) {
96-
case (ty.ty_var(?vid)) {
97-
alt (substs.find(vid)) {
98-
case (some[@ty.t](?resolved_ty)) {
99-
ret resolved_ty;
100-
}
101-
case (none[@ty.t]) {
102-
if (i >= _vec.len[@ast.ty](supplied)) {
103-
// Just leave it as an unresolved parameter
104-
// for now. (We will error out later.)
105-
ret typ;
106-
}
107-
108-
auto result = ast_ty_to_ty_crate(ccx,
109-
supplied.(*i));
110-
*i += 1u;
111-
substs.insert(vid, result);
112-
ret result;
113-
}
96+
case (ty.ty_param(?pid)) {
97+
// Find the index of the type parameter.
98+
auto ty_param_len = _vec.len[ast.def_id](ty_params);
99+
auto i = 0u;
100+
while (i < ty_param_len &&
101+
!common.def_eq(pid, ty_params.(i))) {
102+
i += 1u;
103+
}
104+
if (i == ty_param_len) {
105+
log "substitute_ty_params(): " +
106+
"no ty param for param id!";
107+
fail;
114108
}
109+
110+
// Substitute it in.
111+
ret ast_ty_to_ty_crate(ccx, supplied.(i));
115112
}
116113
case (_) { ret typ; }
117114
}
118115
}
119116
}
120117

121-
fn hash_int(&int x) -> uint { ret x as uint; }
122-
fn eq_int(&int a, &int b) -> bool { ret a == b; }
123-
auto hasher = hash_int;
124-
auto eqer = eq_int;
125-
auto substs = @map.mk_hashmap[int,@ty.t](hasher, eqer);
126-
127-
auto subst_count = @mutable 0u;
128-
auto substituter = ty_substituter(ccx, subst_count, supplied, substs);
129-
130-
auto result = ty.fold_ty(substituter, typ);
131-
118+
auto ty_param_len = _vec.len[ast.def_id](ty_params);
132119
auto supplied_len = _vec.len[@ast.ty](supplied);
133-
if ((*subst_count) != supplied_len) {
134-
ccx.sess.span_err(sp, "expected " + _uint.to_str(*subst_count, 10u) +
120+
if (ty_param_len != supplied_len) {
121+
ccx.sess.span_err(sp, "expected " + _uint.to_str(ty_param_len, 10u) +
135122
" type parameter(s) but found " +
136123
_uint.to_str(supplied_len, 10u) + " parameter(s)");
137124
fail;
138125
}
139126

140-
ret result;
127+
auto substituter = ty_substituter(ccx, ty_params, supplied);
128+
ret ty.fold_ty(substituter, typ);
141129
}
142130

143131
// Parses the programmer's textual representation of a type into our internal
@@ -1476,49 +1464,60 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
14761464
case (ast.expr_path(?pth, ?defopt, _)) {
14771465
auto t = plain_ty(ty.ty_nil);
14781466
check (defopt != none[ast.def]);
1467+
1468+
auto ty_params;
14791469
alt (option.get[ast.def](defopt)) {
14801470
case (ast.def_arg(?id)) {
14811471
check (fcx.locals.contains_key(id));
14821472
t = fcx.locals.get(id);
1473+
ty_params = none[vec[ast.def_id]];
14831474
}
14841475
case (ast.def_local(?id)) {
14851476
alt (fcx.locals.find(id)) {
14861477
case (some[@ty.t](?t1)) { t = t1; }
14871478
case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
14881479
}
1480+
ty_params = none[vec[ast.def_id]];
14891481
}
14901482
case (ast.def_obj_field(?id)) {
14911483
check (fcx.locals.contains_key(id));
14921484
t = fcx.locals.get(id);
1485+
ty_params = none[vec[ast.def_id]];
14931486
}
14941487
case (ast.def_fn(?id)) {
14951488
check (fcx.ccx.item_types.contains_key(id));
1496-
t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
1489+
t = fcx.ccx.item_types.get(id);
1490+
ty_params = some(fcx.ccx.item_ty_params.get(id));
14971491
}
14981492
case (ast.def_native_fn(?id)) {
14991493
check (fcx.ccx.item_types.contains_key(id));
1500-
t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
1494+
t = fcx.ccx.item_types.get(id);
1495+
ty_params = some(fcx.ccx.item_ty_params.get(id));
15011496
}
15021497
case (ast.def_const(?id)) {
15031498
check (fcx.ccx.item_types.contains_key(id));
15041499
t = fcx.ccx.item_types.get(id);
1500+
ty_params = none[vec[ast.def_id]];
15051501
}
1506-
case (ast.def_variant(_, ?variant_id)) {
1502+
case (ast.def_variant(?tag_id, ?variant_id)) {
15071503
check (fcx.ccx.item_types.contains_key(variant_id));
1508-
t = generalize_ty(fcx.ccx,
1509-
fcx.ccx.item_types.get(variant_id));
1504+
t = fcx.ccx.item_types.get(variant_id);
1505+
ty_params = some(fcx.ccx.item_ty_params.get(tag_id));
15101506
}
15111507
case (ast.def_binding(?id)) {
15121508
check (fcx.locals.contains_key(id));
15131509
t = fcx.locals.get(id);
1510+
ty_params = none[vec[ast.def_id]];
15141511
}
15151512
case (ast.def_obj(?id)) {
15161513
check (fcx.ccx.item_types.contains_key(id));
1517-
t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
1514+
t = fcx.ccx.item_types.get(id);
1515+
ty_params = some(fcx.ccx.item_ty_params.get(id));
15181516
}
15191517

15201518
case (ast.def_mod(_)) {
15211519
// Hopefully part of a path.
1520+
ty_params = none[vec[ast.def_id]];
15221521
}
15231522

15241523
case (_) {
@@ -1531,8 +1530,26 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
15311530

15321531
// Substitute type parameters if the user provided some.
15331532
if (_vec.len[@ast.ty](pth.node.types) > 0u) {
1534-
t = substitute_ty_params(fcx.ccx, t, pth.node.types,
1535-
expr.span);
1533+
alt (ty_params) {
1534+
case (none[vec[ast.def_id]]) {
1535+
fcx.ccx.sess.span_err(expr.span, "this kind of " +
1536+
"item may not take type " +
1537+
"parameters");
1538+
}
1539+
case (some[vec[ast.def_id]](?tps)) {
1540+
t = substitute_ty_params(fcx.ccx, t, tps,
1541+
pth.node.types, expr.span);
1542+
}
1543+
}
1544+
} else {
1545+
alt (ty_params) {
1546+
case (none[vec[ast.def_id]]) { /* nothing */ }
1547+
case (some[vec[ast.def_id]](_)) {
1548+
// We will acquire the type parameters through
1549+
// unification.
1550+
t = generalize_ty(fcx.ccx, t);
1551+
}
1552+
}
15361553
}
15371554

15381555
ret @fold.respan[ast.expr_](expr.span,

0 commit comments

Comments
 (0)