Skip to content

Commit fa2bc4f

Browse files
committed
Directly access the module for use suggestions.
1 parent 7ec973d commit fa2bc4f

File tree

1 file changed

+34
-62
lines changed

1 file changed

+34
-62
lines changed

compiler/rustc_typeck/src/check/method/suggest.rs

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
66
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
77
use rustc_hir as hir;
88
use rustc_hir::def::{DefKind, Namespace, Res};
9-
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
10-
use rustc_hir::intravisit;
9+
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
1110
use rustc_hir::lang_items::LangItem;
1211
use rustc_hir::{ExprKind, Node, QPath};
1312
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1011,8 +1010,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10111010
candidates: Vec<DefId>,
10121011
) {
10131012
let module_did = self.tcx.parent_module(self.body_id);
1014-
let module_id = self.tcx.hir().local_def_id_to_hir_id(module_did);
1015-
let (span, found_use) = UsePlacementFinder::check(self.tcx, module_id);
1013+
let (span, found_use) = find_use_placement(self.tcx, module_did);
10161014
if let Some(span) = span {
10171015
let path_strings = candidates.iter().map(|did| {
10181016
// Produce an additional newline to separate the new use statement
@@ -1605,60 +1603,38 @@ pub fn provide(providers: &mut ty::query::Providers) {
16051603
providers.all_traits = compute_all_traits;
16061604
}
16071605

1608-
struct UsePlacementFinder<'tcx> {
1609-
target_module: hir::HirId,
1610-
span: Option<Span>,
1611-
found_use: bool,
1612-
tcx: TyCtxt<'tcx>,
1613-
}
1614-
1615-
impl UsePlacementFinder<'tcx> {
1616-
fn check(tcx: TyCtxt<'tcx>, target_module: hir::HirId) -> (Option<Span>, bool) {
1617-
let mut finder = UsePlacementFinder { target_module, span: None, found_use: false, tcx };
1618-
tcx.hir().walk_crate(&mut finder);
1619-
(finder.span, finder.found_use)
1620-
}
1621-
}
1622-
1623-
impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
1624-
fn visit_mod(&mut self, module: &'tcx hir::Mod<'tcx>, _: Span, hir_id: hir::HirId) {
1625-
if self.span.is_some() {
1626-
return;
1627-
}
1628-
if hir_id != self.target_module {
1629-
intravisit::walk_mod(self, module, hir_id);
1630-
return;
1631-
}
1632-
// Find a `use` statement.
1633-
for &item_id in module.item_ids {
1634-
let item = self.tcx.hir().item(item_id);
1635-
match item.kind {
1636-
hir::ItemKind::Use(..) => {
1637-
// Don't suggest placing a `use` before the prelude
1638-
// import or other generated ones.
1639-
if !item.span.from_expansion() {
1640-
self.span = Some(item.span.shrink_to_lo());
1641-
self.found_use = true;
1642-
return;
1643-
}
1606+
fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
1607+
let mut span = None;
1608+
let mut found_use = false;
1609+
let (module, _, _) = tcx.hir().get_module(target_module);
1610+
1611+
// Find a `use` statement.
1612+
for &item_id in module.item_ids {
1613+
let item = tcx.hir().item(item_id);
1614+
match item.kind {
1615+
hir::ItemKind::Use(..) => {
1616+
// Don't suggest placing a `use` before the prelude
1617+
// import or other generated ones.
1618+
if !item.span.from_expansion() {
1619+
span = Some(item.span.shrink_to_lo());
1620+
found_use = true;
1621+
break;
16441622
}
1645-
// Don't place `use` before `extern crate`...
1646-
hir::ItemKind::ExternCrate(_) => {}
1647-
// ...but do place them before the first other item.
1648-
_ => {
1649-
if self.span.map_or(true, |span| item.span < span) {
1650-
if !item.span.from_expansion() {
1651-
self.span = Some(item.span.shrink_to_lo());
1652-
// Don't insert between attributes and an item.
1653-
let attrs = self.tcx.hir().attrs(item.hir_id());
1654-
// Find the first attribute on the item.
1655-
// FIXME: This is broken for active attributes.
1656-
for attr in attrs {
1657-
if !attr.span.is_dummy()
1658-
&& self.span.map_or(true, |span| attr.span < span)
1659-
{
1660-
self.span = Some(attr.span.shrink_to_lo());
1661-
}
1623+
}
1624+
// Don't place `use` before `extern crate`...
1625+
hir::ItemKind::ExternCrate(_) => {}
1626+
// ...but do place them before the first other item.
1627+
_ => {
1628+
if span.map_or(true, |span| item.span < span) {
1629+
if !item.span.from_expansion() {
1630+
span = Some(item.span.shrink_to_lo());
1631+
// Don't insert between attributes and an item.
1632+
let attrs = tcx.hir().attrs(item.hir_id());
1633+
// Find the first attribute on the item.
1634+
// FIXME: This is broken for active attributes.
1635+
for attr in attrs {
1636+
if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
1637+
span = Some(attr.span.shrink_to_lo());
16621638
}
16631639
}
16641640
}
@@ -1667,11 +1643,7 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
16671643
}
16681644
}
16691645

1670-
type Map = intravisit::ErasedMap<'tcx>;
1671-
1672-
fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
1673-
intravisit::NestedVisitorMap::None
1674-
}
1646+
(span, found_use)
16751647
}
16761648

16771649
fn print_disambiguation_help(

0 commit comments

Comments
 (0)