@@ -59,7 +59,7 @@ use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
59
59
use syntax:: ast_util:: { path_to_ident, walk_pat, trait_method_to_ty_method} ;
60
60
use syntax:: ast_util:: { Privacy , Public , Private , visibility_to_privacy} ;
61
61
use 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 } ;
63
63
use syntax:: parse:: token:: ident_interner;
64
64
use syntax:: parse:: token:: special_idents;
65
65
use syntax:: print:: pprust:: { pat_to_str, path_to_str} ;
@@ -857,6 +857,9 @@ fn Resolver(session: Session, lang_items: LanguageItems,
857
857
858
858
namespaces : ~[ TypeNS , ValueNS ] ,
859
859
860
+ attr_main_fn : None ,
861
+ main_fns : ~[ ] ,
862
+
860
863
def_map : HashMap ( ) ,
861
864
export_map2 : HashMap ( ) ,
862
865
trait_map : @HashMap ( ) ,
@@ -916,6 +919,11 @@ struct Resolver {
916
919
// The four namespaces.
917
920
namespaces: ~[ Namespace ] ,
918
921
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
+
919
927
def_map: DefMap ,
920
928
export_map2: ExportMap2 ,
921
929
trait_map: TraitMap ,
@@ -937,6 +945,7 @@ impl Resolver {
937
945
self . resolve_crate( ) ;
938
946
self . session. abort_if_errors( ) ;
939
947
948
+ self . check_duplicate_main( ) ;
940
949
self . check_for_unused_imports_if_necessary( ) ;
941
950
}
942
951
@@ -3923,15 +3932,22 @@ impl Resolver {
3923
3932
item_fn( ref fn_decl, _, ref ty_params, ref block) => {
3924
3933
// If this is the main function, we must record it in the
3925
3934
// 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 {
3929
3938
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
+ }
3933
3941
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
+ }
3935
3951
}
3936
3952
3937
3953
self . resolve_function( OpaqueFunctionRibKind ,
@@ -5353,6 +5369,30 @@ impl Resolver {
5353
5369
self . def_map. insert( node_id, def) ;
5354
5370
}
5355
5371
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
+
5356
5396
//
5357
5397
// Unused import checking
5358
5398
//
0 commit comments