Combine Session.entry_fn and Session.entry_type and make them thread-safe
This commit is contained in:
parent
7aa7198b4b
commit
27adb31fcc
11 changed files with 31 additions and 38 deletions
|
|
@ -408,7 +408,7 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
|
||||
// Seed entry point
|
||||
if let Some((id, _)) = *tcx.sess.entry_fn.borrow() {
|
||||
if let Some((id, _, _)) = *tcx.sess.entry_fn.borrow() {
|
||||
worklist.push(id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,12 +63,13 @@ pub fn find_entry_point(session: &Session,
|
|||
});
|
||||
if !any_exe {
|
||||
// No need to find a main function
|
||||
session.entry_fn.set(None);
|
||||
return
|
||||
}
|
||||
|
||||
// If the user wants no main function at all, then stop here.
|
||||
if attr::contains_name(&hir_map.krate().attrs, "no_main") {
|
||||
session.entry_type.set(Some(config::EntryNone));
|
||||
session.entry_fn.set(None);
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -153,17 +154,15 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
|
|||
}
|
||||
|
||||
fn configure_main(this: &mut EntryContext, crate_name: &str) {
|
||||
if this.start_fn.is_some() {
|
||||
*this.session.entry_fn.borrow_mut() = this.start_fn;
|
||||
this.session.entry_type.set(Some(config::EntryStart));
|
||||
} else if this.attr_main_fn.is_some() {
|
||||
*this.session.entry_fn.borrow_mut() = this.attr_main_fn;
|
||||
this.session.entry_type.set(Some(config::EntryMain));
|
||||
} else if this.main_fn.is_some() {
|
||||
*this.session.entry_fn.borrow_mut() = this.main_fn;
|
||||
this.session.entry_type.set(Some(config::EntryMain));
|
||||
if let Some((node_id, span)) = this.start_fn {
|
||||
this.session.entry_fn.set(Some((node_id, span, config::EntryStart)));
|
||||
} else if let Some((node_id, span)) = this.attr_main_fn {
|
||||
this.session.entry_fn.set(Some((node_id, span, config::EntryMain)));
|
||||
} else if let Some((node_id, span)) = this.main_fn {
|
||||
this.session.entry_fn.set(Some((node_id, span, config::EntryMain)));
|
||||
} else {
|
||||
// No main function
|
||||
this.session.entry_fn.set(None);
|
||||
let mut err = struct_err!(this.session, E0601,
|
||||
"`main` function not found in crate `{}`", crate_name);
|
||||
if !this.non_main_fns.is_empty() {
|
||||
|
|
|
|||
|
|
@ -614,13 +614,11 @@ impl Options {
|
|||
|
||||
// The type of entry function, so
|
||||
// users can have their own entry
|
||||
// functions that don't start a
|
||||
// scheduler
|
||||
// functions
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum EntryFnType {
|
||||
EntryMain,
|
||||
EntryStart,
|
||||
EntryNone,
|
||||
}
|
||||
|
||||
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
|
||||
|
|
|
|||
|
|
@ -70,8 +70,7 @@ pub struct Session {
|
|||
pub opts: config::Options,
|
||||
pub parse_sess: ParseSess,
|
||||
/// For a library crate, this is always none
|
||||
pub entry_fn: RefCell<Option<(NodeId, Span)>>,
|
||||
pub entry_type: Cell<Option<config::EntryFnType>>,
|
||||
pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
|
||||
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
|
||||
pub derive_registrar_fn: Cell<Option<ast::NodeId>>,
|
||||
pub default_sysroot: Option<PathBuf>,
|
||||
|
|
@ -1094,8 +1093,7 @@ pub fn build_session_(
|
|||
opts: sopts,
|
||||
parse_sess: p_s,
|
||||
// For a library crate, this is always none
|
||||
entry_fn: RefCell::new(None),
|
||||
entry_type: Cell::new(None),
|
||||
entry_fn: Once::new(),
|
||||
plugin_registrar_fn: Cell::new(None),
|
||||
derive_registrar_fn: Cell::new(None),
|
||||
default_sysroot,
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let mut roots = Vec::new();
|
||||
|
||||
{
|
||||
let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _)| {
|
||||
let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _, _)| {
|
||||
tcx.hir.local_def_id(node_id)
|
||||
});
|
||||
|
||||
|
|
@ -1038,7 +1038,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
|
|||
/// the return type of `main`. This is not needed when
|
||||
/// the user writes their own `start` manually.
|
||||
fn push_extra_entry_roots(&mut self) {
|
||||
if self.tcx.sess.entry_type.get() != Some(config::EntryMain) {
|
||||
if self.tcx.sess.entry_fn.get().map(|e| e.2) != Some(config::EntryMain) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
|
|||
match *self.as_mono_item() {
|
||||
MonoItem::Fn(ref instance) => {
|
||||
let entry_def_id =
|
||||
tcx.sess.entry_fn.borrow().map(|(id, _)| tcx.hir.local_def_id(id));
|
||||
tcx.sess.entry_fn.borrow().map(|(id, _, _)| tcx.hir.local_def_id(id));
|
||||
// If this function isn't inlined or otherwise has explicit
|
||||
// linkage, then we'll be creating a globally shared version.
|
||||
if self.explicit_linkage(tcx).is_some() ||
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ pub fn set_link_section(cx: &CodegenCx,
|
|||
/// users main function.
|
||||
fn maybe_create_entry_wrapper(cx: &CodegenCx) {
|
||||
let (main_def_id, span) = match *cx.sess().entry_fn.borrow() {
|
||||
Some((id, span)) => {
|
||||
Some((id, span, _)) => {
|
||||
(cx.tcx.hir.local_def_id(id), span)
|
||||
}
|
||||
None => return,
|
||||
|
|
@ -533,11 +533,11 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
|
|||
|
||||
let main_llfn = callee::get_fn(cx, instance);
|
||||
|
||||
let et = cx.sess().entry_type.get().unwrap();
|
||||
let et = cx.sess().entry_fn.get().map(|e| e.2);
|
||||
match et {
|
||||
config::EntryMain => create_entry_fn(cx, span, main_llfn, main_def_id, true),
|
||||
config::EntryStart => create_entry_fn(cx, span, main_llfn, main_def_id, false),
|
||||
config::EntryNone => {} // Do nothing.
|
||||
Some(config::EntryMain) => create_entry_fn(cx, span, main_llfn, main_def_id, true),
|
||||
Some(config::EntryStart) => create_entry_fn(cx, span, main_llfn, main_def_id, false),
|
||||
None => {} // Do nothing.
|
||||
}
|
||||
|
||||
fn create_entry_fn<'cx>(cx: &'cx CodegenCx,
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
|
||||
let local_id = cx.tcx.hir.as_local_node_id(def_id);
|
||||
match *cx.sess().entry_fn.borrow() {
|
||||
Some((id, _)) => {
|
||||
Some((id, _, _)) => {
|
||||
if local_id == Some(id) {
|
||||
flags = flags | DIFlags::FlagMainSubprogram;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ pub mod symbol_names_test;
|
|||
/// that actually test that compilation succeeds without
|
||||
/// reporting an error.
|
||||
pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
|
||||
if let Some((id, span)) = *tcx.sess.entry_fn.borrow() {
|
||||
if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
|
||||
let main_def_id = tcx.hir.local_def_id(id);
|
||||
|
||||
if tcx.has_attr(main_def_id, "rustc_error") {
|
||||
|
|
|
|||
|
|
@ -1128,10 +1128,10 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
|
||||
// Check that the main return type implements the termination trait.
|
||||
if let Some(term_id) = fcx.tcx.lang_items().termination() {
|
||||
if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
|
||||
if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
|
||||
if id == fn_id {
|
||||
match fcx.sess().entry_type.get() {
|
||||
Some(config::EntryMain) => {
|
||||
match entry_type {
|
||||
config::EntryMain => {
|
||||
let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
|
||||
let trait_ref = ty::TraitRef::new(term_id, substs);
|
||||
let return_ty_span = decl.output.span();
|
||||
|
|
@ -1142,7 +1142,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
traits::Obligation::new(
|
||||
cause, param_env, trait_ref.to_predicate()));
|
||||
},
|
||||
_ => {},
|
||||
config::EntryStart => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,12 +289,10 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
|
||||
fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
|
||||
match tcx.sess.entry_type.get() {
|
||||
Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp),
|
||||
Some(config::EntryStart) => check_start_fn_ty(tcx, id, sp),
|
||||
Some(config::EntryNone) => {}
|
||||
None => bug!("entry function without a type")
|
||||
if let Some((id, sp, entry_type)) = *tcx.sess.entry_fn.borrow() {
|
||||
match entry_type {
|
||||
config::EntryMain => check_main_fn_ty(tcx, id, sp),
|
||||
config::EntryStart => check_start_fn_ty(tcx, id, sp),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue