@@ -80,7 +80,6 @@ use std::c_str::ToCStr;
80
80
use std:: cell:: { Cell , RefCell } ;
81
81
use std:: rc:: Rc ;
82
82
use std:: { i8, i16, i32, i64} ;
83
- use std:: gc:: Gc ;
84
83
use syntax:: abi:: { X86 , X86_64 , Arm , Mips , Mipsel , Rust , RustCall } ;
85
84
use syntax:: abi:: { RustIntrinsic , Abi } ;
86
85
use syntax:: ast_util:: { local_def, is_local} ;
@@ -1704,6 +1703,59 @@ pub fn trans_enum_variant(ccx: &CrateContext,
1704
1703
llfndecl) ;
1705
1704
}
1706
1705
1706
+ pub fn trans_named_tuple_constructor<' a>( mut bcx: & ' a Block <' a>,
1707
+ ctor_ty: ty:: t,
1708
+ disr: ty:: Disr ,
1709
+ args: callee:: CallArgs ,
1710
+ dest: expr:: Dest ) -> Result <' a> {
1711
+
1712
+ let ccx = bcx. fcx. ccx;
1713
+ let tcx = & ccx. tcx;
1714
+
1715
+ let result_ty = match ty:: get( ctor_ty) . sty {
1716
+ ty:: ty_bare_fn( ref bft) => bft. sig. output,
1717
+ _ => ccx. sess( ) . bug(
1718
+ format!( "trans_enum_variant_constructor: \
1719
+ unexpected ctor return type {}",
1720
+ ctor_ty. repr( tcx) ) . as_slice( ) )
1721
+ } ;
1722
+
1723
+ // Get location to store the result. If the user does not care about
1724
+ // the result, just make a stack slot
1725
+ let llresult = match dest {
1726
+ expr:: SaveIn ( d) => d,
1727
+ expr:: Ignore => {
1728
+ if !type_is_zero_size( ccx, result_ty) {
1729
+ alloc_ty( bcx, result_ty, "constructor_result" )
1730
+ } else {
1731
+ C_undef ( type_of:: type_of( ccx, result_ty) )
1732
+ }
1733
+ }
1734
+ } ;
1735
+
1736
+ if !type_is_zero_size( ccx, result_ty) {
1737
+ let repr = adt:: represent_type( ccx, result_ty) ;
1738
+
1739
+ match args {
1740
+ callee:: ArgExprs ( exprs) => {
1741
+ let fields = exprs. iter( ) . map( |x| * x) . enumerate( ) . collect:: <Vec <_>>( ) ;
1742
+ bcx = expr:: trans_adt( bcx, & * repr, disr, fields. as_slice( ) ,
1743
+ None , expr:: SaveIn ( llresult) ) ;
1744
+ }
1745
+ _ => ccx. sess( ) . bug( "expected expr as arguments for variant/struct tuple constructor" )
1746
+ }
1747
+ }
1748
+
1749
+ // If the caller doesn't care about the result
1750
+ // drop the temporary we made
1751
+ let bcx = match dest {
1752
+ expr:: SaveIn ( _) => bcx,
1753
+ expr:: Ignore => glue:: drop_ty( bcx, llresult, result_ty)
1754
+ } ;
1755
+
1756
+ Result :: new( bcx, llresult)
1757
+ }
1758
+
1707
1759
pub fn trans_tuple_struct( ccx: & CrateContext ,
1708
1760
_fields: & [ ast:: StructField ] ,
1709
1761
ctor_id: ast:: NodeId ,
@@ -1746,7 +1798,6 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
1746
1798
1747
1799
if !type_is_zero_size( fcx. ccx, result_ty) {
1748
1800
let repr = adt:: represent_type( ccx, result_ty) ;
1749
- adt:: trans_start_init( bcx, & * repr, fcx. llretptr. get( ) . unwrap( ) , disr) ;
1750
1801
for ( i, arg_datum) in arg_datums. move_iter( ) . enumerate( ) {
1751
1802
let lldestptr = adt:: trans_field_ptr( bcx,
1752
1803
& * repr,
@@ -1755,36 +1806,12 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
1755
1806
i) ;
1756
1807
arg_datum. store_to( bcx, lldestptr) ;
1757
1808
}
1809
+ adt:: trans_set_discr( bcx, & * repr, fcx. llretptr. get( ) . unwrap( ) , disr) ;
1758
1810
}
1759
1811
1760
1812
finish_fn( & fcx, bcx, result_ty) ;
1761
1813
}
1762
1814
1763
- fn trans_enum_def( ccx: & CrateContext , enum_definition: & ast:: EnumDef ,
1764
- sp: Span , id: ast:: NodeId , vi: & [ Rc <ty:: VariantInfo >] ,
1765
- i: & mut uint) {
1766
- for variant in enum_definition. variants. iter( ) {
1767
- let disr_val = vi[ * i] . disr_val;
1768
- * i += 1 ;
1769
-
1770
- match variant. node. kind {
1771
- ast:: TupleVariantKind ( ref args) if args. len( ) > 0 => {
1772
- let llfn = get_item_val( ccx, variant. node. id) ;
1773
- trans_enum_variant( ccx, id, & * * variant, args. as_slice( ) ,
1774
- disr_val, & param_substs:: empty( ) , llfn) ;
1775
- }
1776
- ast:: TupleVariantKind ( _) => {
1777
- // Nothing to do.
1778
- }
1779
- ast:: StructVariantKind ( struct_def) => {
1780
- trans_struct_def( ccx, struct_def) ;
1781
- }
1782
- }
1783
- }
1784
-
1785
- enum_variant_size_lint( ccx, enum_definition, sp, id) ;
1786
- }
1787
-
1788
1815
fn enum_variant_size_lint( ccx: & CrateContext , enum_def: & ast:: EnumDef , sp: Span , id: ast:: NodeId ) {
1789
1816
let mut sizes = Vec :: new( ) ; // does no allocation if no pushes, thankfully
1790
1817
@@ -1877,12 +1904,8 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
1877
1904
ast:: ItemMod ( ref m) => {
1878
1905
trans_mod( ccx, m) ;
1879
1906
}
1880
- ast:: ItemEnum ( ref enum_definition, ref generics) => {
1881
- if !generics. is_type_parameterized( ) {
1882
- let vi = ty:: enum_variants( ccx. tcx( ) , local_def( item. id) ) ;
1883
- let mut i = 0 ;
1884
- trans_enum_def( ccx, enum_definition, item. span, item. id, vi. as_slice( ) , & mut i) ;
1885
- }
1907
+ ast:: ItemEnum ( ref enum_definition, _) => {
1908
+ enum_variant_size_lint( ccx, enum_definition, item. span, item. id) ;
1886
1909
}
1887
1910
ast:: ItemStatic ( _, m, ref expr) => {
1888
1911
// Recurse on the expression to catch items in blocks
@@ -1909,11 +1932,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
1909
1932
ast:: ItemForeignMod ( ref foreign_mod) => {
1910
1933
foreign:: trans_foreign_mod( ccx, foreign_mod) ;
1911
1934
}
1912
- ast:: ItemStruct ( struct_def, ref generics) => {
1913
- if !generics. is_type_parameterized( ) {
1914
- trans_struct_def( ccx, struct_def) ;
1915
- }
1916
- }
1917
1935
ast:: ItemTrait ( ..) => {
1918
1936
// Inside of this trait definition, we won't be actually translating any
1919
1937
// functions, but the trait still needs to be walked. Otherwise default
@@ -1926,20 +1944,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
1926
1944
}
1927
1945
}
1928
1946
1929
- pub fn trans_struct_def( ccx: & CrateContext , struct_def: Gc <ast:: StructDef >) {
1930
- // If this is a tuple-like struct, translate the constructor.
1931
- match struct_def. ctor_id {
1932
- // We only need to translate a constructor if there are fields;
1933
- // otherwise this is a unit-like struct.
1934
- Some ( ctor_id) if struct_def. fields. len( ) > 0 => {
1935
- let llfndecl = get_item_val( ccx, ctor_id) ;
1936
- trans_tuple_struct( ccx, struct_def. fields. as_slice( ) ,
1937
- ctor_id, & param_substs:: empty( ) , llfndecl) ;
1938
- }
1939
- Some ( _) | None => { }
1940
- }
1941
- }
1942
-
1943
1947
// Translate a module. Doing this amounts to translating the items in the
1944
1948
// module; there ends up being no artifact (aside from linkage names) of
1945
1949
// separate modules in the compiled program. That's because modules exist
0 commit comments