@@ -49,7 +49,7 @@ use parse::common::SeqSep;
49
49
use parse:: lexer:: { Reader , TokenAndSpan } ;
50
50
use parse:: obsolete:: ObsoleteSyntax ;
51
51
use parse:: token:: { self , MatchNt , SubstNt } ;
52
- use parse:: { new_sub_parser_from_file, ParseSess } ;
52
+ use parse:: { new_sub_parser_from_file, ParseSess , Directory , DirectoryOwnership } ;
53
53
use util:: parser:: { AssocOp , Fixity } ;
54
54
use print:: pprust;
55
55
use ptr:: P ;
@@ -68,7 +68,6 @@ bitflags! {
68
68
flags Restrictions : u8 {
69
69
const RESTRICTION_STMT_EXPR = 1 << 0 ,
70
70
const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1 ,
71
- const NO_NONINLINE_MOD = 1 << 2 ,
72
71
}
73
72
}
74
73
@@ -200,12 +199,9 @@ pub struct Parser<'a> {
200
199
/// extra detail when the same error is seen twice
201
200
pub obsolete_set : HashSet < ObsoleteSyntax > ,
202
201
/// Used to determine the path to externally loaded source files
203
- pub directory : PathBuf ,
202
+ pub directory : Directory ,
204
203
/// Stack of open delimiters and their spans. Used for error message.
205
204
pub open_braces : Vec < ( token:: DelimToken , Span ) > ,
206
- /// Flag if this parser "owns" the directory that it is currently parsing
207
- /// in. This will affect how nested files are looked up.
208
- pub owns_directory : bool ,
209
205
/// Name of the root module this parser originated from. If `None`, then the
210
206
/// name is not known. This does not change while the parser is descending
211
207
/// into modules, and sub-parsers have new values for this name.
@@ -245,8 +241,8 @@ pub struct ModulePath {
245
241
}
246
242
247
243
pub struct ModulePathSuccess {
248
- pub path : :: std :: path :: PathBuf ,
249
- pub owns_directory : bool ,
244
+ pub path : PathBuf ,
245
+ pub directory_ownership : DirectoryOwnership ,
250
246
}
251
247
252
248
pub struct ModulePathError {
@@ -296,9 +292,8 @@ impl<'a> Parser<'a> {
296
292
quote_depth : 0 ,
297
293
parsing_token_tree : false ,
298
294
obsolete_set : HashSet :: new ( ) ,
299
- directory : PathBuf :: new ( ) ,
295
+ directory : Directory { path : PathBuf :: new ( ) , ownership : DirectoryOwnership :: Owned } ,
300
296
open_braces : Vec :: new ( ) ,
301
- owns_directory : true ,
302
297
root_module_name : None ,
303
298
expected_tokens : Vec :: new ( ) ,
304
299
tts : Vec :: new ( ) ,
@@ -310,8 +305,8 @@ impl<'a> Parser<'a> {
310
305
parser. token = tok. tok ;
311
306
parser. span = tok. sp ;
312
307
if parser. span != syntax_pos:: DUMMY_SP {
313
- parser. directory = PathBuf :: from ( sess. codemap ( ) . span_to_filename ( parser. span ) ) ;
314
- parser. directory . pop ( ) ;
308
+ parser. directory . path = PathBuf :: from ( sess. codemap ( ) . span_to_filename ( parser. span ) ) ;
309
+ parser. directory . path . pop ( ) ;
315
310
}
316
311
parser
317
312
}
@@ -3966,9 +3961,11 @@ impl<'a> Parser<'a> {
3966
3961
}
3967
3962
} else {
3968
3963
// FIXME: Bad copy of attrs
3969
- let restrictions = self . restrictions | Restrictions :: NO_NONINLINE_MOD ;
3970
- match self . with_res ( restrictions,
3971
- |this| this. parse_item_ ( attrs. clone ( ) , false , true ) ) ? {
3964
+ let old_directory_ownership =
3965
+ mem:: replace ( & mut self . directory . ownership , DirectoryOwnership :: UnownedViaBlock ) ;
3966
+ let item = self . parse_item_ ( attrs. clone ( ) , false , true ) ?;
3967
+ self . directory . ownership = old_directory_ownership;
3968
+ match item {
3972
3969
Some ( i) => Stmt {
3973
3970
id : ast:: DUMMY_NODE_ID ,
3974
3971
span : mk_sp ( lo, i. span . hi ) ,
@@ -5271,33 +5268,33 @@ impl<'a> Parser<'a> {
5271
5268
self . bump ( ) ;
5272
5269
if in_cfg {
5273
5270
// This mod is in an external file. Let's go get it!
5274
- let ( m, attrs) = self . eval_src_mod ( id, & outer_attrs, id_span) ?;
5275
- Ok ( ( id, m, Some ( attrs) ) )
5271
+ let ModulePathSuccess { path, directory_ownership } =
5272
+ self . submod_path ( id, & outer_attrs, id_span) ?;
5273
+ let ( module, attrs) =
5274
+ self . eval_src_mod ( path, directory_ownership, id. to_string ( ) , id_span) ?;
5275
+ Ok ( ( id, module, Some ( attrs) ) )
5276
5276
} else {
5277
5277
let placeholder = ast:: Mod { inner : syntax_pos:: DUMMY_SP , items : Vec :: new ( ) } ;
5278
5278
Ok ( ( id, ItemKind :: Mod ( placeholder) , None ) )
5279
5279
}
5280
5280
} else {
5281
- let directory = self . directory . clone ( ) ;
5282
- let restrictions = self . push_directory ( id, & outer_attrs) ;
5281
+ let old_directory = self . directory . clone ( ) ;
5282
+ self . push_directory ( id, & outer_attrs) ;
5283
5283
self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
5284
5284
let mod_inner_lo = self . span . lo ;
5285
5285
let attrs = self . parse_inner_attributes ( ) ?;
5286
- let m = self . with_res ( restrictions, |this| {
5287
- this. parse_mod_items ( & token:: CloseDelim ( token:: Brace ) , mod_inner_lo)
5288
- } ) ?;
5289
- self . directory = directory;
5290
- Ok ( ( id, ItemKind :: Mod ( m) , Some ( attrs) ) )
5286
+ let module = self . parse_mod_items ( & token:: CloseDelim ( token:: Brace ) , mod_inner_lo) ?;
5287
+ self . directory = old_directory;
5288
+ Ok ( ( id, ItemKind :: Mod ( module) , Some ( attrs) ) )
5291
5289
}
5292
5290
}
5293
5291
5294
- fn push_directory ( & mut self , id : Ident , attrs : & [ Attribute ] ) -> Restrictions {
5292
+ fn push_directory ( & mut self , id : Ident , attrs : & [ Attribute ] ) {
5295
5293
if let Some ( path) = :: attr:: first_attr_value_str_by_name ( attrs, "path" ) {
5296
- self . directory . push ( & * path. as_str ( ) ) ;
5297
- self . restrictions - Restrictions :: NO_NONINLINE_MOD
5294
+ self . directory . path . push ( & * path. as_str ( ) ) ;
5295
+ self . directory . ownership = DirectoryOwnership :: Owned ;
5298
5296
} else {
5299
- self . directory . push ( & * id. name . as_str ( ) ) ;
5300
- self . restrictions
5297
+ self . directory . path . push ( & * id. name . as_str ( ) ) ;
5301
5298
}
5302
5299
}
5303
5300
@@ -5317,8 +5314,14 @@ impl<'a> Parser<'a> {
5317
5314
let secondary_exists = codemap. file_exists ( & secondary_path) ;
5318
5315
5319
5316
let result = match ( default_exists, secondary_exists) {
5320
- ( true , false ) => Ok ( ModulePathSuccess { path : default_path, owns_directory : false } ) ,
5321
- ( false , true ) => Ok ( ModulePathSuccess { path : secondary_path, owns_directory : true } ) ,
5317
+ ( true , false ) => Ok ( ModulePathSuccess {
5318
+ path : default_path,
5319
+ directory_ownership : DirectoryOwnership :: UnownedViaMod ,
5320
+ } ) ,
5321
+ ( false , true ) => Ok ( ModulePathSuccess {
5322
+ path : secondary_path,
5323
+ directory_ownership : DirectoryOwnership :: Owned ,
5324
+ } ) ,
5322
5325
( false , false ) => Err ( ModulePathError {
5323
5326
err_msg : format ! ( "file not found for module `{}`" , mod_name) ,
5324
5327
help_msg : format ! ( "name the file either {} or {} inside the directory {:?}" ,
@@ -5346,13 +5349,19 @@ impl<'a> Parser<'a> {
5346
5349
id : ast:: Ident ,
5347
5350
outer_attrs : & [ ast:: Attribute ] ,
5348
5351
id_sp : Span ) -> PResult < ' a , ModulePathSuccess > {
5349
- if let Some ( p) = Parser :: submod_path_from_attr ( outer_attrs, & self . directory ) {
5350
- return Ok ( ModulePathSuccess { path : p, owns_directory : true } ) ;
5352
+ if let Some ( path) = Parser :: submod_path_from_attr ( outer_attrs, & self . directory . path ) {
5353
+ return Ok ( ModulePathSuccess {
5354
+ directory_ownership : match path. file_name ( ) . and_then ( |s| s. to_str ( ) ) {
5355
+ Some ( "mod.rs" ) => DirectoryOwnership :: Owned ,
5356
+ _ => DirectoryOwnership :: UnownedViaMod ,
5357
+ } ,
5358
+ path : path,
5359
+ } ) ;
5351
5360
}
5352
5361
5353
- let paths = Parser :: default_submod_path ( id, & self . directory , self . sess . codemap ( ) ) ;
5362
+ let paths = Parser :: default_submod_path ( id, & self . directory . path , self . sess . codemap ( ) ) ;
5354
5363
5355
- if self . restrictions . contains ( Restrictions :: NO_NONINLINE_MOD ) {
5364
+ if let DirectoryOwnership :: UnownedViaBlock = self . directory . ownership {
5356
5365
let msg =
5357
5366
"Cannot declare a non-inline module inside a block unless it has a path attribute" ;
5358
5367
let mut err = self . diagnostic ( ) . struct_span_err ( id_sp, msg) ;
@@ -5362,10 +5371,10 @@ impl<'a> Parser<'a> {
5362
5371
err. span_note ( id_sp, & msg) ;
5363
5372
}
5364
5373
return Err ( err) ;
5365
- } else if ! self . owns_directory {
5374
+ } else if let DirectoryOwnership :: UnownedViaMod = self . directory . ownership {
5366
5375
let mut err = self . diagnostic ( ) . struct_span_err ( id_sp,
5367
5376
"cannot declare a new module at this location" ) ;
5368
- let this_module = match self . directory . file_name ( ) {
5377
+ let this_module = match self . directory . path . file_name ( ) {
5369
5378
Some ( file_name) => file_name. to_str ( ) . unwrap ( ) . to_owned ( ) ,
5370
5379
None => self . root_module_name . as_ref ( ) . unwrap ( ) . clone ( ) ,
5371
5380
} ;
@@ -5390,25 +5399,11 @@ impl<'a> Parser<'a> {
5390
5399
5391
5400
/// Read a module from a source file.
5392
5401
fn eval_src_mod ( & mut self ,
5393
- id : ast:: Ident ,
5394
- outer_attrs : & [ ast:: Attribute ] ,
5402
+ path : PathBuf ,
5403
+ directory_ownership : DirectoryOwnership ,
5404
+ name : String ,
5395
5405
id_sp : Span )
5396
5406
-> PResult < ' a , ( ast:: ItemKind , Vec < ast:: Attribute > ) > {
5397
- let ModulePathSuccess { path, owns_directory } = self . submod_path ( id,
5398
- outer_attrs,
5399
- id_sp) ?;
5400
-
5401
- self . eval_src_mod_from_path ( path,
5402
- owns_directory,
5403
- id. to_string ( ) ,
5404
- id_sp)
5405
- }
5406
-
5407
- fn eval_src_mod_from_path ( & mut self ,
5408
- path : PathBuf ,
5409
- owns_directory : bool ,
5410
- name : String ,
5411
- id_sp : Span ) -> PResult < ' a , ( ast:: ItemKind , Vec < ast:: Attribute > ) > {
5412
5407
let mut included_mod_stack = self . sess . included_mod_stack . borrow_mut ( ) ;
5413
5408
if let Some ( i) = included_mod_stack. iter ( ) . position ( |p| * p == path) {
5414
5409
let mut err = String :: from ( "circular modules: " ) ;
@@ -5423,7 +5418,8 @@ impl<'a> Parser<'a> {
5423
5418
included_mod_stack. push ( path. clone ( ) ) ;
5424
5419
drop ( included_mod_stack) ;
5425
5420
5426
- let mut p0 = new_sub_parser_from_file ( self . sess , & path, owns_directory, Some ( name) , id_sp) ;
5421
+ let mut p0 =
5422
+ new_sub_parser_from_file ( self . sess , & path, directory_ownership, Some ( name) , id_sp) ;
5427
5423
let mod_inner_lo = p0. span . lo ;
5428
5424
let mod_attrs = p0. parse_inner_attributes ( ) ?;
5429
5425
let m0 = p0. parse_mod_items ( & token:: Eof , mod_inner_lo) ?;
0 commit comments