@@ -14,6 +14,7 @@ use syntax::ext::quote::rt::ToTokens;
14
14
use syntax:: feature_gate:: Features ;
15
15
use syntax:: owned_slice:: OwnedSlice ;
16
16
use syntax:: parse;
17
+ use syntax:: parse:: token:: InternedString ;
17
18
use syntax:: attr:: mk_attr_id;
18
19
use syntax:: ptr:: P ;
19
20
use syntax:: print:: pprust:: tts_to_string;
@@ -211,8 +212,8 @@ pub fn gen_mod(links: &[(String, LinkType)], globs: Vec<Global>, span: Span) ->
211
212
let mut e = ei. borrow_mut ( ) ;
212
213
e. name = unnamed_name ( & mut ctx, e. name . clone ( ) ) ;
213
214
}
214
- let e = ei. borrow ( ) . clone ( ) ;
215
- defs. extend ( cenum_to_rs ( & mut ctx, enum_name ( & e. name ) , e. kind , e. items ) . into_iter ( ) )
215
+ let e = ei. borrow ( ) ;
216
+ defs. extend ( cenum_to_rs ( & mut ctx, enum_name ( & e. name ) , e. kind , & e. items ) . into_iter ( ) )
216
217
} ,
217
218
GVar ( vi) => {
218
219
let v = vi. borrow ( ) ;
@@ -476,8 +477,8 @@ fn ctypedef_to_rs(ctx: &mut GenCtx, name: String, ty: &Type) -> Vec<P<ast::Item>
476
477
let is_empty = ei. borrow ( ) . name . is_empty ( ) ;
477
478
if is_empty {
478
479
ei. borrow_mut ( ) . name = name. clone ( ) ;
479
- let e = ei. borrow ( ) . clone ( ) ;
480
- cenum_to_rs ( ctx, name, e. kind , e. items )
480
+ let e = ei. borrow ( ) ;
481
+ cenum_to_rs ( ctx, name, e. kind , & e. items )
481
482
} else {
482
483
vec ! ( mk_item( ctx, name, ty) )
483
484
}
@@ -555,7 +556,7 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String,
555
556
556
557
let id = rust_type_id ( ctx, name. clone ( ) ) ;
557
558
let struct_def = P ( ast:: Item { ident : ctx. ext_cx . ident_of ( & id[ ..] ) ,
558
- attrs : vec ! ( mk_repr_attr( ctx, layout) , mk_deriving_copy_attr( ctx) ) ,
559
+ attrs : vec ! ( mk_repr_attr( ctx, layout) , mk_deriving_copy_attr( ctx, false ) ) ,
559
560
id : ast:: DUMMY_NODE_ID ,
560
561
node : def,
561
562
vis : ast:: Public ,
@@ -637,7 +638,7 @@ fn cunion_to_rs(ctx: &mut GenCtx, name: String, layout: Layout, members: Vec<Com
637
638
empty_generics ( )
638
639
) ;
639
640
let union_id = rust_type_id ( ctx, name. clone ( ) ) ;
640
- let union_attrs = vec ! ( mk_repr_attr( ctx, layout) , mk_deriving_copy_attr( ctx) ) ;
641
+ let union_attrs = vec ! ( mk_repr_attr( ctx, layout) , mk_deriving_copy_attr( ctx, false ) ) ;
641
642
let union_def = mk_item ( ctx, union_id, def, ast:: Public , union_attrs) ;
642
643
643
644
let union_impl = ast:: ItemImpl (
@@ -682,18 +683,80 @@ fn const_to_rs(ctx: &mut GenCtx, name: String, val: i64, val_ty: ast::Ty) -> P<a
682
683
} )
683
684
}
684
685
685
- fn cenum_to_rs ( ctx : & mut GenCtx , name : String , kind : IKind , items : Vec < EnumItem > ) -> Vec < P < ast:: Item > > {
686
- let ty = TInt ( kind, Layout :: zero ( ) ) ;
687
- let ty_id = rust_type_id ( ctx, name) ;
688
- let ty_def = ctypedef_to_rs ( ctx, ty_id, & ty) ;
689
- let val_ty = cty_to_rs ( ctx, & ty) ;
690
- let mut def = ty_def;
686
+ fn enum_kind_to_rust_type_name ( kind : IKind ) -> & ' static str {
687
+ match kind {
688
+ ISChar => "i8" ,
689
+ IUChar => "u8" ,
690
+ IShort => "i16" ,
691
+ IUShort => "u16" ,
692
+ IInt => "i32" ,
693
+ IUInt => "u32" ,
694
+ ILong => "i64" ,
695
+ IULong => "u64" ,
696
+ _ => unreachable ! ( ) ,
697
+ }
698
+ }
699
+
700
+ fn cenum_to_rs ( ctx : & mut GenCtx , name : String , kind : IKind , enum_items : & [ EnumItem ] )
701
+ -> Vec < P < ast:: Item > > {
702
+ let enum_name = ctx. ext_cx . ident_of ( & name) ;
703
+ let enum_ty = ctx. ext_cx . ty_ident ( ctx. span , enum_name) ;
704
+
705
+ let mut variants = vec ! [ ] ;
706
+ let mut found_values = HashMap :: new ( ) ;
707
+ let mut items = vec ! [ ] ;
708
+
709
+ for item in enum_items {
710
+ let name = ctx. ext_cx . ident_of ( & item. name ) ;
711
+
712
+ if let Some ( orig) = found_values. get ( & item. val ) {
713
+ let value = ctx. ext_cx . expr_path (
714
+ ctx. ext_cx . path ( ctx. span , vec ! [ enum_name, * orig] ) ) ;
715
+ items. push ( P ( ast:: Item {
716
+ ident : name,
717
+ attrs : vec ! [ ] ,
718
+ id : ast:: DUMMY_NODE_ID ,
719
+ node : ast:: ItemConst ( enum_ty. clone ( ) , value) ,
720
+ vis : ast:: Public ,
721
+ span : ctx. span ,
722
+ } ) ) ;
723
+ continue ;
724
+ }
725
+
726
+ found_values. insert ( item. val , name) ;
727
+
728
+ let sign = ast:: UnsuffixedIntLit ( if item. val < 0 { ast:: Minus } else { ast:: Plus } ) ;
729
+ let value = ctx. ext_cx . expr_lit ( ctx. span , ast:: LitInt ( item. val . abs ( ) as u64 , sign) ) ;
691
730
692
- for it in items. iter ( ) {
693
- def. push ( const_to_rs ( ctx, it. name . clone ( ) , it. val , val_ty. clone ( ) ) ) ;
731
+ variants. push ( P ( respan ( ctx. span , ast:: Variant_ {
732
+ name : name,
733
+ attrs : vec ! [ ] ,
734
+ data : ast:: VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ,
735
+ disr_expr : Some ( value) ,
736
+ } ) ) ) ;
694
737
}
695
738
696
- return def;
739
+ let enum_repr = InternedString :: new ( enum_kind_to_rust_type_name ( kind) ) ;
740
+
741
+ let repr_arg = ctx. ext_cx . meta_word ( ctx. span , enum_repr) ;
742
+ let repr_list = ctx. ext_cx . meta_list ( ctx. span , InternedString :: new ( "repr" ) , vec ! [ repr_arg] ) ;
743
+ let repr_attr = respan ( ctx. span , ast:: Attribute_ {
744
+ id : mk_attr_id ( ) ,
745
+ style : ast:: AttrStyle :: Outer ,
746
+ value : repr_list,
747
+ is_sugared_doc : false ,
748
+ } ) ;
749
+
750
+ items. push ( P ( ast:: Item {
751
+ ident : enum_name,
752
+ attrs : vec ! [ mk_deriving_copy_attr( ctx, true ) , repr_attr] ,
753
+ id : ast:: DUMMY_NODE_ID ,
754
+ node : ast:: ItemEnum ( ast:: EnumDef { variants : variants } , empty_generics ( ) ) ,
755
+ vis : ast:: Public ,
756
+ span : ctx. span ,
757
+ } ) ) ;
758
+
759
+ items
697
760
}
698
761
699
762
/// Generates accessors for fields in nested structs and unions which must be
@@ -848,11 +911,14 @@ fn mk_repr_attr(ctx: &mut GenCtx, layout: Layout) -> ast::Attribute {
848
911
} )
849
912
}
850
913
851
- fn mk_deriving_copy_attr ( ctx : & mut GenCtx ) -> ast:: Attribute {
852
- let attr_val = P ( respan ( ctx. span , ast:: MetaList (
853
- to_intern_str ( ctx, "derive" . to_string ( ) ) ,
854
- vec ! ( P ( respan( ctx. span, ast:: MetaWord ( to_intern_str( ctx, "Copy" . to_string( ) ) ) ) ) )
855
- ) ) ) ;
914
+ fn mk_deriving_copy_attr ( ctx : & mut GenCtx , clone : bool ) -> ast:: Attribute {
915
+ let mut words = vec ! ( ) ;
916
+ if clone {
917
+ words. push ( ctx. ext_cx . meta_word ( ctx. span , InternedString :: new ( "Clone" ) ) ) ;
918
+ }
919
+ words. push ( ctx. ext_cx . meta_word ( ctx. span , InternedString :: new ( "Copy" ) ) ) ;
920
+
921
+ let attr_val = ctx. ext_cx . meta_list ( ctx. span , InternedString :: new ( "derive" ) , words) ;
856
922
857
923
respan ( ctx. span , ast:: Attribute_ {
858
924
id : mk_attr_id ( ) ,
0 commit comments