diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-11-05 04:16:26 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-11-22 01:48:10 +0000 |
| commit | 5675d9d28007691c4f396abcd4b29a228150eeb4 (patch) | |
| tree | ff28ee180c2e904520168d953a6946574c94b18b /src/libsyntax/parse/parser.rs | |
| parent | 7b3eeea22c9b81f6e7277b79517a0dab25b9f383 (diff) | |
| download | rust-5675d9d28007691c4f396abcd4b29a228150eeb4.tar.gz rust-5675d9d28007691c4f396abcd4b29a228150eeb4.zip | |
Clean up directory ownership semantics.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 106 |
1 files changed, 51 insertions, 55 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4997e464c2b..ee69125ffae 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -49,7 +49,7 @@ use parse::common::SeqSep; use parse::lexer::{Reader, TokenAndSpan}; use parse::obsolete::ObsoleteSyntax; use parse::token::{self, MatchNt, SubstNt}; -use parse::{new_sub_parser_from_file, ParseSess}; +use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership}; use util::parser::{AssocOp, Fixity}; use print::pprust; use ptr::P; @@ -68,7 +68,6 @@ bitflags! { flags Restrictions: u8 { const RESTRICTION_STMT_EXPR = 1 << 0, const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1, - const NO_NONINLINE_MOD = 1 << 2, } } @@ -200,12 +199,9 @@ pub struct Parser<'a> { /// extra detail when the same error is seen twice pub obsolete_set: HashSet<ObsoleteSyntax>, /// Used to determine the path to externally loaded source files - pub directory: PathBuf, + pub directory: Directory, /// Stack of open delimiters and their spans. Used for error message. pub open_braces: Vec<(token::DelimToken, Span)>, - /// Flag if this parser "owns" the directory that it is currently parsing - /// in. This will affect how nested files are looked up. - pub owns_directory: bool, /// Name of the root module this parser originated from. If `None`, then the /// name is not known. This does not change while the parser is descending /// into modules, and sub-parsers have new values for this name. @@ -245,8 +241,8 @@ pub struct ModulePath { } pub struct ModulePathSuccess { - pub path: ::std::path::PathBuf, - pub owns_directory: bool, + pub path: PathBuf, + pub directory_ownership: DirectoryOwnership, } pub struct ModulePathError { @@ -296,9 +292,8 @@ impl<'a> Parser<'a> { quote_depth: 0, parsing_token_tree: false, obsolete_set: HashSet::new(), - directory: PathBuf::new(), + directory: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned }, open_braces: Vec::new(), - owns_directory: true, root_module_name: None, expected_tokens: Vec::new(), tts: Vec::new(), @@ -310,8 +305,8 @@ impl<'a> Parser<'a> { parser.token = tok.tok; parser.span = tok.sp; if parser.span != syntax_pos::DUMMY_SP { - parser.directory = PathBuf::from(sess.codemap().span_to_filename(parser.span)); - parser.directory.pop(); + parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span)); + parser.directory.path.pop(); } parser } @@ -3966,9 +3961,11 @@ impl<'a> Parser<'a> { } } else { // FIXME: Bad copy of attrs - let restrictions = self.restrictions | Restrictions::NO_NONINLINE_MOD; - match self.with_res(restrictions, - |this| this.parse_item_(attrs.clone(), false, true))? { + let old_directory_ownership = + mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock); + let item = self.parse_item_(attrs.clone(), false, true)?; + self.directory.ownership = old_directory_ownership; + match item { Some(i) => Stmt { id: ast::DUMMY_NODE_ID, span: mk_sp(lo, i.span.hi), @@ -5271,33 +5268,33 @@ impl<'a> Parser<'a> { self.bump(); if in_cfg { // This mod is in an external file. Let's go get it! - let (m, attrs) = self.eval_src_mod(id, &outer_attrs, id_span)?; - Ok((id, m, Some(attrs))) + let ModulePathSuccess { path, directory_ownership } = + self.submod_path(id, &outer_attrs, id_span)?; + let (module, attrs) = + self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?; + Ok((id, module, Some(attrs))) } else { let placeholder = ast::Mod { inner: syntax_pos::DUMMY_SP, items: Vec::new() }; Ok((id, ItemKind::Mod(placeholder), None)) } } else { - let directory = self.directory.clone(); - let restrictions = self.push_directory(id, &outer_attrs); + let old_directory = self.directory.clone(); + self.push_directory(id, &outer_attrs); self.expect(&token::OpenDelim(token::Brace))?; let mod_inner_lo = self.span.lo; let attrs = self.parse_inner_attributes()?; - let m = self.with_res(restrictions, |this| { - this.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo) - })?; - self.directory = directory; - Ok((id, ItemKind::Mod(m), Some(attrs))) + let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?; + self.directory = old_directory; + Ok((id, ItemKind::Mod(module), Some(attrs))) } } - fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) -> Restrictions { + fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) { if let Some(path) = ::attr::first_attr_value_str_by_name(attrs, "path") { - self.directory.push(&*path.as_str()); - self.restrictions - Restrictions::NO_NONINLINE_MOD + self.directory.path.push(&*path.as_str()); + self.directory.ownership = DirectoryOwnership::Owned; } else { - self.directory.push(&*id.name.as_str()); - self.restrictions + self.directory.path.push(&*id.name.as_str()); } } @@ -5317,8 +5314,14 @@ impl<'a> Parser<'a> { let secondary_exists = codemap.file_exists(&secondary_path); let result = match (default_exists, secondary_exists) { - (true, false) => Ok(ModulePathSuccess { path: default_path, owns_directory: false }), - (false, true) => Ok(ModulePathSuccess { path: secondary_path, owns_directory: true }), + (true, false) => Ok(ModulePathSuccess { + path: default_path, + directory_ownership: DirectoryOwnership::UnownedViaMod, + }), + (false, true) => Ok(ModulePathSuccess { + path: secondary_path, + directory_ownership: DirectoryOwnership::Owned, + }), (false, false) => Err(ModulePathError { err_msg: format!("file not found for module `{}`", mod_name), help_msg: format!("name the file either {} or {} inside the directory {:?}", @@ -5346,13 +5349,19 @@ impl<'a> Parser<'a> { id: ast::Ident, outer_attrs: &[ast::Attribute], id_sp: Span) -> PResult<'a, ModulePathSuccess> { - if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &self.directory) { - return Ok(ModulePathSuccess { path: p, owns_directory: true }); + if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) { + return Ok(ModulePathSuccess { + directory_ownership: match path.file_name().and_then(|s| s.to_str()) { + Some("mod.rs") => DirectoryOwnership::Owned, + _ => DirectoryOwnership::UnownedViaMod, + }, + path: path, + }); } - let paths = Parser::default_submod_path(id, &self.directory, self.sess.codemap()); + let paths = Parser::default_submod_path(id, &self.directory.path, self.sess.codemap()); - if self.restrictions.contains(Restrictions::NO_NONINLINE_MOD) { + if let DirectoryOwnership::UnownedViaBlock = self.directory.ownership { let msg = "Cannot declare a non-inline module inside a block unless it has a path attribute"; let mut err = self.diagnostic().struct_span_err(id_sp, msg); @@ -5362,10 +5371,10 @@ impl<'a> Parser<'a> { err.span_note(id_sp, &msg); } return Err(err); - } else if !self.owns_directory { + } else if let DirectoryOwnership::UnownedViaMod = self.directory.ownership { let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); - let this_module = match self.directory.file_name() { + let this_module = match self.directory.path.file_name() { Some(file_name) => file_name.to_str().unwrap().to_owned(), None => self.root_module_name.as_ref().unwrap().clone(), }; @@ -5390,25 +5399,11 @@ impl<'a> Parser<'a> { /// Read a module from a source file. fn eval_src_mod(&mut self, - id: ast::Ident, - outer_attrs: &[ast::Attribute], + path: PathBuf, + directory_ownership: DirectoryOwnership, + name: String, id_sp: Span) -> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> { - let ModulePathSuccess { path, owns_directory } = self.submod_path(id, - outer_attrs, - id_sp)?; - - self.eval_src_mod_from_path(path, - owns_directory, - id.to_string(), - id_sp) - } - - fn eval_src_mod_from_path(&mut self, - path: PathBuf, - owns_directory: bool, - name: String, - id_sp: Span) -> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> { let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut(); if let Some(i) = included_mod_stack.iter().position(|p| *p == path) { let mut err = String::from("circular modules: "); @@ -5423,7 +5418,8 @@ impl<'a> Parser<'a> { included_mod_stack.push(path.clone()); drop(included_mod_stack); - let mut p0 = new_sub_parser_from_file(self.sess, &path, owns_directory, Some(name), id_sp); + let mut p0 = + new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp); let mod_inner_lo = p0.span.lo; let mod_attrs = p0.parse_inner_attributes()?; let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?; |
