1
1
use crate :: base:: * ;
2
2
use crate :: config:: StripUnconfigured ;
3
+ use crate :: configure;
3
4
use crate :: hygiene:: { ExpnData , ExpnId , ExpnKind , SyntaxContext } ;
4
5
use crate :: mbe:: macro_rules:: annotate_err_with_kind;
6
+ use crate :: module:: { parse_external_mod, push_directory, Directory , DirectoryOwnership } ;
5
7
use crate :: placeholders:: { placeholder, PlaceholderExpander } ;
6
8
use crate :: proc_macro:: collect_derives;
7
9
@@ -17,10 +19,8 @@ use rustc_ast_pretty::pprust;
17
19
use rustc_attr:: { self as attr, is_builtin_attr, HasAttrs } ;
18
20
use rustc_errors:: { Applicability , FatalError , PResult } ;
19
21
use rustc_feature:: Features ;
20
- use rustc_parse:: configure;
21
22
use rustc_parse:: parser:: Parser ;
22
23
use rustc_parse:: validate_attr;
23
- use rustc_parse:: DirectoryOwnership ;
24
24
use rustc_session:: lint:: builtin:: UNUSED_DOC_COMMENTS ;
25
25
use rustc_session:: lint:: BuiltinLintDiagnostics ;
26
26
use rustc_session:: parse:: { feature_err, ParseSess } ;
@@ -1366,59 +1366,83 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1366
1366
. make_items ( ) ;
1367
1367
}
1368
1368
1369
+ let mut attrs = mem:: take ( & mut item. attrs ) ; // We do this to please borrowck.
1370
+ let ident = item. ident ;
1371
+ let span = item. span ;
1372
+
1369
1373
match item. kind {
1370
1374
ast:: ItemKind :: MacCall ( ..) => {
1375
+ item. attrs = attrs;
1371
1376
self . check_attributes ( & item. attrs ) ;
1372
1377
item. and_then ( |item| match item. kind {
1373
1378
ItemKind :: MacCall ( mac) => self
1374
- . collect (
1375
- AstFragmentKind :: Items ,
1376
- InvocationKind :: Bang { mac, span : item. span } ,
1377
- )
1379
+ . collect ( AstFragmentKind :: Items , InvocationKind :: Bang { mac, span } )
1378
1380
. make_items ( ) ,
1379
1381
_ => unreachable ! ( ) ,
1380
1382
} )
1381
1383
}
1382
- ast:: ItemKind :: Mod ( ast:: Mod { inner, inline, .. } )
1383
- if item. ident != Ident :: invalid ( ) =>
1384
- {
1385
- let orig_directory_ownership = self . cx . current_expansion . directory_ownership ;
1384
+ ast:: ItemKind :: Mod ( ref mut old_mod @ ast:: Mod { .. } ) if ident != Ident :: invalid ( ) => {
1385
+ let sess = self . cx . parse_sess ;
1386
+ let orig_ownership = self . cx . current_expansion . directory_ownership ;
1386
1387
let mut module = ( * self . cx . current_expansion . module ) . clone ( ) ;
1387
- module. mod_path . push ( item. ident ) ;
1388
1388
1389
- if inline {
1390
- if let Some ( path) = attr:: first_attr_value_str_by_name ( & item. attrs , sym:: path) {
1391
- self . cx . current_expansion . directory_ownership =
1392
- DirectoryOwnership :: Owned { relative : None } ;
1393
- module. directory . push ( & * path. as_str ( ) ) ;
1394
- } else {
1395
- module. directory . push ( & * item. ident . as_str ( ) ) ;
1396
- }
1389
+ let pushed = & mut false ; // Record `parse_external_mod` pushing so we can pop.
1390
+ let dir = Directory { ownership : orig_ownership, path : module. directory } ;
1391
+ let Directory { ownership, path } = if old_mod. inline {
1392
+ // Inline `mod foo { ... }`, but we still need to push directories.
1393
+ item. attrs = attrs;
1394
+ push_directory ( ident, & item. attrs , dir)
1397
1395
} else {
1398
- let path = self . cx . parse_sess . source_map ( ) . span_to_unmapped_path ( inner) ;
1399
- let mut path = match path {
1400
- FileName :: Real ( path) => path,
1401
- other => PathBuf :: from ( other. to_string ( ) ) ,
1396
+ // We have an outline `mod foo;` so we need to parse the file.
1397
+ let ( new_mod, dir) =
1398
+ parse_external_mod ( sess, ident, span, dir, & mut attrs, pushed) ;
1399
+
1400
+ let krate = ast:: Crate {
1401
+ span : new_mod. inner ,
1402
+ module : new_mod,
1403
+ attrs,
1404
+ proc_macros : vec ! [ ] ,
1402
1405
} ;
1403
- let directory_ownership = match path. file_name ( ) . unwrap ( ) . to_str ( ) {
1404
- Some ( "mod.rs" ) => DirectoryOwnership :: Owned { relative : None } ,
1405
- Some ( _) => DirectoryOwnership :: Owned { relative : Some ( item. ident ) } ,
1406
- None => DirectoryOwnership :: UnownedViaMod ,
1406
+ if let Some ( extern_mod_loaded) = self . cx . extern_mod_loaded {
1407
+ extern_mod_loaded ( & krate) ;
1408
+ }
1409
+
1410
+ * old_mod = krate. module ;
1411
+ item. attrs = krate. attrs ;
1412
+ // File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure.
1413
+ item = match self . configure ( item) {
1414
+ Some ( node) => node,
1415
+ None => {
1416
+ if * pushed {
1417
+ sess. included_mod_stack . borrow_mut ( ) . pop ( ) ;
1418
+ }
1419
+ return Default :: default ( ) ;
1420
+ }
1407
1421
} ;
1408
- path. pop ( ) ;
1409
- module. directory = path;
1410
- self . cx . current_expansion . directory_ownership = directory_ownership;
1411
- }
1422
+ dir
1423
+ } ;
1412
1424
1425
+ // Set the module info before we flat map.
1426
+ self . cx . current_expansion . directory_ownership = ownership;
1427
+ module. directory = path;
1428
+ module. mod_path . push ( ident) ;
1413
1429
let orig_module =
1414
1430
mem:: replace ( & mut self . cx . current_expansion . module , Rc :: new ( module) ) ;
1431
+
1415
1432
let result = noop_flat_map_item ( item, self ) ;
1433
+
1434
+ // Restore the module info.
1416
1435
self . cx . current_expansion . module = orig_module;
1417
- self . cx . current_expansion . directory_ownership = orig_directory_ownership;
1436
+ self . cx . current_expansion . directory_ownership = orig_ownership;
1437
+ if * pushed {
1438
+ sess. included_mod_stack . borrow_mut ( ) . pop ( ) ;
1439
+ }
1418
1440
result
1419
1441
}
1420
-
1421
- _ => noop_flat_map_item ( item, self ) ,
1442
+ _ => {
1443
+ item. attrs = attrs;
1444
+ noop_flat_map_item ( item, self )
1445
+ }
1422
1446
}
1423
1447
}
1424
1448
0 commit comments