@@ -225,13 +225,11 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
225
225
item : & ' c ast:: Item ,
226
226
sub_mod : Module < ' ast > ,
227
227
) -> Result < ( ) , ModuleResolutionError > {
228
- let old_directory = self . directory . clone ( ) ;
229
228
let sub_mod_kind = self . peek_sub_mod ( item, & sub_mod) ?;
230
229
if let Some ( sub_mod_kind) = sub_mod_kind {
231
230
self . insert_sub_mod ( sub_mod_kind. clone ( ) ) ?;
232
231
self . visit_sub_mod_inner ( sub_mod, sub_mod_kind) ?;
233
232
}
234
- self . directory = old_directory;
235
233
Ok ( ( ) )
236
234
}
237
235
@@ -288,33 +286,35 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
288
286
path : mod_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
289
287
ownership : directory_ownership,
290
288
} ;
291
- self . visit_sub_mod_after_directory_update ( sub_mod, Some ( directory) )
289
+ self . with_directory ( directory, |this| {
290
+ this. visit_sub_mod_after_directory_update ( sub_mod)
291
+ } ) ?;
292
292
}
293
293
SubModKind :: Internal ( item) => {
294
- self . push_inline_mod_directory ( item. ident , & item. attrs ) ;
295
- self . visit_sub_mod_after_directory_update ( sub_mod, None )
294
+ let directory = self . inline_mod_directory ( item. ident , & item. attrs ) ;
295
+ self . with_directory ( directory, |this| {
296
+ this. visit_sub_mod_after_directory_update ( sub_mod)
297
+ } ) ?;
296
298
}
297
299
SubModKind :: MultiExternal ( mods) => {
298
300
for ( mod_path, directory_ownership, sub_mod) in mods {
299
301
let directory = Directory {
300
302
path : mod_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
301
303
ownership : directory_ownership,
302
304
} ;
303
- self . visit_sub_mod_after_directory_update ( sub_mod, Some ( directory) ) ?;
305
+ self . with_directory ( directory, |this| {
306
+ this. visit_sub_mod_after_directory_update ( sub_mod)
307
+ } ) ?;
304
308
}
305
- Ok ( ( ) )
306
309
}
307
310
}
311
+ Ok ( ( ) )
308
312
}
309
313
310
314
fn visit_sub_mod_after_directory_update (
311
315
& mut self ,
312
316
sub_mod : Module < ' ast > ,
313
- directory : Option < Directory > ,
314
317
) -> Result < ( ) , ModuleResolutionError > {
315
- if let Some ( directory) = directory {
316
- self . directory = directory;
317
- }
318
318
match ( sub_mod. ast_mod_kind , sub_mod. items ) {
319
319
( Some ( Cow :: Borrowed ( ast:: ModKind :: Loaded ( items, _, _) ) ) , _) => {
320
320
self . visit_mod_from_ast ( items)
@@ -470,10 +470,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
470
470
}
471
471
}
472
472
473
- fn push_inline_mod_directory ( & mut self , id : symbol:: Ident , attrs : & [ ast:: Attribute ] ) {
473
+ fn inline_mod_directory ( & mut self , id : symbol:: Ident , attrs : & [ ast:: Attribute ] ) -> Directory {
474
474
if let Some ( path) = find_path_value ( attrs) {
475
- self . directory . path . push ( path. as_str ( ) ) ;
476
- self . directory . ownership = DirectoryOwnership :: Owned { relative : None } ;
475
+ Directory {
476
+ path : self . directory . path . join ( path. as_str ( ) ) ,
477
+ ownership : DirectoryOwnership :: Owned { relative : None } ,
478
+ }
477
479
} else {
478
480
let id = id. as_str ( ) ;
479
481
// We have to push on the current module name in the case of relative
@@ -482,19 +484,28 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
482
484
//
483
485
// For example, a `mod z { ... }` inside `x/y.rs` should set the current
484
486
// directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
485
- if let DirectoryOwnership :: Owned { relative } = & mut self . directory . ownership {
486
- if let Some ( ident) = relative. take ( ) {
487
- // remove the relative offset
488
- self . directory . path . push ( ident. as_str ( ) ) ;
489
-
490
- // In the case where there is an x.rs and an ./x directory we want
491
- // to prevent adding x twice. For example, ./x/x
492
- if self . directory . path . exists ( ) && !self . directory . path . join ( id) . exists ( ) {
493
- return ;
494
- }
487
+ let new_path = if let DirectoryOwnership :: Owned {
488
+ relative : Some ( ident) ,
489
+ } = self . directory . ownership
490
+ {
491
+ // remove the relative offset
492
+ let relative = self . directory . path . join ( ident. as_str ( ) ) ;
493
+ let nested = relative. join ( id) ;
494
+
495
+ // In the case where there is an x.rs and an ./x directory we want
496
+ // to prevent adding x twice. For example, ./x/x
497
+ if relative. exists ( ) && !nested. exists ( ) {
498
+ relative
499
+ } else {
500
+ nested
495
501
}
502
+ } else {
503
+ self . directory . path . join ( id)
504
+ } ;
505
+ Directory {
506
+ path : new_path,
507
+ ownership : self . directory . ownership ,
496
508
}
497
- self . directory . path . push ( id) ;
498
509
}
499
510
}
500
511
@@ -512,8 +523,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
512
523
}
513
524
let mut result = vec ! [ ] ;
514
525
for path in path_visitor. paths ( ) {
515
- let mut actual_path = self . directory . path . clone ( ) ;
516
- actual_path. push ( & path) ;
526
+ let actual_path = self . directory . path . join ( path) ;
517
527
if !actual_path. exists ( ) {
518
528
continue ;
519
529
}
@@ -546,6 +556,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
546
556
}
547
557
result
548
558
}
559
+
560
+ fn with_directory < T > ( & mut self , directory : Directory , f : impl FnOnce ( & mut Self ) -> T ) -> T {
561
+ let old = std:: mem:: replace ( & mut self . directory , directory) ;
562
+ let out = f ( self ) ;
563
+ self . directory = old;
564
+ out
565
+ }
549
566
}
550
567
551
568
fn path_value ( attr : & ast:: Attribute ) -> Option < Symbol > {
0 commit comments