use rustc_ast::entry::EntryPointType;
use rustc_errors::struct_span_err;
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{ForeignItem, ImplItem, Item, ItemKind, Node, TraitItem, CRATE_HIR_ID};
-use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{DefIdTree, TyCtxt};
use rustc_session::config::{CrateType, EntryFnType};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP};
-struct EntryContext<'a, 'tcx> {
- session: &'a Session,
-
- map: Map<'tcx>,
+struct EntryContext<'tcx> {
+ tcx: TyCtxt<'tcx>,
/// The function that has attribute named `main`.
attr_main_fn: Option<(LocalDefId, Span)>,
non_main_fns: Vec<Span>,
}
-impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
+impl<'tcx> ItemLikeVisitor<'tcx> for EntryContext<'tcx> {
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
- let def_key = self.map.def_key(item.def_id);
- let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
+ let at_root = self.tcx.local_parent(item.def_id) == Some(CRATE_DEF_ID);
find_item(item, self, at_root);
}
return None;
}
- let mut ctxt = EntryContext {
- session: tcx.sess,
- map: tcx.hir(),
- attr_main_fn: None,
- start_fn: None,
- non_main_fns: Vec::new(),
- };
+ let mut ctxt =
+ EntryContext { tcx, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
tcx.hir().visit_all_item_likes(&mut ctxt);
// 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.map.attrs(item.hir_id());
- if ctxt.session.contains_name(attrs, sym::start) {
+fn entry_point_type(ctxt: &EntryContext<'_>, item: &Item<'_>, at_root: bool) -> EntryPointType {
+ let attrs = ctxt.tcx.hir().attrs(item.hir_id());
+ if ctxt.tcx.sess.contains_name(attrs, sym::start) {
EntryPointType::Start
- } else if ctxt.session.contains_name(attrs, sym::rustc_main) {
+ } else if ctxt.tcx.sess.contains_name(attrs, sym::rustc_main) {
EntryPointType::MainAttr
} else if item.ident.name == sym::main {
if at_root {
.emit();
}
-fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
+fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_>, at_root: bool) {
match entry_point_type(ctxt, item, at_root) {
EntryPointType::None => (),
_ if !matches!(item.kind, ItemKind::Fn(..)) => {
- let attrs = ctxt.map.attrs(item.hir_id());
- if let Some(attr) = ctxt.session.find_by_name(attrs, sym::start) {
- throw_attr_err(&ctxt.session, attr.span, "start");
+ let attrs = ctxt.tcx.hir().attrs(item.hir_id());
+ if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::start) {
+ throw_attr_err(&ctxt.tcx.sess, attr.span, "start");
}
- if let Some(attr) = ctxt.session.find_by_name(attrs, sym::rustc_main) {
- throw_attr_err(&ctxt.session, attr.span, "rustc_main");
+ if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::rustc_main) {
+ throw_attr_err(&ctxt.tcx.sess, attr.span, "rustc_main");
}
}
EntryPointType::MainNamed => (),
ctxt.attr_main_fn = Some((item.def_id, item.span));
} else {
struct_span_err!(
- ctxt.session,
+ ctxt.tcx.sess,
item.span,
E0137,
"multiple functions with a `#[main]` attribute"
if ctxt.start_fn.is_none() {
ctxt.start_fn = Some((item.def_id, item.span));
} else {
- struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
+ 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();
}
}
-fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> {
+fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
if let Some((def_id, _)) = visitor.start_fn {
Some((def_id.to_def_id(), EntryFnType::Start))
} else if let Some((def_id, _)) = visitor.attr_main_fn {
}
}
-fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
+fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
let sp = tcx.def_span(CRATE_DEF_ID);
if *tcx.sess.parse_sess.reached_eof.borrow() {
// There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about