Skip to content

Commit 3d891e7

Browse files
committed
Initial work for RFC 1260
1 parent c80c31a commit 3d891e7

File tree

7 files changed

+52
-9
lines changed

7 files changed

+52
-9
lines changed

src/librustc/middle/entry.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
use dep_graph::DepNode;
1313
use hir::map as ast_map;
14-
use hir::def_id::{CRATE_DEF_INDEX};
14+
use hir::def_id::{CRATE_DEF_INDEX, DefId};
1515
use session::{config, Session};
1616
use syntax::ast::NodeId;
1717
use syntax::attr;
@@ -36,7 +36,14 @@ struct EntryContext<'a, 'tcx: 'a> {
3636

3737
// The functions that one might think are 'main' but aren't, e.g.
3838
// main functions not defined at the top level. For diagnostics.
39-
non_main_fns: Vec<(NodeId, Span)> ,
39+
non_main_fns: Vec<(NodeId, Span)>,
40+
41+
// Function item that imported to root namespace named 'main'.
42+
// It was collected in resolve phase
43+
defined_as_main: Option<DefId>,
44+
45+
// The function that imported to root namespace named 'main'.
46+
imported_main_fn: Option<(NodeId, Span)>,
4047
}
4148

4249
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
@@ -53,7 +60,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
5360
}
5461
}
5562

56-
pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
63+
pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map, defined_as_main: Option<DefId>) {
5764
let _task = ast_map.dep_graph.in_task(DepNode::EntryPoint);
5865

5966
let any_exe = session.crate_types.borrow().iter().any(|ty| {
@@ -77,6 +84,8 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
7784
attr_main_fn: None,
7885
start_fn: None,
7986
non_main_fns: Vec::new(),
87+
defined_as_main: defined_as_main,
88+
imported_main_fn: None,
8089
};
8190

8291
ast_map.krate().visit_all_item_likes(&mut ctxt);
@@ -86,13 +95,15 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
8695

8796
// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
8897
// them in sync.
89-
fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
98+
fn entry_point_type<F: Fn() -> bool>(item: &Item, at_root: bool, defined_as_main: F) -> EntryPointType {
9099
match item.node {
91100
ItemFn(..) => {
92101
if attr::contains_name(&item.attrs, "start") {
93102
EntryPointType::Start
94103
} else if attr::contains_name(&item.attrs, "main") {
95104
EntryPointType::MainAttr
105+
} else if defined_as_main() {
106+
EntryPointType::ImportedMain
96107
} else if item.name == "main" {
97108
if at_root {
98109
// This is a top-level function so can be 'main'
@@ -110,7 +121,9 @@ fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
110121

111122

112123
fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
113-
match entry_point_type(item, at_root) {
124+
match entry_point_type(item,
125+
at_root,
126+
|| ctxt.defined_as_main == Some(ctxt.map.local_def_id(item.id))) {
114127
EntryPointType::MainNamed => {
115128
if ctxt.main_fn.is_none() {
116129
ctxt.main_fn = Some((item.id, item.span));
@@ -146,6 +159,9 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
146159
.emit();
147160
}
148161
},
162+
EntryPointType::ImportedMain => {
163+
ctxt.imported_main_fn = Some((item.id, item.span));
164+
},
149165
EntryPointType::None => ()
150166
}
151167
}
@@ -160,6 +176,9 @@ fn configure_main(this: &mut EntryContext) {
160176
} else if this.main_fn.is_some() {
161177
*this.session.entry_fn.borrow_mut() = this.main_fn;
162178
this.session.entry_type.set(Some(config::EntryMain));
179+
} else if this.imported_main_fn.is_some() {
180+
*this.session.entry_fn.borrow_mut() = this.imported_main_fn;
181+
this.session.entry_type.set(Some(config::EntryMain));
163182
} else {
164183
// No main function
165184
let mut err = this.session.struct_err("main function not found");

src/librustc_driver/driver.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use rustc::hir;
1212
use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
1313
use rustc::hir::lowering::lower_crate;
14+
use rustc::hir::def_id::DefId;
1415
use rustc_data_structures::blake2b::Blake2bHasher;
1516
use rustc_data_structures::fmt_wrap::FmtWrap;
1617
use rustc::ty::util::ArchIndependentHasher;
@@ -117,7 +118,12 @@ pub fn compile_input(sess: &Session,
117118

118119
let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
119120
let crate_name = link::find_crate_name(Some(sess), &krate.attrs, input);
120-
let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
121+
let ExpansionResult { expanded_crate,
122+
defs,
123+
analysis,
124+
resolutions,
125+
defined_as_main,
126+
mut hir_forest } = {
121127
phase_2_configure_and_expand(
122128
sess, &cstore, krate, registry, &crate_name, addl_plugins, control.make_glob_map,
123129
|expanded_crate| {
@@ -175,6 +181,7 @@ pub fn compile_input(sess: &Session,
175181
resolutions,
176182
&arenas,
177183
&crate_name,
184+
defined_as_main,
178185
|tcx, analysis, incremental_hashes_map, result| {
179186
{
180187
// Eventually, we will want to track plugins.
@@ -536,6 +543,7 @@ pub struct ExpansionResult {
536543
pub analysis: ty::CrateAnalysis<'static>,
537544
pub resolutions: Resolutions,
538545
pub hir_forest: hir_map::Forest,
546+
pub defined_as_main: Option<DefId>,
539547
}
540548

541549
/// Run the "early phases" of the compiler: initial `cfg` processing,
@@ -791,6 +799,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
791799
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
792800
hir_ty_to_ty: NodeMap(),
793801
},
802+
defined_as_main: resolver.defined_as_main,
794803
resolutions: Resolutions {
795804
freevars: resolver.freevars,
796805
trait_map: resolver.trait_map,
@@ -809,6 +818,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
809818
resolutions: Resolutions,
810819
arenas: &'tcx ty::CtxtArenas<'tcx>,
811820
name: &str,
821+
defined_as_main: Option<DefId>,
812822
f: F)
813823
-> Result<R, usize>
814824
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
@@ -842,7 +852,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
842852

843853
time(time_passes,
844854
"looking for entry point",
845-
|| middle::entry::find_entry_point(sess, &hir_map));
855+
|| middle::entry::find_entry_point(sess, &hir_map, defined_as_main));
846856

847857
sess.plugin_registrar_fn.set(time(time_passes, "looking for plugin registrar", || {
848858
plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map)

src/librustc_driver/pretty.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ impl PpSourceMode {
232232
resolutions.clone(),
233233
arenas,
234234
id,
235+
None,
235236
|tcx, _, _, _| {
236237
let annotation = TypedAnnotation { tcx: tcx };
237238
let _ignore = tcx.dep_graph.in_ignore();
@@ -960,6 +961,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
960961
resolutions.clone(),
961962
arenas,
962963
crate_name,
964+
None,
963965
|tcx, _, _, _| {
964966
match ppm {
965967
PpmMir | PpmMirCFG => {

src/librustc_resolve/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,9 @@ pub struct Resolver<'a> {
11021102

11031103
// Avoid duplicated errors for "name already defined".
11041104
name_already_seen: FxHashMap<Name, Span>,
1105+
1106+
// Track function imported as main in root namespace
1107+
pub defined_as_main: Option<DefId>,
11051108
}
11061109

11071110
pub struct ResolverArenas<'a> {
@@ -1277,6 +1280,7 @@ impl<'a> Resolver<'a> {
12771280
macro_exports: Vec::new(),
12781281
invocations: invocations,
12791282
name_already_seen: FxHashMap(),
1283+
defined_as_main: None,
12801284
}
12811285
}
12821286

src/librustc_resolve/resolve_imports.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use self::ImportDirectiveSubclass::*;
1212

1313
use {Module, PerNS};
14-
use Namespace::{self, TypeNS, MacroNS};
14+
use Namespace::{self, TypeNS, MacroNS, ValueNS};
1515
use {NameBinding, NameBindingKind, PathResult, PathScope, PrivacyError, ToNameBinding};
1616
use Resolver;
1717
use {names_to_string, module_to_string};
@@ -293,6 +293,11 @@ impl<'a> Resolver<'a> {
293293
where T: ToNameBinding<'a>
294294
{
295295
let binding = self.arenas.alloc_name_binding(binding.to_name_binding());
296+
if ns == ValueNS && module.parent.is_none() && name == Name::intern("main") {
297+
if let Def::Fn(def_id) = binding.def() {
298+
self.defined_as_main = Some(def_id);
299+
}
300+
}
296301
self.update_resolution(module, name, ns, |this, resolution| {
297302
if let Some(old_binding) = resolution.binding {
298303
if binding.is_glob_import() {

src/libsyntax/entry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ pub enum EntryPointType {
1717
MainAttr,
1818
Start,
1919
OtherMain, // Not an entry point, but some other function named main
20+
ImportedMain, // function imported as "main" in root namespace
2021
}
2122

2223
// Beware, this is duplicated in librustc/middle/entry.rs, make sure to keep
2324
// them in sync.
25+
// FIXME: get it sync or find other way to keep sane in --test mode
2426
pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
2527
match item.node {
2628
ItemKind::Fn(..) => {

src/libsyntax/test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ impl fold::Folder for EntryPointCleaner {
186186
// Remove any #[main] or #[start] from the AST so it doesn't
187187
// clash with the one we're going to add, but mark it as
188188
// #[allow(dead_code)] to avoid printing warnings.
189-
let folded = match entry::entry_point_type(&folded, self.depth) {
189+
let folded = match entry::entry_point_type(&folded, self.depth) {
190+
EntryPointType::ImportedMain => unimplemented!(), // FIXME
190191
EntryPointType::MainNamed |
191192
EntryPointType::MainAttr |
192193
EntryPointType::Start =>

0 commit comments

Comments
 (0)