about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/driver/driver.rs2
-rw-r--r--src/librustc/driver/session.rs22
-rw-r--r--src/librustc/front/std_inject.rs7
-rw-r--r--src/librustc/front/test.rs26
-rw-r--r--src/librustc/middle/entry.rs29
-rw-r--r--src/librustc/middle/reachable.rs9
-rw-r--r--src/librustc/middle/trans/base.rs7
-rw-r--r--src/librustc/middle/typeck/mod.rs18
-rw-r--r--src/test/run-make/libs-and-bins/Makefile7
-rw-r--r--src/test/run-make/libs-and-bins/foo.rs14
10 files changed, 73 insertions, 68 deletions
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index b579a9b9c64..5aa22f7e6d5 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -210,7 +210,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
                                     -> (ast::Crate, syntax::ast_map::Map) {
     let time_passes = sess.time_passes();
 
-    sess.building_library.set(session::building_library(&sess.opts, &krate));
     *sess.crate_types.borrow_mut() = session::collect_crate_types(sess, krate.attrs.as_slice());
 
     time(time_passes, "gated feature checking", (), |_|
@@ -1046,7 +1045,6 @@ pub fn build_session_(sopts: session::Options,
         entry_type: Cell::new(None),
         macro_registrar_fn: Cell::new(None),
         default_sysroot: default_sysroot,
-        building_library: Cell::new(false),
         local_crate_source_file: local_crate_source_file,
         working_dir: os::getcwd(),
         lints: RefCell::new(NodeMap::new()),
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 950e6bd8ee8..58ccfeab73d 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -25,7 +25,6 @@ use syntax::codemap::Span;
 use syntax::diagnostic;
 use syntax::parse::ParseSess;
 use syntax::{abi, ast, codemap};
-use syntax;
 
 use std::cell::{Cell, RefCell};
 use collections::HashSet;
@@ -185,7 +184,6 @@ pub struct Session {
     pub entry_type: Cell<Option<EntryFnType>>,
     pub macro_registrar_fn: Cell<Option<ast::NodeId>>,
     pub default_sysroot: Option<Path>,
-    pub building_library: Cell<bool>,
     // The name of the root source file of the crate, in the local file system. The path is always
     // expected to be absolute. `None` means that there is no source file.
     pub local_crate_source_file: Option<Path>,
@@ -477,26 +475,6 @@ pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> ~str) -> T {
     diagnostic::expect(sess.diagnostic(), opt, msg)
 }
 
-pub fn building_library(options: &Options, krate: &ast::Crate) -> bool {
-    if options.test { return false }
-    for output in options.crate_types.iter() {
-        match *output {
-            CrateTypeExecutable => {}
-            CrateTypeStaticlib | CrateTypeDylib | CrateTypeRlib => return true
-        }
-    }
-    match syntax::attr::first_attr_value_str_by_name(krate.attrs.as_slice(),
-                                                     "crate_type") {
-        Some(s) => {
-            s.equiv(&("lib")) ||
-            s.equiv(&("rlib")) ||
-            s.equiv(&("dylib")) ||
-            s.equiv(&("staticlib"))
-        }
-        _ => false
-    }
-}
-
 pub fn default_lib_output() -> CrateType {
     CrateTypeRlib
 }
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index 7f4c560c146..959197e5b2b 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use driver::session;
 use driver::session::Session;
 
 use syntax::ast;
@@ -86,7 +86,10 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
             span: DUMMY_SP
         });
 
-        if use_start(&krate) && !self.sess.building_library.get() {
+        let any_exe = self.sess.crate_types.borrow().iter().any(|ty| {
+            *ty == session::CrateTypeExecutable
+        });
+        if use_start(&krate) && any_exe {
             vis.push(ast::ViewItem {
                 node: ast::ViewItemExternCrate(token::str_to_ident("native"),
                                              with_version("native"),
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index b5797b2571d..d7f4173b529 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -125,27 +125,23 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
         // Remove any #[main] from the AST so it doesn't clash with
         // the one we're going to add. Only if compiling an executable.
 
-        fn nomain(cx: &TestCtxt, item: @ast::Item) -> @ast::Item {
-            if !cx.sess.building_library.get() {
-                @ast::Item {
-                    attrs: item.attrs.iter().filter_map(|attr| {
-                        if !attr.name().equiv(&("main")) {
-                            Some(*attr)
-                        } else {
-                            None
-                        }
-                    }).collect(),
-                    .. (*item).clone()
-                }
-            } else {
-                item
+        fn nomain(item: @ast::Item) -> @ast::Item {
+            @ast::Item {
+                attrs: item.attrs.iter().filter_map(|attr| {
+                    if !attr.name().equiv(&("main")) {
+                        Some(*attr)
+                    } else {
+                        None
+                    }
+                }).collect(),
+                .. (*item).clone()
             }
         }
 
         let mod_nomain = ast::Mod {
             inner: m.inner,
             view_items: m.view_items.clone(),
-            items: m.items.iter().map(|i| nomain(&self.cx, *i)).collect(),
+            items: m.items.iter().map(|i| nomain(*i)).collect(),
         };
 
         fold::noop_fold_mod(&mod_nomain, self)
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 441a3a36729..a17c8fb5c43 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -48,9 +48,12 @@ impl<'a> Visitor<()> for EntryContext<'a> {
 }
 
 pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map) {
-    if session.building_library.get() {
+    let any_exe = session.crate_types.borrow().iter().any(|ty| {
+        *ty == session::CrateTypeExecutable
+    });
+    if !any_exe {
         // No need to find a main function
-        return;
+        return
     }
 
     // If the user wants no main function at all, then stop here.
@@ -132,18 +135,16 @@ fn configure_main(this: &mut EntryContext) {
         *this.session.entry_fn.borrow_mut() = this.main_fn;
         this.session.entry_type.set(Some(session::EntryMain));
     } else {
-        if !this.session.building_library.get() {
-            // No main function
-            this.session.err("main function not found");
-            if !this.non_main_fns.is_empty() {
-                // There were some functions named 'main' though. Try to give the user a hint.
-                this.session.note("the main function must be defined at the crate level \
-                                   but you have one or more functions named 'main' that are not \
-                                   defined at the crate level. Either move the definition or \
-                                   attach the `#[main]` attribute to override this behavior.");
-                for &(_, span) in this.non_main_fns.iter() {
-                    this.session.span_note(span, "here is a function named 'main'");
-                }
+        // No main function
+        this.session.err("main function not found");
+        if !this.non_main_fns.is_empty() {
+            // There were some functions named 'main' though. Try to give the user a hint.
+            this.session.note("the main function must be defined at the crate level \
+                               but you have one or more functions named 'main' that are not \
+                               defined at the crate level. Either move the definition or \
+                               attach the `#[main]` attribute to override this behavior.");
+            for &(_, span) in this.non_main_fns.iter() {
+                this.session.span_note(span, "here is a function named 'main'");
             }
             this.session.abort_if_errors();
         }
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 6e2edb4e8b2..644861b59fe 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -15,6 +15,7 @@
 // makes all other generics or inline functions that it references
 // reachable as well.
 
+use driver::session;
 use middle::ty;
 use middle::typeck;
 use middle::privacy;
@@ -89,6 +90,8 @@ struct ReachableContext<'a> {
     // A worklist of item IDs. Each item ID in this worklist will be inlined
     // and will be scanned for further references.
     worklist: Vec<ast::NodeId>,
+    // Whether any output of this compilation is a library
+    any_library: bool,
 }
 
 impl<'a> Visitor<()> for ReachableContext<'a> {
@@ -157,10 +160,14 @@ impl<'a> Visitor<()> for ReachableContext<'a> {
 impl<'a> ReachableContext<'a> {
     // Creates a new reachability computation context.
     fn new(tcx: &'a ty::ctxt) -> ReachableContext<'a> {
+        let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
+            *ty != session::CrateTypeExecutable
+        });
         ReachableContext {
             tcx: tcx,
             reachable_symbols: NodeSet::new(),
             worklist: Vec::new(),
+            any_library: any_library,
         }
     }
 
@@ -234,7 +241,7 @@ impl<'a> ReachableContext<'a> {
 
     fn propagate_node(&mut self, node: &ast_map::Node,
                       search_item: ast::NodeId) {
-        if !self.tcx.sess.building_library.get() {
+        if !self.any_library {
             // If we are building an executable, then there's no need to flag
             // anything as external except for `extern fn` types. These
             // functions may still participate in some form of native interface,
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index daed00a32f2..960cc2f921a 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1663,7 +1663,7 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: ~str, node_id: ast::Nod
         lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
     }
 
-    if is_entry_fn(ccx.sess(), node_id) && !ccx.sess().building_library.get() {
+    if is_entry_fn(ccx.sess(), node_id) {
         create_entry_wrapper(ccx, sp, llfn);
     }
 }
@@ -2062,7 +2062,10 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeI
 pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
     use flate;
 
-    if !cx.sess().building_library.get() {
+    let any_library = cx.sess().crate_types.borrow().iter().any(|ty| {
+        *ty != session::CrateTypeExecutable
+    });
+    if !any_library {
         return Vec::new()
     }
 
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 26f0bc7ec72..84b08851deb 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -409,16 +409,14 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
 
 fn check_for_entry_fn(ccx: &CrateCtxt) {
     let tcx = ccx.tcx;
-    if !tcx.sess.building_library.get() {
-        match *tcx.sess.entry_fn.borrow() {
-          Some((id, sp)) => match tcx.sess.entry_type.get() {
-              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 => {}
-        }
+    match *tcx.sess.entry_fn.borrow() {
+        Some((id, sp)) => match tcx.sess.entry_type.get() {
+            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 => {}
     }
 }
 
diff --git a/src/test/run-make/libs-and-bins/Makefile b/src/test/run-make/libs-and-bins/Makefile
new file mode 100644
index 00000000000..4d975d2f717
--- /dev/null
+++ b/src/test/run-make/libs-and-bins/Makefile
@@ -0,0 +1,7 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) foo.rs
+	$(call RUN,foo)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,foo)
+
diff --git a/src/test/run-make/libs-and-bins/foo.rs b/src/test/run-make/libs-and-bins/foo.rs
new file mode 100644
index 00000000000..2ebe63928ca
--- /dev/null
+++ b/src/test/run-make/libs-and-bins/foo.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+#![crate_type = "bin"]
+
+fn main() {}