@@ -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