@@ -59,7 +59,7 @@ use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
5959use  syntax:: ast_util:: { path_to_ident,  walk_pat,  trait_method_to_ty_method} ; 
6060use  syntax:: ast_util:: { Privacy ,  Public ,  Private ,  visibility_to_privacy} ; 
6161use  syntax:: ast_util:: has_legacy_export_attr; 
62- use  syntax:: attr:: { attr_metas,  contains_name} ; 
62+ use  syntax:: attr:: { attr_metas,  contains_name,  attrs_contains_name } ; 
6363use  syntax:: parse:: token:: ident_interner; 
6464use  syntax:: parse:: token:: special_idents; 
6565use  syntax:: print:: pprust:: { pat_to_str,  path_to_str} ; 
@@ -857,6 +857,9 @@ fn Resolver(session: Session, lang_items: LanguageItems,
857857
858858        namespaces :  ~[  TypeNS ,  ValueNS  ] , 
859859
860+         attr_main_fn :  None , 
861+         main_fns :  ~[ ] , 
862+ 
860863        def_map :  HashMap ( ) , 
861864        export_map2 :  HashMap ( ) , 
862865        trait_map :  @HashMap ( ) , 
@@ -916,6 +919,11 @@ struct Resolver {
916919    // The four namespaces. 
917920    namespaces:  ~[ Namespace ] , 
918921
922+     // The function that has attribute named 'main' 
923+     mut  attr_main_fn:  Option < ( node_id ,  span ) > , 
924+     // The functions named 'main' 
925+     mut  main_fns:  ~[ Option < ( node_id ,  span ) > ] , 
926+ 
919927    def_map:  DefMap , 
920928    export_map2:  ExportMap2 , 
921929    trait_map:  TraitMap , 
@@ -937,6 +945,7 @@ impl Resolver {
937945        self . resolve_crate( ) ; 
938946        self . session. abort_if_errors( ) ; 
939947
948+         self . check_duplicate_main( ) ; 
940949        self . check_for_unused_imports_if_necessary( ) ; 
941950    } 
942951
@@ -3923,15 +3932,22 @@ impl Resolver {
39233932            item_fn( ref  fn_decl,  _,  ref  ty_params,  ref  block)  => { 
39243933                // If this is the main function, we must record it in the 
39253934                // session. 
3926-                 // 
3927-                 // For speed, we put the string comparison last in this chain 
3928-                 // of conditionals. 
3935+                 if  ! self . session . building_library   { 
3936+                     if self . attr_main_fn . is_none ( )  && 
3937+                            item . ident ==  special_idents : : main  { 
39293938
3930-                 if  !self . session. building_library &&
3931-                     is_none( & self . session. main_fn)  &&
3932-                     item. ident == special_idents:: main  { 
3939+                         self. main_fns. push( Some ( ( item. id,  item. span) ) ) ; 
3940+                     } 
39333941
3934-                     self. session. main_fn = Some ( ( item. id,  item. span) ) ; 
3942+                     if attrs_contains_name( item. attrs,  ~"main")  { 
3943+                         if  self . attr_main_fn. is_none( )  { 
3944+                             self. attr_main_fn = Some ( ( item. id,  item. span) ) ; 
3945+                         }  else  { 
3946+                             self . session. span_err( 
3947+                                     item. span, 
3948+                                     ~"multiple ' main'  functions") ; 
3949+                         } 
3950+                     } 
39353951                } 
39363952
39373953                self . resolve_function( OpaqueFunctionRibKind , 
@@ -5353,6 +5369,30 @@ impl Resolver {
53535369        self . def_map. insert( node_id,  def) ; 
53545370    } 
53555371
5372+     // 
5373+     // main function checking 
5374+     // 
5375+     // be sure that there is only one main function 
5376+     // 
5377+     fn  check_duplicate_main( )  { 
5378+         if  self . attr_main_fn. is_none( )  { 
5379+             if  self . main_fns. len( )  >= 1 u { 
5380+                 let  mut  i = 1 u; 
5381+                 while  i < self . main_fns. len( )  { 
5382+                     let  ( _,  dup_main_span)  =
5383+                             option:: unwrap( self . main_fns[ i] ) ; 
5384+                     self . session. span_err( 
5385+                         dup_main_span, 
5386+                         ~"multiple ' main'  functions") ; 
5387+                     i += 1 ; 
5388+                 } 
5389+                 self . session. main_fn = self . main_fns[ 0 ] ; 
5390+             } 
5391+         }  else  { 
5392+             self . session. main_fn = self . attr_main_fn; 
5393+         } 
5394+     } 
5395+ 
53565396    // 
53575397    // Unused import checking 
53585398    // 
0 commit comments