@@ -1648,7 +1648,8 @@ fn trans_enum_variant(ccx: @crate_ctxt,
1648
1648
enum_id : ast:: node_id ,
1649
1649
variant : ast:: variant ,
1650
1650
args : ~[ ast:: variant_arg ] ,
1651
- disr : int , is_degen : bool ,
1651
+ disr : int ,
1652
+ is_degen : bool ,
1652
1653
param_substs : Option < param_substs > ,
1653
1654
llfndecl : ValueRef ) {
1654
1655
let _icx = ccx. insn_ctxt ( "trans_enum_variant" ) ;
@@ -1698,6 +1699,51 @@ fn trans_enum_variant(ccx: @crate_ctxt,
1698
1699
finish_fn ( fcx, lltop) ;
1699
1700
}
1700
1701
1702
+ // NB: In theory this should be merged with the function above. But the AST
1703
+ // structures are completely different, so very little code would be shared.
1704
+ fn trans_tuple_struct ( ccx : @crate_ctxt ,
1705
+ fields : ~[ @ast:: struct_field ] ,
1706
+ ctor_id : ast:: node_id ,
1707
+ param_substs : Option < param_substs > ,
1708
+ llfndecl : ValueRef ) {
1709
+ let _icx = ccx. insn_ctxt ( "trans_tuple_struct" ) ;
1710
+
1711
+ // Translate struct fields to function arguments.
1712
+ let fn_args = do fields. map |field| {
1713
+ {
1714
+ mode: ast:: expl ( ast:: by_copy) ,
1715
+ ty: field. node . ty ,
1716
+ ident: special_idents:: arg,
1717
+ id: field. node . id
1718
+ }
1719
+ } ;
1720
+
1721
+ let fcx = new_fn_ctxt_w_id ( ccx, ~[ ] , llfndecl, ctor_id, None ,
1722
+ param_substs, None ) ;
1723
+ let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args) ;
1724
+
1725
+ let bcx = top_scope_block ( fcx, None ) ;
1726
+ let lltop = bcx. llbb ;
1727
+ let arg_tys = ty:: ty_fn_args ( node_id_type ( bcx, ctor_id) ) ;
1728
+ let bcx = copy_args_to_allocas ( fcx, bcx, fn_args, raw_llargs, arg_tys) ;
1729
+
1730
+ for fields. eachi |i, field| {
1731
+ let lldestptr = GEPi ( bcx, fcx. llretptr , [ 0 , 0 , i] ) ;
1732
+ let llarg = match fcx. llargs . get ( field. node . id ) {
1733
+ local_mem( x) => x,
1734
+ _ => {
1735
+ ccx. tcx . sess . bug ( ~"trans_tuple_struct: llarg wasn' t \
1736
+ local_mem")
1737
+ }
1738
+ } ;
1739
+ let arg_ty = arg_tys[ i] . ty ;
1740
+ memmove_ty ( bcx, lldestptr, llarg, arg_ty) ;
1741
+ }
1742
+
1743
+ build_return ( bcx) ;
1744
+ finish_fn ( fcx, lltop) ;
1745
+ }
1746
+
1701
1747
fn trans_class_dtor( ccx : @crate_ctxt , path : path ,
1702
1748
body : ast:: blk , dtor_id : ast:: node_id ,
1703
1749
psubsts : Option < param_substs > ,
@@ -1835,15 +1881,27 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
1835
1881
fn trans_struct_def ( ccx : @crate_ctxt , struct_def : @ast:: struct_def ,
1836
1882
tps : ~[ ast:: ty_param ] , path : @ast_map:: path ,
1837
1883
ident : ast:: ident , id : ast:: node_id ) {
1884
+ // If there are type parameters, the destructor and constructor will be
1885
+ // monomorphized, so we don't translate them here.
1838
1886
if tps. len ( ) == 0 u {
1839
- do option:: iter ( & struct_def. dtor ) |dtor| {
1840
- trans_class_dtor ( ccx, * path, dtor. node . body ,
1841
- dtor. node . id , None , None , local_def ( id) ) ;
1842
- } ;
1887
+ // Translate the destructor.
1888
+ do option:: iter ( & struct_def. dtor ) |dtor| {
1889
+ trans_class_dtor ( ccx, * path, dtor. node . body ,
1890
+ dtor. node . id , None , None , local_def ( id) ) ;
1891
+ } ;
1892
+
1893
+ // If this is a tuple-like struct, translate the constructor.
1894
+ match struct_def. ctor_id {
1895
+ None => { }
1896
+ Some ( ctor_id) => {
1897
+ let llfndecl = get_item_val ( ccx, ctor_id) ;
1898
+ trans_tuple_struct ( ccx, struct_def. fields , ctor_id, None ,
1899
+ llfndecl) ;
1900
+ }
1901
+ }
1843
1902
}
1844
- // If there are ty params, the ctor will get monomorphized
1845
1903
1846
- // Translate methods
1904
+ // Translate methods.
1847
1905
meth:: trans_impl ( ccx, * path, ident, struct_def. methods , tps, None , id) ;
1848
1906
}
1849
1907
@@ -2128,8 +2186,25 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
2128
2186
set_inline_hint ( llfn) ;
2129
2187
llfn
2130
2188
}
2189
+
2190
+ ast_map:: node_struct_ctor( struct_def, struct_item, struct_path) => {
2191
+ // Only register the constructor if this is a tuple-like struct.
2192
+ match struct_def. ctor_id {
2193
+ None => {
2194
+ ccx. tcx . sess . bug ( ~"attempt to register a constructor of \
2195
+ a non-tuple-like struct")
2196
+ }
2197
+ Some ( ctor_id) => {
2198
+ let llfn = register_fn ( ccx, struct_item. span ,
2199
+ * struct_path, ctor_id) ;
2200
+ set_inline_hint ( llfn) ;
2201
+ llfn
2202
+ }
2203
+ }
2204
+ }
2205
+
2131
2206
_ => {
2132
- ccx. sess . bug ( ~"get_item_val ( ) : unexpected variant") ;
2207
+ ccx. sess . bug ( ~"get_item_val ( ) : unexpected variant")
2133
2208
}
2134
2209
} ;
2135
2210
if !( exprt || ccx. reachable . contains_key ( id) ) {
0 commit comments