@@ -71,7 +71,6 @@ use rustc_span::{Span, DUMMY_SP};
71
71
use smallvec:: { smallvec, SmallVec } ;
72
72
use std:: cell:: { Cell , RefCell } ;
73
73
use std:: collections:: BTreeSet ;
74
- use std:: ops:: ControlFlow ;
75
74
use std:: { cmp, fmt, iter, mem, ptr} ;
76
75
use tracing:: debug;
77
76
@@ -315,74 +314,70 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
315
314
}
316
315
}
317
316
317
+ #[ derive( Debug ) ]
318
318
struct UsePlacementFinder {
319
319
target_module : NodeId ,
320
- span : Option < Span > ,
321
- found_use : bool ,
320
+ first_legal_span : Option < Span > ,
321
+ first_use_span : Option < Span > ,
322
322
}
323
323
324
324
impl UsePlacementFinder {
325
325
fn check ( krate : & Crate , target_module : NodeId ) -> ( Option < Span > , bool ) {
326
- let mut finder = UsePlacementFinder { target_module, span : None , found_use : false } ;
327
- if let ControlFlow :: Continue ( ..) = finder. check_mod ( & krate. items , CRATE_NODE_ID ) {
328
- visit:: walk_crate ( & mut finder, krate) ;
329
- }
330
- ( finder. span , finder. found_use )
331
- }
332
-
333
- fn check_mod ( & mut self , items : & [ P < ast:: Item > ] , node_id : NodeId ) -> ControlFlow < ( ) > {
334
- if self . span . is_some ( ) {
335
- return ControlFlow :: Break ( ( ) ) ;
336
- }
337
- if node_id != self . target_module {
338
- return ControlFlow :: Continue ( ( ) ) ;
339
- }
340
- // find a use statement
341
- for item in items {
342
- match item. kind {
343
- ItemKind :: Use ( ..) => {
344
- // don't suggest placing a use before the prelude
345
- // import or other generated ones
346
- if !item. span . from_expansion ( ) {
347
- self . span = Some ( item. span . shrink_to_lo ( ) ) ;
348
- self . found_use = true ;
349
- return ControlFlow :: Break ( ( ) ) ;
350
- }
351
- }
352
- // don't place use before extern crate
353
- ItemKind :: ExternCrate ( _) => { }
354
- // but place them before the first other item
355
- _ => {
356
- if self . span . map_or ( true , |span| item. span < span)
357
- && !item. span . from_expansion ( )
358
- {
359
- self . span = Some ( item. span . shrink_to_lo ( ) ) ;
360
- // don't insert between attributes and an item
361
- // find the first attribute on the item
362
- // FIXME: This is broken for active attributes.
363
- for attr in & item. attrs {
364
- if !attr. span . is_dummy ( )
365
- && self . span . map_or ( true , |span| attr. span < span)
366
- {
367
- self . span = Some ( attr. span . shrink_to_lo ( ) ) ;
368
- }
369
- }
370
- }
371
- }
326
+ let mut finder =
327
+ UsePlacementFinder { target_module, first_legal_span : None , first_use_span : None } ;
328
+ finder. visit_crate ( krate) ;
329
+ if let Some ( use_span) = finder. first_use_span {
330
+ ( Some ( use_span) , true )
331
+ } else {
332
+ ( finder. first_legal_span , false )
333
+ }
334
+ }
335
+ }
336
+
337
+ fn is_span_suitable_for_use_injection ( s : Span ) -> bool {
338
+ // don't suggest placing a use before the prelude
339
+ // import or other generated ones
340
+ !s. from_expansion ( )
341
+ }
342
+
343
+ fn search_for_any_use_in_items ( items : & [ P < ast:: Item > ] ) -> Option < Span > {
344
+ for item in items {
345
+ if let ItemKind :: Use ( ..) = item. kind {
346
+ if is_span_suitable_for_use_injection ( item. span ) {
347
+ return Some ( item. span . shrink_to_lo ( ) ) ;
372
348
}
373
349
}
374
- ControlFlow :: Continue ( ( ) )
375
350
}
351
+ return None ;
376
352
}
377
353
378
354
impl < ' tcx > Visitor < ' tcx > for UsePlacementFinder {
355
+ fn visit_crate ( & mut self , c : & Crate ) {
356
+ if self . target_module == CRATE_NODE_ID {
357
+ let inject = c. spans . inject_use_span ;
358
+ if is_span_suitable_for_use_injection ( inject) {
359
+ self . first_legal_span = Some ( inject) ;
360
+ }
361
+ self . first_use_span = search_for_any_use_in_items ( & c. items ) ;
362
+ return ;
363
+ } else {
364
+ visit:: walk_crate ( self , c) ;
365
+ }
366
+ }
367
+
379
368
fn visit_item ( & mut self , item : & ' tcx ast:: Item ) {
380
- if let ItemKind :: Mod ( _, ModKind :: Loaded ( items, ..) ) = & item. kind {
381
- if let ControlFlow :: Break ( ..) = self . check_mod ( items, item. id ) {
369
+ if self . target_module == item. id {
370
+ if let ItemKind :: Mod ( _, ModKind :: Loaded ( items, _inline, mod_spans) ) = & item. kind {
371
+ let inject = mod_spans. inject_use_span ;
372
+ if is_span_suitable_for_use_injection ( inject) {
373
+ self . first_legal_span = Some ( inject) ;
374
+ }
375
+ self . first_use_span = search_for_any_use_in_items ( items) ;
382
376
return ;
383
377
}
378
+ } else {
379
+ visit:: walk_item ( self , item) ;
384
380
}
385
- visit:: walk_item ( self , item) ;
386
381
}
387
382
}
388
383
@@ -1282,7 +1277,7 @@ impl<'a> Resolver<'a> {
1282
1277
None ,
1283
1278
ModuleKind :: Def ( DefKind :: Mod , root_def_id, kw:: Empty ) ,
1284
1279
ExpnId :: root ( ) ,
1285
- krate. span ,
1280
+ krate. spans . inner_span ,
1286
1281
session. contains_name ( & krate. attrs , sym:: no_implicit_prelude) ,
1287
1282
& mut module_map,
1288
1283
) ;
@@ -1295,7 +1290,7 @@ impl<'a> Resolver<'a> {
1295
1290
& mut FxHashMap :: default ( ) ,
1296
1291
) ;
1297
1292
1298
- let definitions = Definitions :: new ( session. local_stable_crate_id ( ) , krate. span ) ;
1293
+ let definitions = Definitions :: new ( session. local_stable_crate_id ( ) , krate. spans . inner_span ) ;
1299
1294
let root = definitions. get_root_def ( ) ;
1300
1295
1301
1296
let mut visibilities = FxHashMap :: default ( ) ;
0 commit comments