From 9c08db58ab8457878ce67c99e1e7a32ce7ee053a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sat, 3 Aug 2013 19:59:46 -0700 Subject: [PATCH] librustc: Implement `#[no_main]`, which omits the entry point entirely. Useful for SDL and possibly Android too. --- src/librustc/driver/session.rs | 3 ++- src/librustc/middle/entry.rs | 6 ++++++ src/librustc/middle/trans/base.rs | 15 +++++++++------ src/librustc/middle/typeck/mod.rs | 3 ++- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index e43f85008d5..d725e2db1eb 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -179,7 +179,8 @@ pub struct crate_metadata { #[deriving(Eq)] pub enum EntryFnType { EntryMain, - EntryStart + EntryStart, + EntryNone, } pub struct Session_ { diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 469c1c2f93e..39e569a29c9 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -50,6 +50,12 @@ pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map) return; } + // If the user wants no main function at all, then stop here. + if attr::contains_name(crate.attrs, "no_main") { + *session.entry_type = Some(session::EntryNone); + return + } + let ctxt = @mut EntryContext { session: session, ast_map: ast_map, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e0a7cd8cc0b..ff6fa714322 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2295,13 +2295,16 @@ pub fn is_entry_fn(sess: &Session, node_id: ast::NodeId) -> bool { // Create a _rust_main(args: ~[str]) function which will be called from the // runtime rust_start function pub fn create_entry_wrapper(ccx: @mut CrateContext, - _sp: span, main_llfn: ValueRef) { + _sp: span, + main_llfn: ValueRef) { let et = ccx.sess.entry_type.unwrap(); - if et == session::EntryMain { - let llfn = create_main(ccx, main_llfn); - create_entry_fn(ccx, llfn, true); - } else { - create_entry_fn(ccx, main_llfn, false); + match et { + session::EntryMain => { + let llfn = create_main(ccx, main_llfn); + create_entry_fn(ccx, llfn, true); + } + session::EntryStart => create_entry_fn(ccx, main_llfn, false), + session::EntryNone => {} // Do nothing. } fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef { diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 6128c169967..e6c27fc8f83 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -408,9 +408,10 @@ fn check_for_entry_fn(ccx: &CrateCtxt) { Some((id, sp)) => match *tcx.sess.entry_type { Some(session::EntryMain) => check_main_fn_ty(ccx, id, sp), Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp), + Some(session::EntryNone) => {} None => tcx.sess.bug("entry function without a type") }, - None => tcx.sess.bug("type checking without entry function") + None => {} } } }