Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions compiler/rustc_resolve/src/check_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
//
// Checking for unused imports is split into three steps:
//
// - `UnusedImportCheckVisitor` walks the AST to find all the unused imports
// inside of `UseTree`s, recording their `NodeId`s and grouping them by
// the parent `use` item
// - `UnusedImportCheckVisitor` visits the `use` items collected during late
// resolution to find all the unused imports inside of `UseTree`s, recording
// their `NodeId`s and grouping them by the parent `use` item
//
// - `calc_unused_spans` then walks over all the `use` items marked in the
// previous step to collect the spans associated with the `NodeId`s and to
Expand Down Expand Up @@ -410,7 +410,7 @@ fn calc_unused_spans(
}

impl Resolver<'_, '_> {
pub(crate) fn check_unused(&mut self, krate: &ast::Crate) {
pub(crate) fn check_unused(&mut self, use_items: Vec<&ast::Item>) {
let tcx = self.tcx;
let mut maybe_unused_extern_crates = FxHashMap::default();

Expand Down Expand Up @@ -465,7 +465,10 @@ impl Resolver<'_, '_> {
base_id: ast::DUMMY_NODE_ID,
item_span: DUMMY_SP,
};
visit::walk_crate(&mut visitor, krate);
// `use_items` is in crate DFS order, so diagnostics and side effects are unchanged.
for item in use_items {
visitor.visit_item(item);
}

visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);

Expand Down
25 changes: 17 additions & 8 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5587,12 +5587,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
}

/// Walks the whole crate in DFS order, visiting each item, counting the declared number of
/// lifetime generic parameters and function parameters.
struct ItemInfoCollector<'a, 'ra, 'tcx> {
/// lifetime generic parameters and function parameters. Also collects all `use` and
/// `extern crate` items so that `check_unused` doesn't need to walk the crate again.
struct ItemInfoCollector<'a, 'ast, 'ra, 'tcx> {
r: &'a mut Resolver<'ra, 'tcx>,
/// All `use` and `extern crate` items, in the order in which they are visited.
use_items: Vec<&'ast Item>,
}

impl ItemInfoCollector<'_, '_, '_> {
impl ItemInfoCollector<'_, '_, '_, '_> {
fn collect_fn_info(&mut self, decl: &FnDecl, id: NodeId) {
self.r
.delegation_fn_sigs
Expand Down Expand Up @@ -5626,7 +5629,7 @@ fn required_generic_args_suggestion(generics: &ast::Generics) -> Option<String>
if required.is_empty() { None } else { Some(format!("<{}>", required.join(", "))) }
}

impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, 'ast, '_, '_> {
fn visit_item(&mut self, item: &'ast Item) {
match &item.kind {
ItemKind::TyAlias(TyAlias { generics, .. })
Expand Down Expand Up @@ -5659,11 +5662,13 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
}
}

ItemKind::Use(..) | ItemKind::ExternCrate(..) => {
self.use_items.push(item);
}

ItemKind::Mod(..)
| ItemKind::Static(..)
| ItemKind::ConstBlock(..)
| ItemKind::Use(..)
| ItemKind::ExternCrate(..)
| ItemKind::MacroDef(..)
| ItemKind::GlobalAsm(..)
| ItemKind::MacCall(..)
Expand Down Expand Up @@ -5694,9 +5699,12 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
}

impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
/// Returns the `use` and `extern crate` items of the crate, for use by `check_unused`.
pub(crate) fn late_resolve_crate<'ast>(&mut self, krate: &'ast Crate) -> Vec<&'ast Item> {
with_owner(self, CRATE_NODE_ID, |this| {
visit::walk_crate(&mut ItemInfoCollector { r: this }, krate);
let mut info_collector = ItemInfoCollector { r: this, use_items: Vec::new() };
visit::walk_crate(&mut info_collector, krate);
let use_items = info_collector.use_items;
let mut late_resolution_visitor = LateResolutionVisitor::new(this);
late_resolution_visitor
.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
Expand All @@ -5709,6 +5717,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
crate::diagnostics::UnusedLabel,
);
}
use_items
})
}
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2082,9 +2082,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.tcx
.sess
.time("finalize_macro_resolutions", || self.finalize_macro_resolutions(krate));
self.tcx.sess.time("late_resolve_crate", || self.late_resolve_crate(krate));
let use_items =
self.tcx.sess.time("late_resolve_crate", || self.late_resolve_crate(krate));
self.tcx.sess.time("resolve_main", || self.resolve_main());
self.tcx.sess.time("resolve_check_unused", || self.check_unused(krate));
self.tcx.sess.time("resolve_check_unused", || self.check_unused(use_items));
self.tcx.sess.time("resolve_report_errors", || self.report_errors(krate));
self.tcx
.sess
Expand Down
Loading