11use hir:: map as hir_map;
2- use hir:: def_id:: { CRATE_DEF_INDEX } ;
2+ use hir:: def_id:: { CrateNum , CRATE_DEF_INDEX , DefId , LOCAL_CRATE } ;
33use session:: { config, Session } ;
44use session:: config:: EntryFnType ;
55use syntax:: ast:: NodeId ;
@@ -8,6 +8,8 @@ use syntax::entry::EntryPointType;
88use syntax_pos:: Span ;
99use hir:: { Item , ItemKind , ImplItem , TraitItem } ;
1010use hir:: itemlikevisit:: ItemLikeVisitor ;
11+ use ty:: TyCtxt ;
12+ use ty:: query:: Providers ;
1113
1214struct EntryContext < ' a , ' tcx : ' a > {
1315 session : & ' a Session ,
@@ -45,36 +47,34 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
4547 }
4648}
4749
48- pub fn find_entry_point ( session : & Session ,
49- hir_map : & hir_map :: Map < ' _ > ,
50- crate_name : & str ) {
51- let any_exe = session . crate_types . borrow ( ) . iter ( ) . any ( |ty| {
50+ fn entry_fn ( tcx : TyCtxt < ' _ , ' _ , ' _ > , cnum : CrateNum ) -> Option < ( DefId , EntryFnType ) > {
51+ assert_eq ! ( cnum , LOCAL_CRATE ) ;
52+
53+ let any_exe = tcx . sess . crate_types . borrow ( ) . iter ( ) . any ( |ty| {
5254 * ty == config:: CrateType :: Executable
5355 } ) ;
5456 if !any_exe {
5557 // No need to find a main function
56- session. entry_fn . set ( None ) ;
57- return
58+ return None ;
5859 }
5960
6061 // If the user wants no main function at all, then stop here.
61- if attr:: contains_name ( & hir_map. krate ( ) . attrs , "no_main" ) {
62- session. entry_fn . set ( None ) ;
63- return
62+ if attr:: contains_name ( & tcx. hir ( ) . krate ( ) . attrs , "no_main" ) {
63+ return None ;
6464 }
6565
6666 let mut ctxt = EntryContext {
67- session,
68- map : hir_map ,
67+ session : tcx . sess ,
68+ map : tcx . hir ( ) ,
6969 main_fn : None ,
7070 attr_main_fn : None ,
7171 start_fn : None ,
7272 non_main_fns : Vec :: new ( ) ,
7373 } ;
7474
75- hir_map . krate ( ) . visit_all_item_likes ( & mut ctxt) ;
75+ tcx . hir ( ) . krate ( ) . visit_all_item_likes ( & mut ctxt) ;
7676
77- configure_main ( & mut ctxt , crate_name ) ;
77+ configure_main ( tcx , & ctxt )
7878}
7979
8080// Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
@@ -135,43 +135,58 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
135135 . span_label ( item. span , "multiple `start` functions" )
136136 . emit ( ) ;
137137 }
138- } ,
139- EntryPointType :: None => ( )
138+ }
139+ EntryPointType :: None => ( ) ,
140140 }
141141}
142142
143- fn configure_main ( this : & mut EntryContext < ' _ , ' _ > , crate_name : & str ) {
144- if let Some ( ( node_id, span) ) = this. start_fn {
145- this. session . entry_fn . set ( Some ( ( node_id, span, EntryFnType :: Start ) ) ) ;
146- } else if let Some ( ( node_id, span) ) = this. attr_main_fn {
147- this. session . entry_fn . set ( Some ( ( node_id, span, EntryFnType :: Main ) ) ) ;
148- } else if let Some ( ( node_id, span) ) = this. main_fn {
149- this. session . entry_fn . set ( Some ( ( node_id, span, EntryFnType :: Main ) ) ) ;
143+ fn configure_main (
144+ tcx : TyCtxt < ' _ , ' _ , ' _ > ,
145+ visitor : & EntryContext < ' _ , ' _ > ,
146+ ) -> Option < ( DefId , EntryFnType ) > {
147+ if let Some ( ( node_id, _) ) = visitor. start_fn {
148+ Some ( ( tcx. hir ( ) . local_def_id ( node_id) , EntryFnType :: Start ) )
149+ } else if let Some ( ( node_id, _) ) = visitor. attr_main_fn {
150+ Some ( ( tcx. hir ( ) . local_def_id ( node_id) , EntryFnType :: Main ) )
151+ } else if let Some ( ( node_id, _) ) = visitor. main_fn {
152+ Some ( ( tcx. hir ( ) . local_def_id ( node_id) , EntryFnType :: Main ) )
150153 } else {
151154 // No main function
152- this. session . entry_fn . set ( None ) ;
153- let mut err = struct_err ! ( this. session, E0601 ,
154- "`main` function not found in crate `{}`" , crate_name) ;
155- if !this. non_main_fns . is_empty ( ) {
155+ let mut err = struct_err ! ( tcx. sess, E0601 ,
156+ "`main` function not found in crate `{}`" , tcx. crate_name( LOCAL_CRATE ) ) ;
157+ if !visitor. non_main_fns . is_empty ( ) {
156158 // There were some functions named 'main' though. Try to give the user a hint.
157159 err. note ( "the main function must be defined at the crate level \
158160 but you have one or more functions named 'main' that are not \
159161 defined at the crate level. Either move the definition or \
160162 attach the `#[main]` attribute to override this behavior.") ;
161- for & ( _, span) in & this . non_main_fns {
163+ for & ( _, span) in & visitor . non_main_fns {
162164 err. span_note ( span, "here is a function named 'main'" ) ;
163165 }
164166 err. emit ( ) ;
165- this . session . abort_if_errors ( ) ;
167+ tcx . sess . abort_if_errors ( ) ;
166168 } else {
167- if let Some ( ref filename) = this . session . local_crate_source_file {
169+ if let Some ( ref filename) = tcx . sess . local_crate_source_file {
168170 err. note ( & format ! ( "consider adding a `main` function to `{}`" , filename. display( ) ) ) ;
169171 }
170- if this . session . teach ( & err. get_code ( ) . unwrap ( ) ) {
172+ if tcx . sess . teach ( & err. get_code ( ) . unwrap ( ) ) {
171173 err. note ( "If you don't know the basics of Rust, you can go look to the Rust Book \
172174 to get started: https://doc.rust-lang.org/book/") ;
173175 }
174176 err. emit ( ) ;
175177 }
178+
179+ None
176180 }
177181}
182+
183+ pub fn find_entry_point ( tcx : TyCtxt < ' _ , ' _ , ' _ > ) -> Option < ( DefId , EntryFnType ) > {
184+ tcx. entry_fn ( LOCAL_CRATE )
185+ }
186+
187+ pub fn provide ( providers : & mut Providers < ' _ > ) {
188+ * providers = Providers {
189+ entry_fn,
190+ ..* providers
191+ } ;
192+ }
0 commit comments