提交 27adb31f 编写于 作者: J John Kåre Alsaker

Combine Session.entry_fn and Session.entry_type and make them thread-safe

上级 7aa7198b
......@@ -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 @@ pub fn will_create_output_file(&self) -> bool {
// 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 @@ fn push_if_root(&mut self, def_id: DefId) {
/// 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 @@ fn instantiation_mode(&self,
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 @@
/// 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),
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册