about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_passes/src/entry.rs65
-rw-r--r--src/test/ui/error-codes/E0138.stderr4
-rw-r--r--src/test/ui/main-wrong-location.stderr2
3 files changed, 42 insertions, 29 deletions
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 7c543c48824..b494a0fe2ed 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,7 +1,8 @@
 use rustc_ast::entry::EntryPointType;
 use rustc_errors::struct_span_err;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
-use rustc_hir::{Item, ItemKind, Node, CRATE_HIR_ID};
+use rustc_hir::{ItemId, Node, CRATE_HIR_ID};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{DefIdTree, TyCtxt};
 use rustc_session::config::{CrateType, EntryFnType};
@@ -40,8 +41,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
         EntryContext { tcx, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
 
     for id in tcx.hir().items() {
-        let item = tcx.hir().item(id);
-        find_item(item, &mut ctxt);
+        find_item(id, &mut ctxt);
     }
 
     configure_main(tcx, &ctxt)
@@ -49,21 +49,26 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
 
 // Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
 // (with `ast::Item`), so make sure to keep them in sync.
-fn entry_point_type(ctxt: &EntryContext<'_>, item: &Item<'_>, at_root: bool) -> EntryPointType {
-    let attrs = ctxt.tcx.hir().attrs(item.hir_id());
+// A small optimization was added so that hir::Item is fetched only when needed.
+// An equivalent optimization was not applied to the duplicated code in test_harness.rs.
+fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> EntryPointType {
+    let attrs = ctxt.tcx.hir().attrs(id.hir_id());
     if ctxt.tcx.sess.contains_name(attrs, sym::start) {
         EntryPointType::Start
     } else if ctxt.tcx.sess.contains_name(attrs, sym::rustc_main) {
         EntryPointType::MainAttr
-    } else if item.ident.name == sym::main {
-        if at_root {
-            // This is a top-level function so can be `main`.
-            EntryPointType::MainNamed
+    } else {
+        let item = ctxt.tcx.hir().item(id);
+        if item.ident.name == sym::main {
+            if at_root {
+                // This is a top-level function so can be `main`.
+                EntryPointType::MainNamed
+            } else {
+                EntryPointType::OtherMain
+            }
         } else {
-            EntryPointType::OtherMain
+            EntryPointType::None
         }
-    } else {
-        EntryPointType::None
     }
 }
 
@@ -72,13 +77,13 @@ fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
         .emit();
 }
 
-fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_>) {
-    let at_root = ctxt.tcx.opt_local_parent(item.def_id) == Some(CRATE_DEF_ID);
+fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
+    let at_root = ctxt.tcx.opt_local_parent(id.def_id) == Some(CRATE_DEF_ID);
 
-    match entry_point_type(ctxt, item, at_root) {
+    match entry_point_type(ctxt, id, at_root) {
         EntryPointType::None => (),
-        _ if !matches!(item.kind, ItemKind::Fn(..)) => {
-            let attrs = ctxt.tcx.hir().attrs(item.hir_id());
+        _ if !matches!(ctxt.tcx.hir().def_kind(id.def_id), DefKind::Fn) => {
+            let attrs = ctxt.tcx.hir().attrs(id.hir_id());
             if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::start) {
                 throw_attr_err(&ctxt.tcx.sess, attr.span, "start");
             }
@@ -88,31 +93,39 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_>) {
         }
         EntryPointType::MainNamed => (),
         EntryPointType::OtherMain => {
-            ctxt.non_main_fns.push(item.span);
+            ctxt.non_main_fns.push(ctxt.tcx.def_span(id.def_id.to_def_id()));
         }
         EntryPointType::MainAttr => {
             if ctxt.attr_main_fn.is_none() {
-                ctxt.attr_main_fn = Some((item.def_id, item.span));
+                ctxt.attr_main_fn = Some((id.def_id, ctxt.tcx.def_span(id.def_id.to_def_id())));
             } else {
                 struct_span_err!(
                     ctxt.tcx.sess,
-                    item.span,
+                    ctxt.tcx.def_span(id.def_id.to_def_id()),
                     E0137,
                     "multiple functions with a `#[main]` attribute"
                 )
-                .span_label(item.span, "additional `#[main]` function")
+                .span_label(
+                    ctxt.tcx.def_span(id.def_id.to_def_id()),
+                    "additional `#[main]` function",
+                )
                 .span_label(ctxt.attr_main_fn.unwrap().1, "first `#[main]` function")
                 .emit();
             }
         }
         EntryPointType::Start => {
             if ctxt.start_fn.is_none() {
-                ctxt.start_fn = Some((item.def_id, item.span));
+                ctxt.start_fn = Some((id.def_id, ctxt.tcx.def_span(id.def_id.to_def_id())));
             } else {
-                struct_span_err!(ctxt.tcx.sess, item.span, E0138, "multiple `start` functions")
-                    .span_label(ctxt.start_fn.unwrap().1, "previous `#[start]` function here")
-                    .span_label(item.span, "multiple `start` functions")
-                    .emit();
+                struct_span_err!(
+                    ctxt.tcx.sess,
+                    ctxt.tcx.def_span(id.def_id.to_def_id()),
+                    E0138,
+                    "multiple `start` functions"
+                )
+                .span_label(ctxt.start_fn.unwrap().1, "previous `#[start]` function here")
+                .span_label(ctxt.tcx.def_span(id.def_id.to_def_id()), "multiple `start` functions")
+                .emit();
             }
         }
     }
diff --git a/src/test/ui/error-codes/E0138.stderr b/src/test/ui/error-codes/E0138.stderr
index 2dc6976fe0e..fa8c3942732 100644
--- a/src/test/ui/error-codes/E0138.stderr
+++ b/src/test/ui/error-codes/E0138.stderr
@@ -2,10 +2,10 @@ error[E0138]: multiple `start` functions
   --> $DIR/E0138.rs:7:1
    |
 LL | fn foo(argc: isize, argv: *const *const u8) -> isize { 0 }
-   | ---------------------------------------------------------- previous `#[start]` function here
+   | ---------------------------------------------------- previous `#[start]` function here
 ...
 LL | fn f(argc: isize, argv: *const *const u8) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ multiple `start` functions
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ multiple `start` functions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/main-wrong-location.stderr b/src/test/ui/main-wrong-location.stderr
index 0058af9b79e..3d64b0a67a1 100644
--- a/src/test/ui/main-wrong-location.stderr
+++ b/src/test/ui/main-wrong-location.stderr
@@ -8,7 +8,7 @@ note: here is a function named `main`
   --> $DIR/main-wrong-location.rs:4:5
    |
 LL |     fn main() { }
-   |     ^^^^^^^^^^^^^
+   |     ^^^^^^^^^
    = note: you have one or more functions named `main` not defined at the crate level
    = help: consider moving the `main` function definitions