@@ -1098,97 +1098,6 @@ fn variant_arg_types(&@crate_ctxt ccx, &span sp, &ast::def_id vid,
1098
1098
// directly inside check_expr(). This results in a quadratic algorithm.
1099
1099
1100
1100
mod pushdown {
1101
- // Push-down over typed patterns. Note that the pattern that you pass to
1102
- // this function must have been passed to check_pat() first.
1103
- //
1104
- // TODO: enforce this via a predicate.
1105
-
1106
- fn pushdown_pat( & @stmt_ctxt scx, & ty:: t expected, & @ast:: pat pat) {
1107
- alt ( pat. node) {
1108
- case ( ast:: pat_wild( ?ann) ) {
1109
- auto t = demand:: simple( scx, pat. span, expected,
1110
- ann_to_type( scx. fcx. ccx. tcx. node_types, ann) ) ;
1111
- write:: ty_only_fixup( scx, ann. id, t) ;
1112
- }
1113
- case ( ast:: pat_lit( ?lit, ?ann) ) {
1114
- auto t = demand:: simple( scx, pat. span, expected,
1115
- ann_to_type( scx. fcx. ccx. tcx. node_types, ann) ) ;
1116
- write:: ty_only_fixup( scx, ann. id, t) ;
1117
- }
1118
- case ( ast:: pat_bind( ?id, ?did, ?ann) ) {
1119
- auto t = demand:: simple( scx, pat. span, expected,
1120
- ann_to_type( scx. fcx. ccx. tcx. node_types, ann) ) ;
1121
- scx. fcx. locals. insert( did, t) ;
1122
- write:: ty_only_fixup( scx, ann. id, t) ;
1123
- }
1124
- case ( ast:: pat_tag( ?id, ?subpats, ?ann) ) {
1125
- // Take the variant's type parameters out of the expected
1126
- // type.
1127
- auto tag_tps;
1128
- alt ( struct ( scx. fcx. ccx. tcx, expected) ) {
1129
- case ( ty:: ty_tag( _, ?tps) ) { tag_tps = tps; }
1130
- case ( _) {
1131
- scx. fcx. ccx. tcx. sess. span_err( pat. span,
1132
- "Non-constructor used in a pattern" ) ;
1133
- }
1134
- }
1135
-
1136
- // Get the types of the arguments of the variant.
1137
-
1138
- let vec[ ty:: t] tparams = [ ] ;
1139
- auto j = 0 u;
1140
- auto actual_ty_params =
1141
- ty:: ann_to_type_params( scx. fcx. ccx. tcx. node_types, ann) ;
1142
-
1143
- for ( ty:: t some_ty in tag_tps) {
1144
- let ty:: t t1 = some_ty;
1145
- let ty:: t t2 = actual_ty_params. ( j) ;
1146
-
1147
- let ty:: t res = demand:: simple( scx, pat. span, t1, t2) ;
1148
-
1149
- vec:: push( tparams, res) ;
1150
- j += 1 u;
1151
- }
1152
-
1153
- auto arg_tys;
1154
- alt ( scx. fcx. ccx. tcx. def_map. get( ann. id) ) {
1155
- case ( ast:: def_variant( _, ?vdefid) ) {
1156
- arg_tys = variant_arg_types( scx. fcx. ccx, pat. span,
1157
- vdefid, tparams) ;
1158
- }
1159
- }
1160
-
1161
- auto i = 0 u;
1162
- for ( @ast:: pat subpat in subpats) {
1163
- pushdown_pat( scx, arg_tys. ( i) , subpat) ;
1164
- i += 1 u;
1165
- }
1166
-
1167
- auto tps =
1168
- ty:: ann_to_type_params( scx. fcx. ccx. tcx. node_types, ann) ;
1169
- auto tt = ann_to_type( scx. fcx. ccx. tcx. node_types, ann) ;
1170
-
1171
- let ty_param_substs_and_ty res_t = demand:: full( scx, pat. span,
1172
- expected, tt, tps, NO_AUTODEREF ) ;
1173
-
1174
- auto ty_params_subst = ty:: ann_to_ty_param_substs_opt_and_ty
1175
- ( scx. fcx. ccx. tcx. node_types, ann) ;
1176
-
1177
- auto ty_params_opt;
1178
- alt ( ty_params_subst. _0) {
1179
- case ( none) {
1180
- ty_params_opt = none[ vec[ ty:: t] ] ;
1181
- }
1182
- case ( some( ?tps) ) {
1183
- ty_params_opt = some[ vec[ ty:: t] ] ( tag_tps) ;
1184
- }
1185
- }
1186
-
1187
- write:: ty_fixup( scx, ann. id, tup( ty_params_opt, tt) ) ;
1188
- }
1189
- }
1190
- }
1191
-
1192
1101
// Push-down over typed expressions. Note that the expression that you
1193
1102
// pass to this function must have been passed to check_expr() first.
1194
1103
//
@@ -1673,75 +1582,88 @@ fn check_lit(@crate_ctxt ccx, &@ast::lit lit) -> ty::t {
1673
1582
fail; // not reached
1674
1583
}
1675
1584
1676
- fn check_pat( & @stmt_ctxt scx, & @ast:: pat pat) {
1585
+ // Pattern checking is top-down rather than bottom-up so that bindings get
1586
+ // their types immediately.
1587
+ fn check_pat( & @stmt_ctxt scx, & @ast:: pat pat, ty:: t expected) {
1677
1588
alt ( pat. node) {
1678
1589
case ( ast:: pat_wild( ?ann) ) {
1679
- auto typ = next_ty_var( scx) ;
1680
- write:: ty_only_fixup( scx, ann. id, typ) ;
1590
+ write:: ty_only_fixup( scx, ann. id, expected) ;
1681
1591
}
1682
1592
case ( ast:: pat_lit( ?lt, ?ann) ) {
1683
1593
auto typ = check_lit( scx. fcx. ccx, lt) ;
1594
+ typ = demand:: simple( scx, pat. span, expected, typ) ;
1684
1595
write:: ty_only_fixup( scx, ann. id, typ) ;
1685
1596
}
1686
- case ( ast:: pat_bind( ?id, ?def_id, ?a ) ) {
1687
- auto typ = next_ty_var ( scx) ;
1688
- write:: ty_only_fixup( scx, a . id, typ ) ;
1597
+ case ( ast:: pat_bind( ?id, ?def_id, ?ann ) ) {
1598
+ scx. fcx . locals . insert ( def_id , expected ) ;
1599
+ write:: ty_only_fixup( scx, ann . id, expected ) ;
1689
1600
}
1690
- case ( ast:: pat_tag( ?p, ?subpats, ?old_ann) ) {
1691
- auto vdef = ast:: variant_def_ids
1692
- ( scx. fcx. ccx. tcx. def_map. get( old_ann. id) ) ;
1693
- auto t = ty:: lookup_item_type( scx. fcx. ccx. tcx,
1694
- vdef. _1) . _1;
1695
- auto len = vec:: len[ ast:: ident] ( p. node. idents) ;
1696
- auto last_id = p. node. idents. ( len - 1 u) ;
1697
-
1698
- auto tpt = ty:: lookup_item_type( scx. fcx. ccx. tcx,
1699
- vdef. _0) ;
1700
-
1701
- auto path_tpot = instantiate_path( scx, p, tpt, pat. span) ;
1702
-
1703
- alt ( struct ( scx. fcx. ccx. tcx, t) ) {
1704
- // N-ary variants have function types.
1705
- case ( ty:: ty_fn( _, ?args, ?tag_ty, _) ) {
1706
- auto arg_len = vec:: len[ arg] ( args) ;
1707
- auto subpats_len = vec:: len[ @ast:: pat] ( subpats) ;
1708
- if ( arg_len != subpats_len) {
1709
- // TODO: pluralize properly
1710
- auto err_msg = "tag type " + last_id + " has " +
1711
- uint:: to_str( arg_len, 10 u) +
1712
- " field(s), but this pattern has " +
1713
- uint:: to_str( subpats_len, 10 u) +
1714
- " field(s)" ;
1715
-
1716
- scx. fcx. ccx. tcx. sess. span_err( pat. span, err_msg) ;
1717
- fail; // TODO: recover
1718
- }
1719
-
1720
- for ( @ast:: pat subpat in subpats) {
1721
- check_pat( scx, subpat) ;
1722
- }
1601
+ case ( ast:: pat_tag( ?path, ?subpats, ?ann) ) {
1602
+ // Typecheck the path.
1603
+ auto v_def = scx. fcx. ccx. tcx. def_map. get( ann. id) ;
1604
+ auto v_def_ids = ast:: variant_def_ids( v_def) ;
1723
1605
1724
- write:: ty_fixup( scx, old_ann. id, path_tpot) ;
1725
- }
1726
-
1727
- // Nullary variants have tag types.
1728
- case ( ty:: ty_tag( ?tid, _) ) {
1729
- auto subpats_len = vec:: len[ @ast:: pat] ( subpats) ;
1730
- if ( subpats_len > 0 u) {
1731
- // TODO: pluralize properly
1732
- auto err_msg = "tag type " + last_id +
1733
- " has no field(s)," +
1734
- " but this pattern has " +
1735
- uint:: to_str( subpats_len, 10 u) +
1736
- " field(s)" ;
1737
-
1738
- scx. fcx. ccx. tcx. sess. span_err( pat. span, err_msg) ;
1739
- fail; // TODO: recover
1740
- }
1606
+ auto tag_tpt = ty:: lookup_item_type( scx. fcx. ccx. tcx,
1607
+ v_def_ids. _0) ;
1608
+ auto path_tpot = instantiate_path( scx, path, tag_tpt, pat. span) ;
1741
1609
1742
- write:: ty_fixup( scx, old_ann. id, path_tpot) ;
1610
+ // Take the tag type params out of `expected`.
1611
+ auto expected_tps;
1612
+ alt ( struct ( scx. fcx. ccx. tcx, expected) ) {
1613
+ case ( ty:: ty_tag( _, ?tps) ) { expected_tps = tps; }
1614
+ case ( _) {
1615
+ // FIXME: Switch expected and actual in this message? I
1616
+ // can never tell.
1617
+ scx. fcx. ccx. tcx. sess. span_err( pat. span,
1618
+ #fmt( "mismatched types: expected tag but found %s" ,
1619
+ ty:: ty_to_str( scx. fcx. ccx. tcx, expected) ) ) ;
1620
+ }
1621
+ }
1622
+
1623
+ // Unify with the expected tag type.
1624
+ auto path_tpt = demand:: full( scx, pat. span, expected,
1625
+ path_tpot. _1, expected_tps,
1626
+ NO_AUTODEREF ) ;
1627
+ path_tpot = tup( some[ vec[ ty:: t] ] ( path_tpt. _0) , path_tpt. _1) ;
1628
+
1629
+ // Get the number of arguments in this tag variant.
1630
+ auto arg_types = variant_arg_types( scx. fcx. ccx, pat. span,
1631
+ v_def_ids. _1, expected_tps) ;
1632
+
1633
+ auto subpats_len = vec:: len[ @ast:: pat] ( subpats) ;
1634
+
1635
+ if ( vec:: len[ ty:: t] ( arg_types) > 0 u) {
1636
+ // N-ary variant.
1637
+ auto arg_len = vec:: len[ ty:: t] ( arg_types) ;
1638
+ if ( arg_len != subpats_len) {
1639
+ // TODO: note definition of tag variant
1640
+ // TODO (issue #448): Wrap a #fmt string over multiple
1641
+ // lines...
1642
+ scx. fcx. ccx. tcx. sess. span_err( pat. span, #fmt(
1643
+ "this pattern has %u field%s, but the corresponding variant has %u field%s" ,
1644
+ subpats_len,
1645
+ if ( subpats_len == 0 u) { "" } else { "s" } ,
1646
+ arg_len,
1647
+ if ( arg_len == 0 u) { "" } else { "s" } ) ) ;
1648
+ }
1649
+
1650
+ // TODO: vec::iter2
1651
+ auto i = 0 u;
1652
+ for ( @ast:: pat subpat in subpats) {
1653
+ check_pat( scx, subpat, arg_types. ( i) ) ;
1654
+ i += 1 u;
1743
1655
}
1656
+ } else if ( subpats_len > 0 u) {
1657
+ // TODO: note definition of tag variant
1658
+ // TODO (issue #448): Wrap a #fmt string over multiple
1659
+ // lines...
1660
+ scx. fcx. ccx. tcx. sess. span_err( pat. span, #fmt(
1661
+ "this pattern has %u field%s, but the corresponding variant has no fields" ,
1662
+ subpats_len,
1663
+ if ( subpats_len == 0 u) { "" } else { "s" } ) ) ;
1744
1664
}
1665
+
1666
+ write:: ty_fixup( scx, ann. id, path_tpot) ;
1745
1667
}
1746
1668
}
1747
1669
}
@@ -2247,20 +2169,14 @@ fn check_expr(&@stmt_ctxt scx, &@ast::expr expr) {
2247
2169
2248
2170
// Typecheck the patterns first, so that we get types for all the
2249
2171
// bindings.
2250
- auto pattern_ty = expr_ty( scx. fcx. ccx. tcx, expr) ;
2172
+ auto pattern_ty = ty :: expr_ty( scx. fcx. ccx. tcx, expr) ;
2251
2173
2252
2174
let vec[ @ast:: pat] pats = [ ] ;
2253
2175
for ( ast:: arm arm in arms) {
2254
- check_pat( scx, arm. pat) ;
2255
- pattern_ty = demand:: simple( scx, arm. pat. span, pattern_ty,
2256
- pat_ty( scx. fcx. ccx. tcx, arm. pat) ) ;
2176
+ check_pat( scx, arm. pat, pattern_ty) ;
2257
2177
pats += [ arm. pat] ;
2258
2178
}
2259
2179
2260
- for ( @ast:: pat pat in pats) {
2261
- pushdown:: pushdown_pat( scx, pattern_ty, pat) ;
2262
- }
2263
-
2264
2180
// Now typecheck the blocks.
2265
2181
auto result_ty = next_ty_var( scx) ;
2266
2182
0 commit comments