10
10
11
11
12
12
use front:: map as ast_map;
13
+ use middle:: def_id:: { CRATE_DEF_INDEX } ;
13
14
use session:: { config, Session } ;
14
15
use syntax:: ast:: NodeId ;
15
16
use syntax:: attr;
16
17
use syntax:: codemap:: Span ;
17
18
use syntax:: entry:: EntryPointType ;
18
19
use rustc_front:: hir:: { Item , ItemFn } ;
19
- use rustc_front:: visit;
20
- use rustc_front:: visit:: Visitor ;
20
+ use rustc_front:: intravisit:: Visitor ;
21
21
22
- struct EntryContext < ' a > {
22
+ struct EntryContext < ' a , ' tcx : ' a > {
23
23
session : & ' a Session ,
24
24
25
- // The current depth in the ast
26
- depth : usize ,
25
+ map : & ' a ast_map:: Map < ' tcx > ,
27
26
28
27
// The top-level function called 'main'
29
28
main_fn : Option < ( NodeId , Span ) > ,
@@ -39,11 +38,12 @@ struct EntryContext<'a> {
39
38
non_main_fns : Vec < ( NodeId , Span ) > ,
40
39
}
41
40
42
- impl < ' a , ' v > Visitor < ' v > for EntryContext < ' a > {
43
- fn visit_item ( & mut self , item : & Item ) {
44
- self . depth += 1 ;
45
- find_item ( item, self ) ;
46
- self . depth -= 1 ;
41
+ impl < ' a , ' tcx > Visitor < ' tcx > for EntryContext < ' a , ' tcx > {
42
+ fn visit_item ( & mut self , item : & ' tcx Item ) {
43
+ let def_id = self . map . local_def_id ( item. id ) ;
44
+ let def_key = self . map . def_key ( def_id) ;
45
+ let at_root = def_key. parent == Some ( CRATE_DEF_INDEX ) ;
46
+ find_item ( item, self , at_root) ;
47
47
}
48
48
}
49
49
@@ -64,29 +64,29 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
64
64
65
65
let mut ctxt = EntryContext {
66
66
session : session,
67
- depth : 0 ,
67
+ map : ast_map ,
68
68
main_fn : None ,
69
69
attr_main_fn : None ,
70
70
start_fn : None ,
71
71
non_main_fns : Vec :: new ( ) ,
72
72
} ;
73
73
74
- visit :: walk_crate ( & mut ctxt , ast_map. krate ( ) ) ;
74
+ ast_map. krate ( ) . visit_all_items ( & mut ctxt ) ;
75
75
76
76
configure_main ( & mut ctxt) ;
77
77
}
78
78
79
79
// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
80
80
// them in sync.
81
- fn entry_point_type ( item : & Item , depth : usize ) -> EntryPointType {
81
+ fn entry_point_type ( item : & Item , at_root : bool ) -> EntryPointType {
82
82
match item. node {
83
83
ItemFn ( ..) => {
84
84
if attr:: contains_name ( & item. attrs , "start" ) {
85
85
EntryPointType :: Start
86
86
} else if attr:: contains_name ( & item. attrs , "main" ) {
87
87
EntryPointType :: MainAttr
88
88
} else if item. name . as_str ( ) == "main" {
89
- if depth == 1 {
89
+ if at_root {
90
90
// This is a top-level function so can be 'main'
91
91
EntryPointType :: MainNamed
92
92
} else {
@@ -101,8 +101,8 @@ fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
101
101
}
102
102
103
103
104
- fn find_item ( item : & Item , ctxt : & mut EntryContext ) {
105
- match entry_point_type ( item, ctxt . depth ) {
104
+ fn find_item ( item : & Item , ctxt : & mut EntryContext , at_root : bool ) {
105
+ match entry_point_type ( item, at_root ) {
106
106
EntryPointType :: MainNamed => {
107
107
if ctxt. main_fn . is_none ( ) {
108
108
ctxt. main_fn = Some ( ( item. id , item. span ) ) ;
@@ -132,8 +132,6 @@ fn find_item(item: &Item, ctxt: &mut EntryContext) {
132
132
} ,
133
133
EntryPointType :: None => ( )
134
134
}
135
-
136
- visit:: walk_item ( ctxt, item) ;
137
135
}
138
136
139
137
fn configure_main ( this : & mut EntryContext ) {
0 commit comments