@@ -552,110 +552,126 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
552
552
}
553
553
}
554
554
555
+ fn ensure_generics_abi ( ccx : & CrateCtxt ,
556
+ span : Span ,
557
+ abis : AbiSet ,
558
+ generics : & ast:: Generics ) {
559
+ if generics. ty_params . len ( ) > 0 &&
560
+ !( abis. is_rust ( ) || abis. is_intrinsic ( ) ) {
561
+ ccx. tcx . sess . span_err ( span,
562
+ "foreign functions may not use type parameters" ) ;
563
+ }
564
+ }
565
+
555
566
pub fn convert ( ccx : & CrateCtxt , it : & ast:: Item ) {
556
567
let tcx = ccx. tcx ;
557
568
debug ! ( "convert: item {} with id {}" , token:: get_ident( it. ident) , it. id) ;
558
569
match it. node {
559
- // These don't define types.
560
- ast:: ItemForeignMod ( _) | ast:: ItemMod ( _) | ast:: ItemMac ( _) => { }
561
- ast:: ItemEnum ( ref enum_definition, ref generics) => {
562
- ensure_no_ty_param_bounds ( ccx, it. span , generics, "enumeration" ) ;
563
- let tpt = ty_of_item ( ccx, it) ;
564
- write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
565
- get_enum_variant_types ( ccx,
566
- tpt. ty ,
567
- enum_definition. variants ,
568
- generics) ;
569
- }
570
- ast:: ItemImpl ( ref generics, ref opt_trait_ref, selfty, ref ms) => {
571
- let i_ty_generics = ty_generics ( ccx, generics, 0 ) ;
572
- let selfty = ccx. to_ty ( & ExplicitRscope , selfty) ;
573
- write_ty_to_tcx ( tcx, it. id , selfty) ;
570
+ // These don't define types.
571
+ ast:: ItemForeignMod ( _) | ast:: ItemMod ( _) | ast:: ItemMac ( _) => { }
572
+ ast:: ItemEnum ( ref enum_definition, ref generics) => {
573
+ ensure_no_ty_param_bounds ( ccx, it. span , generics, "enumeration" ) ;
574
+ let tpt = ty_of_item ( ccx, it) ;
575
+ write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
576
+ get_enum_variant_types ( ccx,
577
+ tpt. ty ,
578
+ enum_definition. variants ,
579
+ generics) ;
580
+ } ,
581
+ ast:: ItemImpl ( ref generics, ref opt_trait_ref, selfty, ref ms) => {
582
+ let i_ty_generics = ty_generics ( ccx, generics, 0 ) ;
583
+ let selfty = ccx. to_ty ( & ExplicitRscope , selfty) ;
584
+ write_ty_to_tcx ( tcx, it. id , selfty) ;
574
585
575
- {
576
- let mut tcache = tcx. tcache . borrow_mut ( ) ;
577
- tcache. get ( ) . insert ( local_def ( it. id ) ,
578
- ty_param_bounds_and_ty {
579
- generics : i_ty_generics. clone ( ) ,
580
- ty : selfty} ) ;
581
- }
586
+ {
587
+ let mut tcache = tcx. tcache . borrow_mut ( ) ;
588
+ tcache. get ( ) . insert ( local_def ( it. id ) ,
589
+ ty_param_bounds_and_ty {
590
+ generics : i_ty_generics. clone ( ) ,
591
+ ty : selfty} ) ;
592
+ }
582
593
583
- // If there is a trait reference, treat the methods as always public.
584
- // This is to work around some incorrect behavior in privacy checking:
585
- // when the method belongs to a trait, it should acquire the privacy
586
- // from the trait, not the impl. Forcing the visibility to be public
587
- // makes things sorta work.
588
- let parent_visibility = if opt_trait_ref. is_some ( ) {
589
- ast:: Public
590
- } else {
591
- it. vis
592
- } ;
594
+ // If there is a trait reference, treat the methods as always public.
595
+ // This is to work around some incorrect behavior in privacy checking:
596
+ // when the method belongs to a trait, it should acquire the privacy
597
+ // from the trait, not the impl. Forcing the visibility to be public
598
+ // makes things sorta work.
599
+ let parent_visibility = if opt_trait_ref. is_some ( ) {
600
+ ast:: Public
601
+ } else {
602
+ it. vis
603
+ } ;
593
604
594
- convert_methods ( ccx,
595
- ImplContainer ( local_def ( it. id ) ) ,
596
- * ms,
597
- selfty,
598
- & i_ty_generics,
599
- generics,
600
- parent_visibility) ;
601
-
602
- for trait_ref in opt_trait_ref. iter ( ) {
603
- let trait_ref = instantiate_trait_ref ( ccx, trait_ref, selfty) ;
604
-
605
- // Prevent the builtin kind traits from being manually implemented.
606
- if tcx. lang_items . to_builtin_kind ( trait_ref. def_id ) . is_some ( ) {
607
- tcx. sess . span_err ( it. span ,
608
- "cannot provide an explicit implementation \
609
- for a builtin kind") ;
605
+ convert_methods ( ccx,
606
+ ImplContainer ( local_def ( it. id ) ) ,
607
+ * ms,
608
+ selfty,
609
+ & i_ty_generics,
610
+ generics,
611
+ parent_visibility) ;
612
+
613
+ for trait_ref in opt_trait_ref. iter ( ) {
614
+ let trait_ref = instantiate_trait_ref ( ccx, trait_ref, selfty) ;
615
+
616
+ // Prevent the builtin kind traits from being manually implemented.
617
+ if tcx. lang_items . to_builtin_kind ( trait_ref. def_id ) . is_some ( ) {
618
+ tcx. sess . span_err ( it. span ,
619
+ "cannot provide an explicit implementation \
620
+ for a builtin kind") ;
621
+ }
610
622
}
611
- }
612
- }
613
- ast:: ItemTrait ( ref generics, _, ref trait_methods) => {
614
- let trait_def = trait_def_of_item ( ccx, it) ;
615
-
616
- // Run convert_methods on the provided methods.
617
- let ( _, provided_methods) =
618
- split_trait_methods ( * trait_methods) ;
619
- let untransformed_rcvr_ty = ty:: mk_self ( tcx, local_def ( it. id ) ) ;
620
- convert_methods ( ccx,
621
- TraitContainer ( local_def ( it. id ) ) ,
622
- provided_methods,
623
- untransformed_rcvr_ty,
624
- & trait_def. generics ,
625
- generics,
626
- it. vis ) ;
627
-
628
- // We need to do this *after* converting methods, since
629
- // convert_methods produces a tcache entry that is wrong for
630
- // static trait methods. This is somewhat unfortunate.
631
- ensure_trait_methods ( ccx, it. id ) ;
632
- }
633
- ast:: ItemStruct ( struct_def, ref generics) => {
634
- ensure_no_ty_param_bounds ( ccx, it. span , generics, "structure" ) ;
635
-
636
- // Write the class type
637
- let tpt = ty_of_item ( ccx, it) ;
638
- write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
623
+ } ,
624
+ ast:: ItemTrait ( ref generics, _, ref trait_methods) => {
625
+ let trait_def = trait_def_of_item ( ccx, it) ;
626
+
627
+ // Run convert_methods on the provided methods.
628
+ let ( _, provided_methods) =
629
+ split_trait_methods ( * trait_methods) ;
630
+ let untransformed_rcvr_ty = ty:: mk_self ( tcx, local_def ( it. id ) ) ;
631
+ convert_methods ( ccx,
632
+ TraitContainer ( local_def ( it. id ) ) ,
633
+ provided_methods,
634
+ untransformed_rcvr_ty,
635
+ & trait_def. generics ,
636
+ generics,
637
+ it. vis ) ;
638
+
639
+ // We need to do this *after* converting methods, since
640
+ // convert_methods produces a tcache entry that is wrong for
641
+ // static trait methods. This is somewhat unfortunate.
642
+ ensure_trait_methods ( ccx, it. id ) ;
643
+ } ,
644
+ ast:: ItemStruct ( struct_def, ref generics) => {
645
+ ensure_no_ty_param_bounds ( ccx, it. span , generics, "structure" ) ;
646
+
647
+ // Write the class type
648
+ let tpt = ty_of_item ( ccx, it) ;
649
+ write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
639
650
640
- {
641
- let mut tcache = tcx. tcache . borrow_mut ( ) ;
642
- tcache. get ( ) . insert ( local_def ( it. id ) , tpt. clone ( ) ) ;
643
- }
651
+ {
652
+ let mut tcache = tcx. tcache . borrow_mut ( ) ;
653
+ tcache. get ( ) . insert ( local_def ( it. id ) , tpt. clone ( ) ) ;
654
+ }
644
655
645
- convert_struct ( ccx, struct_def, tpt, it. id ) ;
646
- }
647
- ast:: ItemTy ( _, ref generics) => {
648
- ensure_no_ty_param_bounds ( ccx, it. span , generics, "type" ) ;
649
- let tpt = ty_of_item ( ccx, it) ;
650
- write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
651
- }
652
- _ => {
653
- // This call populates the type cache with the converted type
654
- // of the item in passing. All we have to do here is to write
655
- // it into the node type table.
656
- let tpt = ty_of_item ( ccx, it) ;
657
- write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
658
- }
656
+ convert_struct ( ccx, struct_def, tpt, it. id ) ;
657
+ } ,
658
+ ast:: ItemTy ( _, ref generics) => {
659
+ ensure_no_ty_param_bounds ( ccx, it. span , generics, "type" ) ;
660
+ let tpt = ty_of_item ( ccx, it) ;
661
+ write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
662
+ } ,
663
+ ast:: ItemFn ( _, _, abi, ref generics, _) => {
664
+ ensure_generics_abi ( ccx, it. span , abi, generics) ;
665
+ let tpt = ty_of_item ( ccx, it) ;
666
+ write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
667
+ } ,
668
+ _ => {
669
+ // This call populates the type cache with the converted type
670
+ // of the item in passing. All we have to do here is to write
671
+ // it into the node type table.
672
+ let tpt = ty_of_item ( ccx, it) ;
673
+ write_ty_to_tcx ( tcx, it. id , tpt. ty ) ;
674
+ } ,
659
675
}
660
676
}
661
677
0 commit comments