]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/entry.rs
Auto merge of #30341 - pnkfelix:call-site-scope, r=nikomatsakis
[rust.git] / src / librustc / middle / entry.rs
index 8cdd4f7fe74c5562588f00a828a744035fd06052..ecf16aaed836a699c72457bb2781a120fce1e7d1 100644 (file)
@@ -9,21 +9,20 @@
 // except according to those terms.
 
 
-use ast_map;
+use front::map as ast_map;
+use middle::def_id::{CRATE_DEF_INDEX};
 use session::{config, Session};
-use syntax;
-use syntax::ast::{NodeId, Item};
+use syntax::ast::NodeId;
 use syntax::attr;
 use syntax::codemap::Span;
 use syntax::entry::EntryPointType;
-use syntax::visit;
-use syntax::visit::Visitor;
+use rustc_front::hir::{Item, ItemFn};
+use rustc_front::intravisit::Visitor;
 
-struct EntryContext<'a> {
+struct EntryContext<'a, 'tcx: 'a> {
     session: &'a Session,
 
-    // The current depth in the ast
-    depth: usize,
+    map: &'a ast_map::Map<'tcx>,
 
     // The top-level function called 'main'
     main_fn: Option<(NodeId, Span)>,
@@ -39,11 +38,12 @@ struct EntryContext<'a> {
     non_main_fns: Vec<(NodeId, Span)> ,
 }
 
-impl<'a, 'v> Visitor<'v> for EntryContext<'a> {
-    fn visit_item(&mut self, item: &Item) {
-        self.depth += 1;
-        find_item(item, self);
-        self.depth -= 1;
+impl<'a, 'tcx> Visitor<'tcx> for EntryContext<'a, 'tcx> {
+    fn visit_item(&mut self, item: &'tcx Item) {
+        let def_id = self.map.local_def_id(item.id);
+        let def_key = self.map.def_key(def_id);
+        let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
+        find_item(item, self, at_root);
     }
 }
 
@@ -64,20 +64,45 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
 
     let mut ctxt = EntryContext {
         session: session,
-        depth: 0,
+        map: ast_map,
         main_fn: None,
         attr_main_fn: None,
         start_fn: None,
         non_main_fns: Vec::new(),
     };
 
-    visit::walk_crate(&mut ctxt, ast_map.krate());
+    ast_map.krate().visit_all_items(&mut ctxt);
 
     configure_main(&mut ctxt);
 }
 
-fn find_item(item: &Item, ctxt: &mut EntryContext) {
-    match syntax::entry::entry_point_type(item, ctxt.depth) {
+// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
+// them in sync.
+fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
+    match item.node {
+        ItemFn(..) => {
+            if attr::contains_name(&item.attrs, "start") {
+                EntryPointType::Start
+            } else if attr::contains_name(&item.attrs, "main") {
+                EntryPointType::MainAttr
+            } else if item.name.as_str() == "main" {
+                if at_root {
+                    // This is a top-level function so can be 'main'
+                    EntryPointType::MainNamed
+                } else {
+                    EntryPointType::OtherMain
+                }
+            } else {
+                EntryPointType::None
+            }
+        }
+        _ => EntryPointType::None,
+    }
+}
+
+
+fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
+    match entry_point_type(item, at_root) {
         EntryPointType::MainNamed => {
             if ctxt.main_fn.is_none() {
                 ctxt.main_fn = Some((item.id, item.span));
@@ -107,8 +132,6 @@ fn find_item(item: &Item, ctxt: &mut EntryContext) {
         },
         EntryPointType::None => ()
     }
-
-    visit::walk_item(ctxt, item);
 }
 
 fn configure_main(this: &mut EntryContext) {