@@ -85,59 +85,47 @@ fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
85
85
// expression.
86
86
fn substitute_ty_params ( & @crate_ctxt ccx ,
87
87
@ty. t typ ,
88
+ vec[ ast. def_id] ty_params ,
88
89
vec[ @ast. ty] supplied,
89
90
& span sp) -> @ty. t {
90
91
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) {
94
94
fn fold_simple_ty ( @ty. t typ ) -> @ty. t {
95
95
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 += 1 u;
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 = 0 u;
100
+ while ( i < ty_param_len &&
101
+ !common. def_eq ( pid, ty_params. ( i) ) ) {
102
+ i += 1 u;
103
+ }
104
+ if ( i == ty_param_len) {
105
+ log "substitute_ty_params(): " +
106
+ "no ty param for param id!" ;
107
+ fail;
114
108
}
109
+
110
+ // Substitute it in.
111
+ ret ast_ty_to_ty_crate ( ccx, supplied. ( i) ) ;
115
112
}
116
113
case ( _) { ret typ; }
117
114
}
118
115
}
119
116
}
120
117
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 0 u;
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) ;
132
119
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 , 10 u) +
120
+ if ( ty_param_len != supplied_len) {
121
+ ccx. sess . span_err ( sp, "expected " + _uint. to_str ( ty_param_len , 10 u) +
135
122
" type parameter(s) but found " +
136
123
_uint. to_str ( supplied_len, 10 u) + " parameter(s)" ) ;
137
124
fail;
138
125
}
139
126
140
- ret result;
127
+ auto substituter = ty_substituter ( ccx, ty_params, supplied) ;
128
+ ret ty. fold_ty ( substituter, typ) ;
141
129
}
142
130
143
131
// 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 {
1476
1464
case ( ast. expr_path( ?pth, ?defopt, _) ) {
1477
1465
auto t = plain_ty( ty. ty_nil) ;
1478
1466
check ( defopt != none[ ast. def] ) ;
1467
+
1468
+ auto ty_params;
1479
1469
alt ( option. get[ ast. def] ( defopt) ) {
1480
1470
case ( ast. def_arg( ?id) ) {
1481
1471
check ( fcx. locals. contains_key( id) ) ;
1482
1472
t = fcx. locals. get( id) ;
1473
+ ty_params = none[ vec[ ast. def_id] ] ;
1483
1474
}
1484
1475
case ( ast. def_local( ?id) ) {
1485
1476
alt ( fcx. locals. find( id) ) {
1486
1477
case ( some[ @ty. t] ( ?t1) ) { t = t1; }
1487
1478
case ( none[ @ty. t] ) { t = plain_ty( ty. ty_local( id) ) ; }
1488
1479
}
1480
+ ty_params = none[ vec[ ast. def_id] ] ;
1489
1481
}
1490
1482
case ( ast. def_obj_field( ?id) ) {
1491
1483
check ( fcx. locals. contains_key( id) ) ;
1492
1484
t = fcx. locals. get( id) ;
1485
+ ty_params = none[ vec[ ast. def_id] ] ;
1493
1486
}
1494
1487
case ( ast. def_fn( ?id) ) {
1495
1488
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) ) ;
1497
1491
}
1498
1492
case ( ast. def_native_fn( ?id) ) {
1499
1493
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) ) ;
1501
1496
}
1502
1497
case ( ast. def_const( ?id) ) {
1503
1498
check ( fcx. ccx. item_types. contains_key( id) ) ;
1504
1499
t = fcx. ccx. item_types. get( id) ;
1500
+ ty_params = none[ vec[ ast. def_id] ] ;
1505
1501
}
1506
- case ( ast. def_variant( _ , ?variant_id) ) {
1502
+ case ( ast. def_variant( ?tag_id , ?variant_id) ) {
1507
1503
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 ) ) ;
1510
1506
}
1511
1507
case ( ast. def_binding( ?id) ) {
1512
1508
check ( fcx. locals. contains_key( id) ) ;
1513
1509
t = fcx. locals. get( id) ;
1510
+ ty_params = none[ vec[ ast. def_id] ] ;
1514
1511
}
1515
1512
case ( ast. def_obj( ?id) ) {
1516
1513
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) ) ;
1518
1516
}
1519
1517
1520
1518
case ( ast. def_mod( _) ) {
1521
1519
// Hopefully part of a path.
1520
+ ty_params = none[ vec[ ast. def_id] ] ;
1522
1521
}
1523
1522
1524
1523
case ( _) {
@@ -1531,8 +1530,26 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
1531
1530
1532
1531
// Substitute type parameters if the user provided some.
1533
1532
if ( _vec. len[ @ast. ty] ( pth. node. types) > 0 u) {
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
+ }
1536
1553
}
1537
1554
1538
1555
ret @fold. respan[ ast. expr_] ( expr. span,
0 commit comments