@@ -80,7 +80,6 @@ use std::c_str::ToCStr;
8080use std:: cell:: { Cell , RefCell } ;
8181use std:: rc:: Rc ;
8282use std:: { i8, i16, i32, i64} ;
83- use std:: gc:: Gc ;
8483use syntax:: abi:: { X86 , X86_64 , Arm , Mips , Mipsel , Rust , RustCall } ;
8584use syntax:: abi:: { RustIntrinsic , Abi } ;
8685use syntax:: ast_util:: { local_def, is_local} ;
@@ -1704,6 +1703,59 @@ pub fn trans_enum_variant(ccx: &CrateContext,
17041703 llfndecl) ;
17051704}
17061705
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+
17071759pub fn trans_tuple_struct( ccx: & CrateContext ,
17081760 _fields: & [ ast:: StructField ] ,
17091761 ctor_id: ast:: NodeId ,
@@ -1746,7 +1798,6 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
17461798
17471799 if !type_is_zero_size( fcx. ccx, result_ty) {
17481800 let repr = adt:: represent_type( ccx, result_ty) ;
1749- adt:: trans_start_init( bcx, & * repr, fcx. llretptr. get( ) . unwrap( ) , disr) ;
17501801 for ( i, arg_datum) in arg_datums. move_iter( ) . enumerate( ) {
17511802 let lldestptr = adt:: trans_field_ptr( bcx,
17521803 & * repr,
@@ -1755,36 +1806,12 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
17551806 i) ;
17561807 arg_datum. store_to( bcx, lldestptr) ;
17571808 }
1809+ adt:: trans_set_discr( bcx, & * repr, fcx. llretptr. get( ) . unwrap( ) , disr) ;
17581810 }
17591811
17601812 finish_fn( & fcx, bcx, result_ty) ;
17611813}
17621814
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-
17881815fn enum_variant_size_lint( ccx: & CrateContext , enum_def: & ast:: EnumDef , sp: Span , id: ast:: NodeId ) {
17891816 let mut sizes = Vec :: new( ) ; // does no allocation if no pushes, thankfully
17901817
@@ -1877,12 +1904,8 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
18771904 ast:: ItemMod ( ref m) => {
18781905 trans_mod( ccx, m) ;
18791906 }
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) ;
18861909 }
18871910 ast:: ItemStatic ( _, m, ref expr) => {
18881911 // Recurse on the expression to catch items in blocks
@@ -1909,11 +1932,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
19091932 ast:: ItemForeignMod ( ref foreign_mod) => {
19101933 foreign:: trans_foreign_mod( ccx, foreign_mod) ;
19111934 }
1912- ast:: ItemStruct ( struct_def, ref generics) => {
1913- if !generics. is_type_parameterized( ) {
1914- trans_struct_def( ccx, struct_def) ;
1915- }
1916- }
19171935 ast:: ItemTrait ( ..) => {
19181936 // Inside of this trait definition, we won't be actually translating any
19191937 // functions, but the trait still needs to be walked. Otherwise default
@@ -1926,20 +1944,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
19261944 }
19271945}
19281946
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-
19431947// Translate a module. Doing this amounts to translating the items in the
19441948// module; there ends up being no artifact (aside from linkage names) of
19451949// separate modules in the compiled program. That's because modules exist
0 commit comments