@@ -25,6 +25,7 @@ import middle.ty.type_is_scalar;
25
25
import std. _str ;
26
26
import std. _uint ;
27
27
import std. _vec ;
28
+ import std. map ;
28
29
import std. map . hashmap ;
29
30
import std. option ;
30
31
import std. option . none ;
@@ -78,6 +79,65 @@ fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
78
79
ret ty. fold_ty ( generalizer, t) ;
79
80
}
80
81
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 += 1 u;
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 0 u;
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, 10 u) +
133
+ " type parameter(s) but found " +
134
+ _uint. to_str ( supplied_len, 10 u) + " parameter(s)" ) ;
135
+ fail;
136
+ }
137
+
138
+ ret result;
139
+ }
140
+
81
141
// Parses the programmer's textual representation of a type into our internal
82
142
// notion of a type. `getter` is a function that returns the type
83
143
// corresponding to a definition ID.
@@ -1445,6 +1505,12 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
1445
1505
}
1446
1506
}
1447
1507
1508
+ // Substitute type parameters if the user provided some.
1509
+ if ( _vec. len [ @ast. ty ] ( pth. node . types ) > 0 u) {
1510
+ t = substitute_ty_params ( fcx. ccx , t, pth. node . types ,
1511
+ expr. span ) ;
1512
+ }
1513
+
1448
1514
ret @fold. respan [ ast. expr_ ] ( expr. span ,
1449
1515
ast. expr_path ( pth, defopt,
1450
1516
ast. ann_type ( t) ) ) ;
0 commit comments