From 825f6ace1d8692af23f4a2842c87cb2dcc864fad Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 2 May 2014 15:26:45 -0700 Subject: [PATCH] rustc: Remove the session building_library flag This has long since not been too relevant since the introduction of many crate type outputs. This commit removes the flag entirely, adjusting all logic to do the most reasonable thing when building both a library and an executable. Closes #13337 --- src/librustc/driver/driver.rs | 2 -- src/librustc/driver/session.rs | 22 ------------------ src/librustc/front/std_inject.rs | 7 ++++-- src/librustc/front/test.rs | 26 +++++++++------------ src/librustc/middle/entry.rs | 29 ++++++++++++------------ src/librustc/middle/reachable.rs | 9 +++++++- src/librustc/middle/trans/base.rs | 7 ++++-- src/librustc/middle/typeck/mod.rs | 18 +++++++-------- src/test/run-make/libs-and-bins/Makefile | 7 ++++++ src/test/run-make/libs-and-bins/foo.rs | 14 ++++++++++++ 10 files changed, 73 insertions(+), 68 deletions(-) create mode 100644 src/test/run-make/libs-and-bins/Makefile create mode 100644 src/test/run-make/libs-and-bins/foo.rs diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index b579a9b9c64c1..5aa22f7e6d561 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 950e6bd8ee833..58ccfeab73d18 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>, pub macro_registrar_fn: Cell>, pub default_sysroot: Option, - pub building_library: Cell, // 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, @@ -477,26 +475,6 @@ pub fn expect(sess: &Session, opt: Option, 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 7f4c560c146a1..959197e5b2b02 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 b5797b2571d3d..d7f4173b529c4 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 441a3a3672983..a17c8fb5c433e 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 6e2edb4e8b2ae..644861b59fed6 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, + // 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 daed00a32f21d..960cc2f921aa4 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 { 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 26f0bc7ec728c..84b08851deb7b 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 0000000000000..4d975d2f71718 --- /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 0000000000000..2ebe63928cad6 --- /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 or the MIT license +// , 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() {}