@@ -201,6 +201,7 @@ use ext::base::ExtCtxt;
201201use ext:: build:: AstBuilder ;
202202use codemap:: { self , DUMMY_SP } ;
203203use codemap:: Span ;
204+ use diagnostic:: SpanHandler ;
204205use fold:: MoveMap ;
205206use owned_slice:: OwnedSlice ;
206207use parse:: token:: InternedString ;
@@ -391,6 +392,7 @@ impl<'a> TraitDef<'a> {
391392 ast:: ItemEnum ( ref enum_def, ref generics) => {
392393 self . expand_enum_def ( cx,
393394 enum_def,
395+ & item. attrs [ ..] ,
394396 item. ident ,
395397 generics)
396398 }
@@ -653,6 +655,7 @@ impl<'a> TraitDef<'a> {
653655 fn expand_enum_def ( & self ,
654656 cx : & mut ExtCtxt ,
655657 enum_def : & EnumDef ,
658+ type_attrs : & [ ast:: Attribute ] ,
656659 type_ident : Ident ,
657660 generics : & Generics ) -> P < ast:: Item > {
658661 let mut field_tys = Vec :: new ( ) ;
@@ -687,6 +690,7 @@ impl<'a> TraitDef<'a> {
687690 method_def. expand_enum_method_body ( cx,
688691 self ,
689692 enum_def,
693+ type_attrs,
690694 type_ident,
691695 self_args,
692696 & nonself_args[ ..] )
@@ -706,6 +710,32 @@ impl<'a> TraitDef<'a> {
706710 }
707711}
708712
713+ fn find_repr_type_name ( diagnostic : & SpanHandler ,
714+ type_attrs : & [ ast:: Attribute ] ) -> & ' static str {
715+ let mut repr_type_name = "i32" ;
716+ for a in type_attrs {
717+ for r in & attr:: find_repr_attrs ( diagnostic, a) {
718+ repr_type_name = match * r {
719+ attr:: ReprAny | attr:: ReprPacked => continue ,
720+ attr:: ReprExtern => "i32" ,
721+
722+ attr:: ReprInt ( _, attr:: SignedInt ( ast:: TyIs ) ) => "isize" ,
723+ attr:: ReprInt ( _, attr:: SignedInt ( ast:: TyI8 ) ) => "i8" ,
724+ attr:: ReprInt ( _, attr:: SignedInt ( ast:: TyI16 ) ) => "i16" ,
725+ attr:: ReprInt ( _, attr:: SignedInt ( ast:: TyI32 ) ) => "i32" ,
726+ attr:: ReprInt ( _, attr:: SignedInt ( ast:: TyI64 ) ) => "i64" ,
727+
728+ attr:: ReprInt ( _, attr:: UnsignedInt ( ast:: TyUs ) ) => "usize" ,
729+ attr:: ReprInt ( _, attr:: UnsignedInt ( ast:: TyU8 ) ) => "u8" ,
730+ attr:: ReprInt ( _, attr:: UnsignedInt ( ast:: TyU16 ) ) => "u16" ,
731+ attr:: ReprInt ( _, attr:: UnsignedInt ( ast:: TyU32 ) ) => "u32" ,
732+ attr:: ReprInt ( _, attr:: UnsignedInt ( ast:: TyU64 ) ) => "u64" ,
733+ }
734+ }
735+ }
736+ repr_type_name
737+ }
738+
709739impl < ' a > MethodDef < ' a > {
710740 fn call_substructure_method ( & self ,
711741 cx : & mut ExtCtxt ,
@@ -974,12 +1004,13 @@ impl<'a> MethodDef<'a> {
9741004 cx : & mut ExtCtxt ,
9751005 trait_ : & TraitDef ,
9761006 enum_def : & EnumDef ,
1007+ type_attrs : & [ ast:: Attribute ] ,
9771008 type_ident : Ident ,
9781009 self_args : Vec < P < Expr > > ,
9791010 nonself_args : & [ P < Expr > ] )
9801011 -> P < Expr > {
9811012 self . build_enum_match_tuple (
982- cx, trait_, enum_def, type_ident, self_args, nonself_args)
1013+ cx, trait_, enum_def, type_attrs , type_ident, self_args, nonself_args)
9831014 }
9841015
9851016
@@ -1013,6 +1044,7 @@ impl<'a> MethodDef<'a> {
10131044 cx : & mut ExtCtxt ,
10141045 trait_ : & TraitDef ,
10151046 enum_def : & EnumDef ,
1047+ type_attrs : & [ ast:: Attribute ] ,
10161048 type_ident : Ident ,
10171049 self_args : Vec < P < Expr > > ,
10181050 nonself_args : & [ P < Expr > ] ) -> P < Expr > {
@@ -1168,6 +1200,10 @@ impl<'a> MethodDef<'a> {
11681200 // std::intrinsics::discriminant_value(&__arg2) } as isize;
11691201 // ```
11701202 let mut index_let_stmts: Vec < P < ast:: Stmt > > = Vec :: new ( ) ;
1203+
1204+ let target_type_name =
1205+ find_repr_type_name ( & cx. parse_sess . span_diagnostic , type_attrs) ;
1206+
11711207 for ( & ident, self_arg) in vi_idents. iter ( ) . zip ( self_args. iter ( ) ) {
11721208 let path = vec ! [ cx. ident_of_std( "core" ) ,
11731209 cx. ident_of( "intrinsics" ) ,
@@ -1192,7 +1228,7 @@ impl<'a> MethodDef<'a> {
11921228 // What it should do is lookup whether the enum has an
11931229 // repr-attribute and cast to that if necessary. But
11941230 // attributes are not yet available to this function.
1195- let target_ty = cx. ty_ident ( sp, cx. ident_of ( "isize" ) ) ;
1231+ let target_ty = cx. ty_ident ( sp, cx. ident_of ( target_type_name ) ) ;
11961232 let variant_disr = cx. expr_cast ( sp, variant_value, target_ty) ;
11971233 let let_stmt = cx. stmt_let ( sp, false , ident, variant_disr) ;
11981234 index_let_stmts. push ( let_stmt) ;
0 commit comments