Querify entry_fn
This commit is contained in:
parent
33e6df4b62
commit
ff19a53ef0
17 changed files with 115 additions and 109 deletions
|
@ -583,6 +583,7 @@ define_dep_nodes!( <'tcx>
|
||||||
[] CheckImplItemWellFormed(DefId),
|
[] CheckImplItemWellFormed(DefId),
|
||||||
[] ReachableNonGenerics(CrateNum),
|
[] ReachableNonGenerics(CrateNum),
|
||||||
[] NativeLibraries(CrateNum),
|
[] NativeLibraries(CrateNum),
|
||||||
|
[] EntryFn(CrateNum),
|
||||||
[] PluginRegistrarFn(CrateNum),
|
[] PluginRegistrarFn(CrateNum),
|
||||||
[] ProcMacroDeclsStatic(CrateNum),
|
[] ProcMacroDeclsStatic(CrateNum),
|
||||||
[input] CrateDisambiguator(CrateNum),
|
[input] CrateDisambiguator(CrateNum),
|
||||||
|
|
|
@ -409,7 +409,7 @@ fn create_and_seed_worklist<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
}).chain(
|
}).chain(
|
||||||
// Seed entry point
|
// Seed entry point
|
||||||
tcx.sess.entry_fn.borrow().map(|(id, _, _)| id)
|
tcx.entry_fn(LOCAL_CRATE).map(|(def_id, _)| tcx.hir().as_local_node_id(def_id).unwrap())
|
||||||
).collect::<Vec<_>>();
|
).collect::<Vec<_>>();
|
||||||
|
|
||||||
// Seed implemented trait items
|
// Seed implemented trait items
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use hir::map as hir_map;
|
use hir::map as hir_map;
|
||||||
use hir::def_id::{CRATE_DEF_INDEX};
|
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||||
use session::{config, Session};
|
use session::{config, Session};
|
||||||
use session::config::EntryFnType;
|
use session::config::EntryFnType;
|
||||||
use syntax::ast::NodeId;
|
use syntax::ast::NodeId;
|
||||||
|
@ -8,6 +8,8 @@ use syntax::entry::EntryPointType;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use hir::{Item, ItemKind, ImplItem, TraitItem};
|
use hir::{Item, ItemKind, ImplItem, TraitItem};
|
||||||
use hir::itemlikevisit::ItemLikeVisitor;
|
use hir::itemlikevisit::ItemLikeVisitor;
|
||||||
|
use ty::TyCtxt;
|
||||||
|
use ty::query::Providers;
|
||||||
|
|
||||||
struct EntryContext<'a, 'tcx: 'a> {
|
struct EntryContext<'a, 'tcx: 'a> {
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
|
@ -45,36 +47,34 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_entry_point(session: &Session,
|
fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
|
||||||
hir_map: &hir_map::Map<'_>,
|
assert_eq!(cnum, LOCAL_CRATE);
|
||||||
crate_name: &str) {
|
|
||||||
let any_exe = session.crate_types.borrow().iter().any(|ty| {
|
let any_exe = tcx.sess.crate_types.borrow().iter().any(|ty| {
|
||||||
*ty == config::CrateType::Executable
|
*ty == config::CrateType::Executable
|
||||||
});
|
});
|
||||||
if !any_exe {
|
if !any_exe {
|
||||||
// No need to find a main function
|
// No need to find a main function
|
||||||
session.entry_fn.set(None);
|
return None;
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user wants no main function at all, then stop here.
|
// If the user wants no main function at all, then stop here.
|
||||||
if attr::contains_name(&hir_map.krate().attrs, "no_main") {
|
if attr::contains_name(&tcx.hir().krate().attrs, "no_main") {
|
||||||
session.entry_fn.set(None);
|
return None;
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ctxt = EntryContext {
|
let mut ctxt = EntryContext {
|
||||||
session,
|
session: tcx.sess,
|
||||||
map: hir_map,
|
map: tcx.hir(),
|
||||||
main_fn: None,
|
main_fn: None,
|
||||||
attr_main_fn: None,
|
attr_main_fn: None,
|
||||||
start_fn: None,
|
start_fn: None,
|
||||||
non_main_fns: Vec::new(),
|
non_main_fns: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
hir_map.krate().visit_all_item_likes(&mut ctxt);
|
tcx.hir().krate().visit_all_item_likes(&mut ctxt);
|
||||||
|
|
||||||
configure_main(&mut ctxt, crate_name);
|
configure_main(tcx, &ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
|
// Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
|
||||||
|
@ -135,43 +135,58 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
|
||||||
.span_label(item.span, "multiple `start` functions")
|
.span_label(item.span, "multiple `start` functions")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
EntryPointType::None => ()
|
EntryPointType::None => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_main(this: &mut EntryContext<'_, '_>, crate_name: &str) {
|
fn configure_main(
|
||||||
if let Some((node_id, span)) = this.start_fn {
|
tcx: TyCtxt<'_, '_, '_>,
|
||||||
this.session.entry_fn.set(Some((node_id, span, EntryFnType::Start)));
|
visitor: &EntryContext<'_, '_>,
|
||||||
} else if let Some((node_id, span)) = this.attr_main_fn {
|
) -> Option<(DefId, EntryFnType)> {
|
||||||
this.session.entry_fn.set(Some((node_id, span, EntryFnType::Main)));
|
if let Some((node_id, _)) = visitor.start_fn {
|
||||||
} else if let Some((node_id, span)) = this.main_fn {
|
Some((tcx.hir().local_def_id(node_id), EntryFnType::Start))
|
||||||
this.session.entry_fn.set(Some((node_id, span, EntryFnType::Main)));
|
} else if let Some((node_id, _)) = visitor.attr_main_fn {
|
||||||
|
Some((tcx.hir().local_def_id(node_id), EntryFnType::Main))
|
||||||
|
} else if let Some((node_id, _)) = visitor.main_fn {
|
||||||
|
Some((tcx.hir().local_def_id(node_id), EntryFnType::Main))
|
||||||
} else {
|
} else {
|
||||||
// No main function
|
// No main function
|
||||||
this.session.entry_fn.set(None);
|
let mut err = struct_err!(tcx.sess, E0601,
|
||||||
let mut err = struct_err!(this.session, E0601,
|
"`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
|
||||||
"`main` function not found in crate `{}`", crate_name);
|
if !visitor.non_main_fns.is_empty() {
|
||||||
if !this.non_main_fns.is_empty() {
|
|
||||||
// There were some functions named 'main' though. Try to give the user a hint.
|
// There were some functions named 'main' though. Try to give the user a hint.
|
||||||
err.note("the main function must be defined at the crate level \
|
err.note("the main function must be defined at the crate level \
|
||||||
but you have one or more functions named 'main' that are not \
|
but you have one or more functions named 'main' that are not \
|
||||||
defined at the crate level. Either move the definition or \
|
defined at the crate level. Either move the definition or \
|
||||||
attach the `#[main]` attribute to override this behavior.");
|
attach the `#[main]` attribute to override this behavior.");
|
||||||
for &(_, span) in &this.non_main_fns {
|
for &(_, span) in &visitor.non_main_fns {
|
||||||
err.span_note(span, "here is a function named 'main'");
|
err.span_note(span, "here is a function named 'main'");
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
this.session.abort_if_errors();
|
tcx.sess.abort_if_errors();
|
||||||
} else {
|
} else {
|
||||||
if let Some(ref filename) = this.session.local_crate_source_file {
|
if let Some(ref filename) = tcx.sess.local_crate_source_file {
|
||||||
err.note(&format!("consider adding a `main` function to `{}`", filename.display()));
|
err.note(&format!("consider adding a `main` function to `{}`", filename.display()));
|
||||||
}
|
}
|
||||||
if this.session.teach(&err.get_code().unwrap()) {
|
if tcx.sess.teach(&err.get_code().unwrap()) {
|
||||||
err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
|
err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
|
||||||
to get started: https://doc.rust-lang.org/book/");
|
to get started: https://doc.rust-lang.org/book/");
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_entry_point(tcx: TyCtxt<'_, '_, '_>) -> Option<(DefId, EntryFnType)> {
|
||||||
|
tcx.entry_fn(LOCAL_CRATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn provide(providers: &mut Providers<'_>) {
|
||||||
|
*providers = Providers {
|
||||||
|
entry_fn,
|
||||||
|
..*providers
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -649,15 +649,15 @@ impl Options {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The type of entry function, so
|
// The type of entry function, so users can have their own entry functions
|
||||||
// users can have their own entry
|
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
|
||||||
// functions
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
pub enum EntryFnType {
|
pub enum EntryFnType {
|
||||||
Main,
|
Main,
|
||||||
Start,
|
Start,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_stable_hash_via_hash!(EntryFnType);
|
||||||
|
|
||||||
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
|
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
|
||||||
pub enum CrateType {
|
pub enum CrateType {
|
||||||
Executable,
|
Executable,
|
||||||
|
|
|
@ -67,8 +67,6 @@ pub struct Session {
|
||||||
/// This is `None` if the host and target are the same.
|
/// This is `None` if the host and target are the same.
|
||||||
pub target_tlib_path: Option<SearchPath>,
|
pub target_tlib_path: Option<SearchPath>,
|
||||||
pub parse_sess: ParseSess,
|
pub parse_sess: ParseSess,
|
||||||
/// For a library crate, this is always none
|
|
||||||
pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
|
|
||||||
pub sysroot: PathBuf,
|
pub sysroot: PathBuf,
|
||||||
/// The name of the root source file of the crate, in the local file system.
|
/// The name of the root source file of the crate, in the local file system.
|
||||||
/// `None` means that there is no source file.
|
/// `None` means that there is no source file.
|
||||||
|
@ -1173,8 +1171,6 @@ pub fn build_session_(
|
||||||
host_tlib_path,
|
host_tlib_path,
|
||||||
target_tlib_path,
|
target_tlib_path,
|
||||||
parse_sess: p_s,
|
parse_sess: p_s,
|
||||||
// For a library crate, this is always none
|
|
||||||
entry_fn: Once::new(),
|
|
||||||
sysroot,
|
sysroot,
|
||||||
local_crate_source_file,
|
local_crate_source_file,
|
||||||
working_dir,
|
working_dir,
|
||||||
|
|
|
@ -629,6 +629,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> QueryDescription<'tcx> for queries::entry_fn<'tcx> {
|
||||||
|
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
|
||||||
|
"looking up the entry function of a crate".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
|
impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
|
||||||
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
|
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
|
||||||
"looking up the plugin registrar for a crate".into()
|
"looking up the plugin registrar for a crate".into()
|
||||||
|
|
|
@ -22,7 +22,7 @@ use mir::mono::CodegenUnit;
|
||||||
use mir;
|
use mir;
|
||||||
use mir::interpret::GlobalId;
|
use mir::interpret::GlobalId;
|
||||||
use session::{CompileResult, CrateDisambiguator};
|
use session::{CompileResult, CrateDisambiguator};
|
||||||
use session::config::OutputFilenames;
|
use session::config::{EntryFnType, OutputFilenames};
|
||||||
use traits::{self, Vtable};
|
use traits::{self, Vtable};
|
||||||
use traits::query::{
|
use traits::query::{
|
||||||
CanonicalPredicateGoal, CanonicalProjectionGoal,
|
CanonicalPredicateGoal, CanonicalProjectionGoal,
|
||||||
|
@ -476,6 +476,8 @@ define_queries! { <'tcx>
|
||||||
|
|
||||||
[] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
|
[] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
|
||||||
|
|
||||||
|
// For a library crate, this is always none
|
||||||
|
[] fn entry_fn: EntryFn(CrateNum) -> Option<(DefId, EntryFnType)>,
|
||||||
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
|
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
|
||||||
[] fn proc_macro_decls_static: ProcMacroDeclsStatic(CrateNum) -> Option<DefId>,
|
[] fn proc_macro_decls_static: ProcMacroDeclsStatic(CrateNum) -> Option<DefId>,
|
||||||
[] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
|
[] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
|
||||||
|
|
|
@ -1362,6 +1362,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
|
||||||
DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
|
DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
|
||||||
DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
|
DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
|
||||||
DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
|
DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
|
||||||
|
DepKind::EntryFn => { force!(entry_fn, krate!()); }
|
||||||
DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
|
DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
|
||||||
DepKind::ProcMacroDeclsStatic => { force!(proc_macro_decls_static, krate!()); }
|
DepKind::ProcMacroDeclsStatic => { force!(proc_macro_decls_static, krate!()); }
|
||||||
DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
|
DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
|
||||||
|
|
|
@ -14,7 +14,7 @@ use llvm;
|
||||||
use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags,
|
use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags,
|
||||||
DILexicalBlock};
|
DILexicalBlock};
|
||||||
use rustc::hir::CodegenFnAttrFlags;
|
use rustc::hir::CodegenFnAttrFlags;
|
||||||
use rustc::hir::def_id::{DefId, CrateNum};
|
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
||||||
use rustc::ty::subst::{Substs, UnpackedKind};
|
use rustc::ty::subst::{Substs, UnpackedKind};
|
||||||
|
|
||||||
use abi::Abi;
|
use abi::Abi;
|
||||||
|
@ -290,9 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
|
|
||||||
let mut flags = DIFlags::FlagPrototyped;
|
let mut flags = DIFlags::FlagPrototyped;
|
||||||
|
|
||||||
let local_id = self.tcx().hir().as_local_node_id(def_id);
|
if let Some((id, _)) = self.tcx.entry_fn(LOCAL_CRATE) {
|
||||||
if let Some((id, _, _)) = *self.sess().entry_fn.borrow() {
|
if id == def_id {
|
||||||
if local_id == Some(id) {
|
|
||||||
flags |= DIFlags::FlagMainSubprogram;
|
flags |= DIFlags::FlagMainSubprogram;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if tcx.sess.entry_fn.borrow().is_some() {
|
if tcx.entry_fn(LOCAL_CRATE).is_some() {
|
||||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("main"));
|
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("main"));
|
||||||
|
|
||||||
symbols.push((exported_symbol, SymbolExportLevel::C));
|
symbols.push((exported_symbol, SymbolExportLevel::C));
|
||||||
|
|
|
@ -441,10 +441,8 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
cx: &'a Bx::CodegenCx
|
cx: &'a Bx::CodegenCx
|
||||||
) {
|
) {
|
||||||
let (main_def_id, span) = match *cx.sess().entry_fn.borrow() {
|
let (main_def_id, span) = match cx.tcx().entry_fn(LOCAL_CRATE) {
|
||||||
Some((id, span, _)) => {
|
Some((def_id, _)) => { (def_id, cx.tcx().def_span(def_id)) },
|
||||||
(cx.tcx().hir().local_def_id(id), span)
|
|
||||||
}
|
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -458,7 +456,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
|
|
||||||
let main_llfn = cx.get_fn(instance);
|
let main_llfn = cx.get_fn(instance);
|
||||||
|
|
||||||
let et = cx.sess().entry_fn.get().map(|e| e.2);
|
let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
|
||||||
match et {
|
match et {
|
||||||
Some(EntryFnType::Main) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, true),
|
Some(EntryFnType::Main) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, true),
|
||||||
Some(EntryFnType::Start) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, false),
|
Some(EntryFnType::Start) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, false),
|
||||||
|
|
|
@ -31,6 +31,7 @@ extern crate syntax_pos;
|
||||||
#[macro_use] extern crate rustc_data_structures;
|
#[macro_use] extern crate rustc_data_structures;
|
||||||
|
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
|
|
||||||
pub mod link;
|
pub mod link;
|
||||||
pub mod codegen_backend;
|
pub mod codegen_backend;
|
||||||
|
@ -42,11 +43,9 @@ pub mod symbol_names_test;
|
||||||
/// that actually test that compilation succeeds without
|
/// that actually test that compilation succeeds without
|
||||||
/// reporting an error.
|
/// reporting an error.
|
||||||
pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
|
pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
|
||||||
if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
|
if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
|
||||||
let main_def_id = tcx.hir().local_def_id(id);
|
if tcx.has_attr(def_id, "rustc_error") {
|
||||||
|
tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
|
||||||
if tcx.has_attr(main_def_id, "rustc_error") {
|
|
||||||
tcx.sess.span_fatal(span, "compilation successful");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1174,6 +1174,7 @@ pub fn default_provide(providers: &mut ty::query::Providers) {
|
||||||
rustc_passes::provide(providers);
|
rustc_passes::provide(providers);
|
||||||
rustc_traits::provide(providers);
|
rustc_traits::provide(providers);
|
||||||
middle::region::provide(providers);
|
middle::region::provide(providers);
|
||||||
|
middle::entry::provide(providers);
|
||||||
cstore::provide(providers);
|
cstore::provide(providers);
|
||||||
lint::provide(providers);
|
lint::provide(providers);
|
||||||
}
|
}
|
||||||
|
@ -1210,10 +1211,6 @@ where
|
||||||
rustc_incremental::load_query_result_cache(sess)
|
rustc_incremental::load_query_result_cache(sess)
|
||||||
});
|
});
|
||||||
|
|
||||||
time(sess, "looking for entry point", || {
|
|
||||||
middle::entry::find_entry_point(sess, &hir_map, name)
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut local_providers = ty::query::Providers::default();
|
let mut local_providers = ty::query::Providers::default();
|
||||||
default_provide(&mut local_providers);
|
default_provide(&mut local_providers);
|
||||||
codegen_backend.provide(&mut local_providers);
|
codegen_backend.provide(&mut local_providers);
|
||||||
|
@ -1243,6 +1240,10 @@ where
|
||||||
// tcx available.
|
// tcx available.
|
||||||
time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
|
time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
|
||||||
|
|
||||||
|
time(sess, "looking for entry point", || {
|
||||||
|
middle::entry::find_entry_point(tcx)
|
||||||
|
});
|
||||||
|
|
||||||
time(sess, "looking for plugin registrar", || {
|
time(sess, "looking for plugin registrar", || {
|
||||||
plugin::build::find_plugin_registrar(tcx)
|
plugin::build::find_plugin_registrar(tcx)
|
||||||
});
|
});
|
||||||
|
|
|
@ -177,13 +177,13 @@
|
||||||
use rustc::hir::{self, CodegenFnAttrFlags};
|
use rustc::hir::{self, CodegenFnAttrFlags};
|
||||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::mir::interpret::{AllocId, ConstValue};
|
use rustc::mir::interpret::{AllocId, ConstValue};
|
||||||
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
|
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
|
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
|
||||||
use rustc::ty::adjustment::CustomCoerceUnsized;
|
use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||||
use rustc::session::config;
|
use rustc::session::config::EntryFnType;
|
||||||
use rustc::mir::{self, Location, Promoted};
|
use rustc::mir::{self, Location, Promoted};
|
||||||
use rustc::mir::visit::Visitor as MirVisitor;
|
use rustc::mir::visit::Visitor as MirVisitor;
|
||||||
use rustc::mir::mono::MonoItem;
|
use rustc::mir::mono::MonoItem;
|
||||||
|
@ -321,9 +321,7 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let mut roots = Vec::new();
|
let mut roots = Vec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _, _)| {
|
let entry_fn = tcx.entry_fn(LOCAL_CRATE);
|
||||||
tcx.hir().local_def_id(node_id)
|
|
||||||
});
|
|
||||||
|
|
||||||
debug!("collect_roots: entry_fn = {:?}", entry_fn);
|
debug!("collect_roots: entry_fn = {:?}", entry_fn);
|
||||||
|
|
||||||
|
@ -924,7 +922,7 @@ struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
mode: MonoItemCollectionMode,
|
mode: MonoItemCollectionMode,
|
||||||
output: &'b mut Vec<MonoItem<'tcx>>,
|
output: &'b mut Vec<MonoItem<'tcx>>,
|
||||||
entry_fn: Option<DefId>,
|
entry_fn: Option<(DefId, EntryFnType)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
||||||
|
@ -1023,7 +1021,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
MonoItemCollectionMode::Lazy => {
|
MonoItemCollectionMode::Lazy => {
|
||||||
self.entry_fn == Some(def_id) ||
|
self.entry_fn.map(|(id, _)| id) == Some(def_id) ||
|
||||||
self.tcx.is_reachable_non_generic(def_id) ||
|
self.tcx.is_reachable_non_generic(def_id) ||
|
||||||
self.tcx.codegen_fn_attrs(def_id).flags.contains(
|
self.tcx.codegen_fn_attrs(def_id).flags.contains(
|
||||||
CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
||||||
|
@ -1048,14 +1046,9 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
|
||||||
/// the return type of `main`. This is not needed when
|
/// the return type of `main`. This is not needed when
|
||||||
/// the user writes their own `start` manually.
|
/// the user writes their own `start` manually.
|
||||||
fn push_extra_entry_roots(&mut self) {
|
fn push_extra_entry_roots(&mut self) {
|
||||||
if self.tcx.sess.entry_fn.get().map(|e| e.2) != Some(config::EntryFnType::Main) {
|
let main_def_id = match self.entry_fn {
|
||||||
return
|
Some((def_id, EntryFnType::Main)) => def_id,
|
||||||
}
|
_ => return,
|
||||||
|
|
||||||
let main_def_id = if let Some(def_id) = self.entry_fn {
|
|
||||||
def_id
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let start_def_id = match self.tcx.lang_items().require(StartFnLangItem) {
|
let start_def_id = match self.tcx.lang_items().require(StartFnLangItem) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::session::config::OptLevel;
|
use rustc::session::config::OptLevel;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
|
use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
|
@ -75,8 +75,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
|
||||||
|
|
||||||
match *self.as_mono_item() {
|
match *self.as_mono_item() {
|
||||||
MonoItem::Fn(ref instance) => {
|
MonoItem::Fn(ref instance) => {
|
||||||
let entry_def_id =
|
let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(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
|
// If this function isn't inlined or otherwise has explicit
|
||||||
// linkage, then we'll be creating a globally shared version.
|
// linkage, then we'll be creating a globally shared version.
|
||||||
if self.explicit_linkage(tcx).is_some() ||
|
if self.explicit_linkage(tcx).is_some() ||
|
||||||
|
|
|
@ -132,7 +132,8 @@ use std::ops::{self, Deref};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
use require_c_abi_if_variadic;
|
use require_c_abi_if_variadic;
|
||||||
use session::{CompileIncomplete, config, Session};
|
use session::{CompileIncomplete, Session};
|
||||||
|
use session::config::EntryFnType;
|
||||||
use TypeAndSubsts;
|
use TypeAndSubsts;
|
||||||
use lint;
|
use lint;
|
||||||
use util::captures::Captures;
|
use util::captures::Captures;
|
||||||
|
@ -1163,19 +1164,18 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
// Check that the main return type implements the termination trait.
|
// Check that the main return type implements the termination trait.
|
||||||
if let Some(term_id) = fcx.tcx.lang_items().termination() {
|
if let Some(term_id) = fcx.tcx.lang_items().termination() {
|
||||||
if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
|
if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
|
||||||
if id == fn_id {
|
let main_id = fcx.tcx.hir().as_local_node_id(def_id).unwrap();
|
||||||
if let config::EntryFnType::Main = entry_type {
|
if main_id == fn_id {
|
||||||
let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
|
let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
|
||||||
let trait_ref = ty::TraitRef::new(term_id, substs);
|
let trait_ref = ty::TraitRef::new(term_id, substs);
|
||||||
let return_ty_span = decl.output.span();
|
let return_ty_span = decl.output.span();
|
||||||
let cause = traits::ObligationCause::new(
|
let cause = traits::ObligationCause::new(
|
||||||
return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
|
return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
|
||||||
|
|
||||||
inherited.register_predicate(
|
inherited.register_predicate(
|
||||||
traits::Obligation::new(
|
traits::Obligation::new(
|
||||||
cause, param_env, trait_ref.to_predicate()));
|
cause, param_env, trait_ref.to_predicate()));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,23 +104,22 @@ mod namespace;
|
||||||
mod outlives;
|
mod outlives;
|
||||||
mod variance;
|
mod variance;
|
||||||
|
|
||||||
use hir::Node;
|
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc::hir;
|
use rustc::hir::{self, Node};
|
||||||
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::infer::InferOk;
|
use rustc::infer::InferOk;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::middle;
|
use rustc::middle;
|
||||||
use rustc::session;
|
use rustc::session;
|
||||||
use rustc::session::config::nightly_options;
|
use rustc::session::CompileIncomplete;
|
||||||
|
use rustc::session::config::{EntryFnType, nightly_options};
|
||||||
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
|
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc::util;
|
use rustc::util;
|
||||||
use rustc::util::profiling::ProfileCategory;
|
use rustc::util::profiling::ProfileCategory;
|
||||||
use session::{CompileIncomplete, config};
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::ast;
|
|
||||||
use util::common::time;
|
use util::common::time;
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -185,10 +184,9 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, main_def_id: DefId) {
|
||||||
main_id: ast::NodeId,
|
let main_id = tcx.hir().as_local_node_id(main_def_id).unwrap();
|
||||||
main_span: Span) {
|
let main_span = tcx.def_span(main_def_id);
|
||||||
let main_def_id = tcx.hir().local_def_id(main_id);
|
|
||||||
let main_t = tcx.type_of(main_def_id);
|
let main_t = tcx.type_of(main_def_id);
|
||||||
match main_t.sty {
|
match main_t.sty {
|
||||||
ty::FnDef(..) => {
|
ty::FnDef(..) => {
|
||||||
|
@ -251,10 +249,9 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, start_def_id: DefId) {
|
||||||
start_id: ast::NodeId,
|
let start_id = tcx.hir().as_local_node_id(start_def_id).unwrap();
|
||||||
start_span: Span) {
|
let start_span = tcx.def_span(start_def_id);
|
||||||
let start_def_id = tcx.hir().local_def_id(start_id);
|
|
||||||
let start_t = tcx.type_of(start_def_id);
|
let start_t = tcx.type_of(start_def_id);
|
||||||
match start_t.sty {
|
match start_t.sty {
|
||||||
ty::FnDef(..) => {
|
ty::FnDef(..) => {
|
||||||
|
@ -310,11 +307,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>) {
|
fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||||
if let Some((id, sp, entry_type)) = *tcx.sess.entry_fn.borrow() {
|
match tcx.entry_fn(LOCAL_CRATE) {
|
||||||
match entry_type {
|
Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id),
|
||||||
config::EntryFnType::Main => check_main_fn_ty(tcx, id, sp),
|
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
|
||||||
config::EntryFnType::Start => check_start_fn_ty(tcx, id, sp),
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue