@@ -912,23 +912,48 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
912
912
}
913
913
case ( ast. expr_rec( ?fields_0, ?base_0, ?ann) ) {
914
914
915
- // FIXME: handle presence of a nonempty base.
916
- check ( base_0 == none[ @ast. expr] ) ;
917
915
auto base_1 = base_0;
918
916
919
917
auto t = demand( fcx, e. span, expected, ann_to_type( ann) ) ;
920
918
let vec[ ast. field] fields_1 = vec( ) ;
921
919
alt ( t. struct ) {
922
920
case ( ty. ty_rec( ?field_tys) ) {
923
- auto i = 0 u;
924
- for ( ast. field field_0 in fields_0) {
925
- check ( _str. eq( field_0. ident, field_tys. ( i) . ident) ) ;
926
- auto e_1 = demand_expr( fcx, field_tys. ( i) . ty,
927
- field_0. expr) ;
928
- fields_1 += vec( rec( mut =field_0. mut ,
929
- ident=field_0. ident,
930
- expr=e_1) ) ;
931
- i += 1 u;
921
+ alt ( base_0) {
922
+ case ( none[ @ast. expr] ) {
923
+ auto i = 0 u;
924
+ for ( ast. field field_0 in fields_0) {
925
+ check ( _str. eq( field_0. ident,
926
+ field_tys. ( i) . ident) ) ;
927
+ auto e_1 = demand_expr( fcx,
928
+ field_tys. ( i) . ty,
929
+ field_0. expr) ;
930
+ fields_1 += vec( rec( mut =field_0. mut ,
931
+ ident=field_0. ident,
932
+ expr=e_1) ) ;
933
+ i += 1 u;
934
+ }
935
+ }
936
+ case ( some[ @ast. expr] ( ?bx) ) {
937
+
938
+ base_1 =
939
+ some[ @ast. expr] ( demand_expr( fcx, t, bx) ) ;
940
+
941
+ let vec[ field] base_fields = vec( ) ;
942
+
943
+ for ( ast. field field_0 in fields_0) {
944
+
945
+ for ( ty. field ft in field_tys) {
946
+ if ( _str. eq( field_0. ident, ft. ident) ) {
947
+ auto e_1 = demand_expr( fcx, ft. ty,
948
+ field_0. expr) ;
949
+ fields_1 +=
950
+ vec( rec( mut =field_0. mut ,
951
+ ident=field_0. ident,
952
+ expr=e_1) ) ;
953
+ }
954
+ }
955
+ }
956
+ }
932
957
}
933
958
}
934
959
case ( _) {
@@ -1708,8 +1733,6 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
1708
1733
1709
1734
case ( ast. expr_rec( ?fields, ?base, _) ) {
1710
1735
1711
- // FIXME: handle presence of a nonempty base.
1712
- check ( base == none[ @ast. expr] ) ;
1713
1736
auto base_1 = base;
1714
1737
1715
1738
let vec[ ast. field] fields_1 = vec( ) ;
@@ -1725,7 +1748,50 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
1725
1748
append[ field] ( fields_t, rec( ident=f. ident, ty=expr_t) ) ;
1726
1749
}
1727
1750
1728
- auto ann = ast. ann_type( plain_ty( ty. ty_rec( fields_t) ) ) ;
1751
+ auto ann = ast. ann_none;
1752
+
1753
+ alt ( base) {
1754
+ case ( none[ @ast. expr] ) {
1755
+ ann = ast. ann_type( plain_ty( ty. ty_rec( fields_t) ) ) ;
1756
+ }
1757
+
1758
+ case ( some[ @ast. expr] ( ?bexpr) ) {
1759
+ auto bexpr_1 = check_expr( fcx, bexpr) ;
1760
+ auto bexpr_t = expr_ty( bexpr_1) ;
1761
+
1762
+ let vec[ field] base_fields = vec( ) ;
1763
+
1764
+ alt ( bexpr_t. struct ) {
1765
+ case ( ty. ty_rec( ?flds) ) {
1766
+ base_fields = flds;
1767
+ }
1768
+ case ( _) {
1769
+ fcx. ccx. sess. span_err
1770
+ ( expr. span,
1771
+ "record update non-record base" ) ;
1772
+ }
1773
+ }
1774
+
1775
+ ann = ast. ann_type( bexpr_t) ;
1776
+
1777
+ for ( ty. field f in fields_t) {
1778
+ auto found = false ;
1779
+ for ( ty. field bf in base_fields) {
1780
+ if ( _str. eq( f. ident, bf. ident) ) {
1781
+ demand( fcx, expr. span, f. ty, bf. ty) ;
1782
+ found = true ;
1783
+ }
1784
+ }
1785
+ if ( !found) {
1786
+ fcx. ccx. sess. span_err
1787
+ ( expr. span,
1788
+ "unknown field in record update: "
1789
+ + f. ident) ;
1790
+ }
1791
+ }
1792
+ }
1793
+ }
1794
+
1729
1795
ret @fold. respan[ ast. expr_] ( expr. span,
1730
1796
ast. expr_rec( fields_1, base_1, ann) ) ;
1731
1797
}
0 commit comments