From 4ad1c6600115593a7c2f2273f138872728d3211a Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Mon, 6 Aug 2018 22:28:05 +0900 Subject: [PATCH 1/2] Use custom path value if one exists when searching modules --- src/modules.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/modules.rs b/src/modules.rs index d94b2dd13332..3316c5a970bc 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -15,6 +15,7 @@ use std::path::{Path, PathBuf}; use syntax::ast; use syntax::codemap; use syntax::parse::{parser, DirectoryOwnership}; +use syntax_pos::symbol::Symbol; use config::FileName; use utils::contains_skip; @@ -38,6 +39,18 @@ pub fn list_files<'a>( Ok(result) } +fn path_value(attr: &ast::Attribute) -> Option { + if attr.name() == "path" { + attr.value_str() + } else { + None + } +} + +fn find_path_value(attrs: &[ast::Attribute]) -> Option { + attrs.iter().flat_map(path_value).next() +} + /// Recursively list all external modules included in a module. fn list_submodules<'a>( module: &'a ast::Mod, @@ -53,7 +66,11 @@ fn list_submodules<'a>( let is_internal = codemap.span_to_filename(item.span) == codemap.span_to_filename(sub_mod.inner); let (dir_path, relative) = if is_internal { - (search_dir.join(&item.ident.to_string()), None) + if let Some(path) = find_path_value(&item.attrs) { + (search_dir.join(&path.as_str()), None) + } else { + (search_dir.join(&item.ident.to_string()), None) + } } else { let (mod_path, relative) = module_file(item.ident, &item.attrs, search_dir, relative, codemap)?; From a201d856d10913b887f259c5302d4f5dfcebf6a9 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Mon, 6 Aug 2018 22:34:58 +0900 Subject: [PATCH 2/2] Add comment --- src/modules.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules.rs b/src/modules.rs index 3316c5a970bc..7619c0afa57a 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -47,6 +47,9 @@ fn path_value(attr: &ast::Attribute) -> Option { } } +// N.B. Even when there are multiple `#[path = ...]` attributes, we just need to +// examine the first one, since rustc ignores the second and the subsequent ones +// as unused attributes. fn find_path_value(attrs: &[ast::Attribute]) -> Option { attrs.iter().flat_map(path_value).next() }