@@ -6,8 +6,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6
6
use rustc_errors:: { pluralize, struct_span_err, Applicability , DiagnosticBuilder } ;
7
7
use rustc_hir as hir;
8
8
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 } ;
11
10
use rustc_hir:: lang_items:: LangItem ;
12
11
use rustc_hir:: { ExprKind , Node , QPath } ;
13
12
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
@@ -1011,9 +1010,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1011
1010
candidates : Vec < DefId > ,
1012
1011
) {
1013
1012
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 krate = self . tcx . hir ( ) . krate ( ) ;
1016
- let ( span, found_use) = UsePlacementFinder :: check ( self . tcx , krate, module_id) ;
1013
+ let ( span, found_use) = find_use_placement ( self . tcx , module_did) ;
1017
1014
if let Some ( span) = span {
1018
1015
let path_strings = candidates. iter ( ) . map ( |did| {
1019
1016
// Produce an additional newline to separate the new use statement
@@ -1606,64 +1603,38 @@ pub fn provide(providers: &mut ty::query::Providers) {
1606
1603
providers. all_traits = compute_all_traits;
1607
1604
}
1608
1605
1609
- struct UsePlacementFinder < ' tcx > {
1610
- target_module : hir:: HirId ,
1611
- span : Option < Span > ,
1612
- found_use : bool ,
1613
- tcx : TyCtxt < ' tcx > ,
1614
- }
1615
-
1616
- impl UsePlacementFinder < ' tcx > {
1617
- fn check (
1618
- tcx : TyCtxt < ' tcx > ,
1619
- krate : & ' tcx hir:: Crate < ' tcx > ,
1620
- target_module : hir:: HirId ,
1621
- ) -> ( Option < Span > , bool ) {
1622
- let mut finder = UsePlacementFinder { target_module, span : None , found_use : false , tcx } ;
1623
- intravisit:: walk_crate ( & mut finder, krate) ;
1624
- ( finder. span , finder. found_use )
1625
- }
1626
- }
1627
-
1628
- impl intravisit:: Visitor < ' tcx > for UsePlacementFinder < ' tcx > {
1629
- fn visit_mod ( & mut self , module : & ' tcx hir:: Mod < ' tcx > , _: Span , hir_id : hir:: HirId ) {
1630
- if self . span . is_some ( ) {
1631
- return ;
1632
- }
1633
- if hir_id != self . target_module {
1634
- intravisit:: walk_mod ( self , module, hir_id) ;
1635
- return ;
1636
- }
1637
- // Find a `use` statement.
1638
- for & item_id in module. item_ids {
1639
- let item = self . tcx . hir ( ) . item ( item_id) ;
1640
- match item. kind {
1641
- hir:: ItemKind :: Use ( ..) => {
1642
- // Don't suggest placing a `use` before the prelude
1643
- // import or other generated ones.
1644
- if !item. span . from_expansion ( ) {
1645
- self . span = Some ( item. span . shrink_to_lo ( ) ) ;
1646
- self . found_use = true ;
1647
- return ;
1648
- }
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 ;
1649
1622
}
1650
- // Don't place `use` before `extern crate`...
1651
- hir:: ItemKind :: ExternCrate ( _) => { }
1652
- // ...but do place them before the first other item.
1653
- _ => {
1654
- if self . span . map_or ( true , |span| item. span < span) {
1655
- if !item. span . from_expansion ( ) {
1656
- self . span = Some ( item. span . shrink_to_lo ( ) ) ;
1657
- // Don't insert between attributes and an item.
1658
- let attrs = self . tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
1659
- // Find the first attribute on the item.
1660
- // FIXME: This is broken for active attributes.
1661
- for attr in attrs {
1662
- if !attr. span . is_dummy ( )
1663
- && self . span . map_or ( true , |span| attr. span < span)
1664
- {
1665
- self . span = Some ( attr. span . shrink_to_lo ( ) ) ;
1666
- }
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 ( ) ) ;
1667
1638
}
1668
1639
}
1669
1640
}
@@ -1672,11 +1643,7 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
1672
1643
}
1673
1644
}
1674
1645
1675
- type Map = intravisit:: ErasedMap < ' tcx > ;
1676
-
1677
- fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
1678
- intravisit:: NestedVisitorMap :: None
1679
- }
1646
+ ( span, found_use)
1680
1647
}
1681
1648
1682
1649
fn print_disambiguation_help (
0 commit comments