Skip to content

Allow foo.rs to be parent to foo/bar.rs #39702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,9 +898,16 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
} else {
let mut path =
PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner));
let directory_ownership = match path.file_name().unwrap().to_str() {
Some("mod.rs") => DirectoryOwnership::Owned,
_ => DirectoryOwnership::UnownedViaMod(false),
let directory_ownership = {
let file_name = path.file_name().unwrap();
match file_name.to_str() {
Some("mod.rs") => DirectoryOwnership::Owned,
Some(s) if s.ends_with(".rs") && s.len() > 3 => {
let directory_name = s.rsplitn(2, '.').skip(1).next().unwrap();
DirectoryOwnership::OwnedUnder(Ident::from_str(directory_name))
}
_ => DirectoryOwnership::UnownedViaMod(true),
}
};
path.pop();
module.directory = path;
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

//! The main parser interface

use ast::{self, CrateConfig};
use ast::{self, CrateConfig, Ident};
use codemap::CodeMap;
use syntax_pos::{self, Span, FileMap};
use errors::{Handler, ColorConfig, DiagnosticBuilder};
Expand Down Expand Up @@ -87,6 +87,7 @@ pub enum DirectoryOwnership {
Owned,
UnownedViaBlock,
UnownedViaMod(bool /* legacy warnings? */),
OwnedUnder(Ident),
}

// a bunch of utility functions of the form parse_<thing>_from_<source>
Expand Down
32 changes: 24 additions & 8 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5146,20 +5146,28 @@ impl<'a> Parser<'a> {
}

/// Returns either a path to a module, or .
pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -> ModulePath
pub fn default_submod_path(id: ast::Ident, dir: &Directory, codemap: &CodeMap) -> ModulePath
{
let mod_name = id.to_string();
let dir_path = &dir.path;
let default_path_str = format!("{}.rs", mod_name);
let secondary_path_str = format!("{}/mod.rs", mod_name);
let default_path = dir_path.join(&default_path_str);
let secondary_path = dir_path.join(&secondary_path_str);

let (default_path, secondary_path) = match dir.ownership {
DirectoryOwnership::OwnedUnder(under_id) => {
let under_path = dir_path.join(under_id.to_string());
(under_path.join(&default_path_str), under_path.join(&secondary_path_str))
}
_ => (dir_path.join(&default_path_str), dir_path.join(&secondary_path_str)),
};

let default_exists = codemap.file_exists(&default_path);
let secondary_exists = codemap.file_exists(&secondary_path);

let result = match (default_exists, secondary_exists) {
(true, false) => Ok(ModulePathSuccess {
path: default_path,
directory_ownership: DirectoryOwnership::UnownedViaMod(false),
directory_ownership: DirectoryOwnership::OwnedUnder(id),
warn: false,
}),
(false, true) => Ok(ModulePathSuccess {
Expand Down Expand Up @@ -5195,17 +5203,25 @@ impl<'a> Parser<'a> {
outer_attrs: &[ast::Attribute],
id_sp: Span) -> PResult<'a, ModulePathSuccess> {
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()) {
let ownership = {
let file_name = path.file_name().unwrap();
match file_name.to_str() {
Some("mod.rs") => DirectoryOwnership::Owned,
Some(s) if s.ends_with(".rs") && s.len() > 3 => {
let directory_name = s.rsplitn(2, '.').skip(1).next().unwrap();
DirectoryOwnership::OwnedUnder(Ident::from_str(directory_name))
}
_ => DirectoryOwnership::UnownedViaMod(true),
},
}
};
return Ok(ModulePathSuccess {
directory_ownership: ownership,
path: path,
warn: false,
});
}

let paths = Parser::default_submod_path(id, &self.directory.path, self.sess.codemap());
let paths = Parser::default_submod_path(id, &self.directory, self.sess.codemap());

if let DirectoryOwnership::UnownedViaBlock = self.directory.ownership {
let msg =
Expand Down