@@ -49,7 +49,7 @@ use parse::common::SeqSep;
4949use parse:: lexer:: { Reader , TokenAndSpan } ;
5050use parse:: obsolete:: ObsoleteSyntax ;
5151use 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 } ;
5353use util:: parser:: { AssocOp , Fixity } ;
5454use print:: pprust;
5555use ptr:: P ;
@@ -68,7 +68,6 @@ bitflags! {
6868 flags Restrictions : u8 {
6969 const RESTRICTION_STMT_EXPR = 1 << 0 ,
7070 const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1 ,
71- const NO_NONINLINE_MOD = 1 << 2 ,
7271 }
7372}
7473
@@ -200,12 +199,9 @@ pub struct Parser<'a> {
200199 /// extra detail when the same error is seen twice
201200 pub obsolete_set : HashSet < ObsoleteSyntax > ,
202201 /// Used to determine the path to externally loaded source files
203- pub directory : PathBuf ,
202+ pub directory : Directory ,
204203 /// Stack of open delimiters and their spans. Used for error message.
205204 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 ,
209205 /// Name of the root module this parser originated from. If `None`, then the
210206 /// name is not known. This does not change while the parser is descending
211207 /// into modules, and sub-parsers have new values for this name.
@@ -245,8 +241,8 @@ pub struct ModulePath {
245241}
246242
247243pub struct ModulePathSuccess {
248- pub path : :: std :: path :: PathBuf ,
249- pub owns_directory : bool ,
244+ pub path : PathBuf ,
245+ pub directory_ownership : DirectoryOwnership ,
250246}
251247
252248pub struct ModulePathError {
@@ -296,9 +292,8 @@ impl<'a> Parser<'a> {
296292 quote_depth : 0 ,
297293 parsing_token_tree : false ,
298294 obsolete_set : HashSet :: new ( ) ,
299- directory : PathBuf :: new ( ) ,
295+ directory : Directory { path : PathBuf :: new ( ) , ownership : DirectoryOwnership :: Owned } ,
300296 open_braces : Vec :: new ( ) ,
301- owns_directory : true ,
302297 root_module_name : None ,
303298 expected_tokens : Vec :: new ( ) ,
304299 tts : Vec :: new ( ) ,
@@ -310,8 +305,8 @@ impl<'a> Parser<'a> {
310305 parser. token = tok. tok ;
311306 parser. span = tok. sp ;
312307 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 ( ) ;
315310 }
316311 parser
317312 }
@@ -3966,9 +3961,11 @@ impl<'a> Parser<'a> {
39663961 }
39673962 } else {
39683963 // 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 {
39723969 Some ( i) => Stmt {
39733970 id : ast:: DUMMY_NODE_ID ,
39743971 span : mk_sp ( lo, i. span . hi ) ,
@@ -5271,33 +5268,33 @@ impl<'a> Parser<'a> {
52715268 self . bump ( ) ;
52725269 if in_cfg {
52735270 // 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) ) )
52765276 } else {
52775277 let placeholder = ast:: Mod { inner : syntax_pos:: DUMMY_SP , items : Vec :: new ( ) } ;
52785278 Ok ( ( id, ItemKind :: Mod ( placeholder) , None ) )
52795279 }
52805280 } 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) ;
52835283 self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
52845284 let mod_inner_lo = self . span . lo ;
52855285 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) ) )
52915289 }
52925290 }
52935291
5294- fn push_directory ( & mut self , id : Ident , attrs : & [ Attribute ] ) -> Restrictions {
5292+ fn push_directory ( & mut self , id : Ident , attrs : & [ Attribute ] ) {
52955293 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 ;
52985296 } else {
5299- self . directory . push ( & * id. name . as_str ( ) ) ;
5300- self . restrictions
5297+ self . directory . path . push ( & * id. name . as_str ( ) ) ;
53015298 }
53025299 }
53035300
@@ -5317,8 +5314,14 @@ impl<'a> Parser<'a> {
53175314 let secondary_exists = codemap. file_exists ( & secondary_path) ;
53185315
53195316 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+ } ) ,
53225325 ( false , false ) => Err ( ModulePathError {
53235326 err_msg : format ! ( "file not found for module `{}`" , mod_name) ,
53245327 help_msg : format ! ( "name the file either {} or {} inside the directory {:?}" ,
@@ -5346,13 +5349,19 @@ impl<'a> Parser<'a> {
53465349 id : ast:: Ident ,
53475350 outer_attrs : & [ ast:: Attribute ] ,
53485351 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+ } ) ;
53515360 }
53525361
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 ( ) ) ;
53545363
5355- if self . restrictions . contains ( Restrictions :: NO_NONINLINE_MOD ) {
5364+ if let DirectoryOwnership :: UnownedViaBlock = self . directory . ownership {
53565365 let msg =
53575366 "Cannot declare a non-inline module inside a block unless it has a path attribute" ;
53585367 let mut err = self . diagnostic ( ) . struct_span_err ( id_sp, msg) ;
@@ -5362,10 +5371,10 @@ impl<'a> Parser<'a> {
53625371 err. span_note ( id_sp, & msg) ;
53635372 }
53645373 return Err ( err) ;
5365- } else if ! self . owns_directory {
5374+ } else if let DirectoryOwnership :: UnownedViaMod = self . directory . ownership {
53665375 let mut err = self . diagnostic ( ) . struct_span_err ( id_sp,
53675376 "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 ( ) {
53695378 Some ( file_name) => file_name. to_str ( ) . unwrap ( ) . to_owned ( ) ,
53705379 None => self . root_module_name . as_ref ( ) . unwrap ( ) . clone ( ) ,
53715380 } ;
@@ -5390,25 +5399,11 @@ impl<'a> Parser<'a> {
53905399
53915400 /// Read a module from a source file.
53925401 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 ,
53955405 id_sp : Span )
53965406 -> 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 > ) > {
54125407 let mut included_mod_stack = self . sess . included_mod_stack . borrow_mut ( ) ;
54135408 if let Some ( i) = included_mod_stack. iter ( ) . position ( |p| * p == path) {
54145409 let mut err = String :: from ( "circular modules: " ) ;
@@ -5423,7 +5418,8 @@ impl<'a> Parser<'a> {
54235418 included_mod_stack. push ( path. clone ( ) ) ;
54245419 drop ( included_mod_stack) ;
54255420
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) ;
54275423 let mod_inner_lo = p0. span . lo ;
54285424 let mod_attrs = p0. parse_inner_attributes ( ) ?;
54295425 let m0 = p0. parse_mod_items ( & token:: Eof , mod_inner_lo) ?;
0 commit comments