Skip to content

Commit 8bb1dbc

Browse files
committed
---
yaml --- r: 1414 b: refs/heads/master c: b6f1c83 h: refs/heads/master v: v3
1 parent 40afcf4 commit 8bb1dbc

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 3a7271a026248c88ebefff6c5b585245a5151eb1
2+
refs/heads/master: b6f1c832e3c883a2ef2f5b47a68db79f33f5fb25

trunk/src/comp/middle/typeck.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import middle.ty.type_is_scalar;
2525
import std._str;
2626
import std._uint;
2727
import std._vec;
28+
import std.map;
2829
import std.map.hashmap;
2930
import std.option;
3031
import std.option.none;
@@ -78,6 +79,65 @@ fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
7879
ret ty.fold_ty(generalizer, t);
7980
}
8081

82+
// Substitutes the user's explicit types for the parameters in a path
83+
// expression.
84+
fn substitute_ty_params(&@crate_ctxt ccx,
85+
@ty.t typ,
86+
vec[@ast.ty] supplied,
87+
&span sp) -> @ty.t {
88+
state obj ty_substituter(@crate_ctxt ccx,
89+
@mutable uint i,
90+
vec[@ast.ty] supplied,
91+
@hashmap[int,@ty.t] substs) {
92+
fn fold_simple_ty(@ty.t typ) -> @ty.t {
93+
alt (typ.struct) {
94+
case (ty.ty_var(?vid)) {
95+
alt (substs.find(vid)) {
96+
case (some[@ty.t](?resolved_ty)) {
97+
ret resolved_ty;
98+
}
99+
case (none[@ty.t]) {
100+
if (i >= _vec.len[@ast.ty](supplied)) {
101+
// Just leave it as an unresolved parameter
102+
// for now. (We will error out later.)
103+
ret typ;
104+
}
105+
106+
auto result = ast_ty_to_ty_crate(ccx,
107+
supplied.(*i));
108+
*i += 1u;
109+
substs.insert(vid, result);
110+
ret result;
111+
}
112+
}
113+
}
114+
case (_) { ret typ; }
115+
}
116+
}
117+
}
118+
119+
fn hash_int(&int x) -> uint { ret x as uint; }
120+
fn eq_int(&int a, &int b) -> bool { ret a == b; }
121+
auto hasher = hash_int;
122+
auto eqer = eq_int;
123+
auto substs = @map.mk_hashmap[int,@ty.t](hasher, eqer);
124+
125+
auto subst_count = @mutable 0u;
126+
auto substituter = ty_substituter(ccx, subst_count, supplied, substs);
127+
128+
auto result = ty.fold_ty(substituter, typ);
129+
130+
auto supplied_len = _vec.len[@ast.ty](supplied);
131+
if ((*subst_count) != supplied_len) {
132+
ccx.sess.span_err(sp, "expected " + _uint.to_str(*subst_count, 10u) +
133+
" type parameter(s) but found " +
134+
_uint.to_str(supplied_len, 10u) + " parameter(s)");
135+
fail;
136+
}
137+
138+
ret result;
139+
}
140+
81141
// Parses the programmer's textual representation of a type into our internal
82142
// notion of a type. `getter` is a function that returns the type
83143
// corresponding to a definition ID.
@@ -1445,6 +1505,12 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
14451505
}
14461506
}
14471507

1508+
// Substitute type parameters if the user provided some.
1509+
if (_vec.len[@ast.ty](pth.node.types) > 0u) {
1510+
t = substitute_ty_params(fcx.ccx, t, pth.node.types,
1511+
expr.span);
1512+
}
1513+
14481514
ret @fold.respan[ast.expr_](expr.span,
14491515
ast.expr_path(pth, defopt,
14501516
ast.ann_type(t)));

0 commit comments

Comments
 (0)