@@ -7,7 +7,7 @@ use rustc_errors::{
7
7
pluralize, struct_span_err, Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed ,
8
8
} ;
9
9
use rustc_hir as hir;
10
- use rustc_hir:: def_id:: { DefId , LocalDefId } ;
10
+ use rustc_hir:: def_id:: DefId ;
11
11
use rustc_hir:: lang_items:: LangItem ;
12
12
use rustc_hir:: { ExprKind , Node , QPath } ;
13
13
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
@@ -1473,12 +1473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1473
1473
}
1474
1474
}
1475
1475
1476
- fn suggest_use_candidates (
1477
- & self ,
1478
- err : & mut Diagnostic ,
1479
- mut msg : String ,
1480
- candidates : Vec < DefId > ,
1481
- ) {
1476
+ fn suggest_use_candidates ( & self , err : & mut Diagnostic , msg : String , candidates : Vec < DefId > ) {
1482
1477
let parent_map = self . tcx . visible_parent_map ( ( ) ) ;
1483
1478
1484
1479
// Separate out candidates that must be imported with a glob, because they are named `_`
@@ -1502,80 +1497,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1502
1497
} ) ;
1503
1498
1504
1499
let module_did = self . tcx . parent_module ( self . body_id ) ;
1505
- let ( span, found_use) = find_use_placement ( self . tcx , module_did) ;
1506
- if let Some ( span) = span {
1507
- let path_strings = candidates. iter ( ) . map ( |trait_did| {
1508
- // Produce an additional newline to separate the new use statement
1509
- // from the directly following item.
1510
- let additional_newline = if found_use { "" } else { "\n " } ;
1511
- format ! (
1512
- "use {};\n {}" ,
1513
- with_crate_prefix!( self . tcx. def_path_str( * trait_did) ) ,
1514
- additional_newline
1515
- )
1516
- } ) ;
1500
+ let ( module, _, _) = self . tcx . hir ( ) . get_module ( module_did) ;
1501
+ let span = module. spans . inject_use_span ;
1517
1502
1518
- let glob_path_strings = globs. iter ( ) . map ( |trait_did| {
1519
- let parent_did = parent_map. get ( trait_did) . unwrap ( ) ;
1503
+ let path_strings = candidates. iter ( ) . map ( |trait_did| {
1504
+ format ! ( "use {};\n " , with_crate_prefix!( self . tcx. def_path_str( * trait_did) ) , )
1505
+ } ) ;
1520
1506
1521
- // Produce an additional newline to separate the new use statement
1522
- // from the directly following item.
1523
- let additional_newline = if found_use { "" } else { "\n " } ;
1524
- format ! (
1525
- "use {}::*; // trait {}\n {}" ,
1526
- with_crate_prefix!( self . tcx. def_path_str( * parent_did) ) ,
1527
- self . tcx. item_name( * trait_did) ,
1528
- additional_newline
1529
- )
1530
- } ) ;
1507
+ let glob_path_strings = globs. iter ( ) . map ( |trait_did| {
1508
+ let parent_did = parent_map. get ( trait_did) . unwrap ( ) ;
1509
+ format ! (
1510
+ "use {}::*; // trait {}\n " ,
1511
+ with_crate_prefix!( self . tcx. def_path_str( * parent_did) ) ,
1512
+ self . tcx. item_name( * trait_did) ,
1513
+ )
1514
+ } ) ;
1531
1515
1532
- err. span_suggestions (
1533
- span,
1534
- & msg,
1535
- path_strings. chain ( glob_path_strings) ,
1536
- Applicability :: MaybeIncorrect ,
1537
- ) ;
1538
- } else {
1539
- let limit = if candidates. len ( ) + globs. len ( ) == 5 { 5 } else { 4 } ;
1540
- for ( i, trait_did) in candidates. iter ( ) . take ( limit) . enumerate ( ) {
1541
- if candidates. len ( ) + globs. len ( ) > 1 {
1542
- msg. push_str ( & format ! (
1543
- "\n candidate #{}: `use {};`" ,
1544
- i + 1 ,
1545
- with_crate_prefix!( self . tcx. def_path_str( * trait_did) )
1546
- ) ) ;
1547
- } else {
1548
- msg. push_str ( & format ! (
1549
- "\n `use {};`" ,
1550
- with_crate_prefix!( self . tcx. def_path_str( * trait_did) )
1551
- ) ) ;
1552
- }
1553
- }
1554
- for ( i, trait_did) in
1555
- globs. iter ( ) . take ( limit. saturating_sub ( candidates. len ( ) ) ) . enumerate ( )
1556
- {
1557
- let parent_did = parent_map. get ( trait_did) . unwrap ( ) ;
1558
-
1559
- if candidates. len ( ) + globs. len ( ) > 1 {
1560
- msg. push_str ( & format ! (
1561
- "\n candidate #{}: `use {}::*; // trait {}`" ,
1562
- candidates. len( ) + i + 1 ,
1563
- with_crate_prefix!( self . tcx. def_path_str( * parent_did) ) ,
1564
- self . tcx. item_name( * trait_did) ,
1565
- ) ) ;
1566
- } else {
1567
- msg. push_str ( & format ! (
1568
- "\n `use {}::*; // trait {}`" ,
1569
- with_crate_prefix!( self . tcx. def_path_str( * parent_did) ) ,
1570
- self . tcx. item_name( * trait_did) ,
1571
- ) ) ;
1572
- }
1573
- }
1574
- if candidates. len ( ) > limit {
1575
- msg. push_str ( & format ! ( "\n and {} others" , candidates. len( ) + globs. len( ) - limit) ) ;
1576
- }
1577
- err. note ( & msg) ;
1578
- }
1516
+ err. span_suggestions (
1517
+ span,
1518
+ & msg,
1519
+ path_strings. chain ( glob_path_strings) ,
1520
+ Applicability :: MaybeIncorrect ,
1521
+ ) ;
1579
1522
}
1580
1523
1581
1524
fn suggest_valid_traits (
@@ -2100,53 +2043,6 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
2100
2043
tcx. all_traits ( ) . map ( |def_id| TraitInfo { def_id } ) . collect ( )
2101
2044
}
2102
2045
2103
- fn find_use_placement < ' tcx > ( tcx : TyCtxt < ' tcx > , target_module : LocalDefId ) -> ( Option < Span > , bool ) {
2104
- // FIXME(#94854): this code uses an out-of-date method for inferring a span
2105
- // to suggest. It would be better to thread the ModSpans from the AST into
2106
- // the HIR, and then use that to drive the suggestion here.
2107
-
2108
- let mut span = None ;
2109
- let mut found_use = false ;
2110
- let ( module, _, _) = tcx. hir ( ) . get_module ( target_module) ;
2111
-
2112
- // Find a `use` statement.
2113
- for & item_id in module. item_ids {
2114
- let item = tcx. hir ( ) . item ( item_id) ;
2115
- match item. kind {
2116
- hir:: ItemKind :: Use ( ..) => {
2117
- // Don't suggest placing a `use` before the prelude
2118
- // import or other generated ones.
2119
- if !item. span . from_expansion ( ) {
2120
- span = Some ( item. span . shrink_to_lo ( ) ) ;
2121
- found_use = true ;
2122
- break ;
2123
- }
2124
- }
2125
- // Don't place `use` before `extern crate`...
2126
- hir:: ItemKind :: ExternCrate ( _) => { }
2127
- // ...but do place them before the first other item.
2128
- _ => {
2129
- if span. map_or ( true , |span| item. span < span) {
2130
- if !item. span . from_expansion ( ) {
2131
- span = Some ( item. span . shrink_to_lo ( ) ) ;
2132
- // Don't insert between attributes and an item.
2133
- let attrs = tcx. hir ( ) . attrs ( item. hir_id ( ) ) ;
2134
- // Find the first attribute on the item.
2135
- // FIXME: This is broken for active attributes.
2136
- for attr in attrs {
2137
- if !attr. span . is_dummy ( ) && span. map_or ( true , |span| attr. span < span) {
2138
- span = Some ( attr. span . shrink_to_lo ( ) ) ;
2139
- }
2140
- }
2141
- }
2142
- }
2143
- }
2144
- }
2145
- }
2146
-
2147
- ( span, found_use)
2148
- }
2149
-
2150
2046
fn print_disambiguation_help < ' tcx > (
2151
2047
item_name : Ident ,
2152
2048
args : Option < & ' tcx [ hir:: Expr < ' tcx > ] > ,
0 commit comments