diff options
| -rw-r--r-- | compiler/rustc_passes/src/entry.rs | 65 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0138.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/main-wrong-location.stderr | 2 |
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 |
