aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-11-03 18:00:24 +0000
committerGitHub <noreply@github.com>2021-11-03 18:00:24 +0000
commit8e992e371bbd896c8b605e1ebade5cad80b1b411 (patch)
tree329a3e626fb05effe7383efb8df3bdf671f7e35c /gcc/rust/ast
parent674221a3b27f5455fddc793ec9aaf30a4d858ecb (diff)
parent1657ee53d578d68c7d807312b1063ffd804d7ef9 (diff)
downloadgcc-8e992e371bbd896c8b605e1ebade5cad80b1b411.zip
gcc-8e992e371bbd896c8b605e1ebade5cad80b1b411.tar.gz
gcc-8e992e371bbd896c8b605e1ebade5cad80b1b411.tar.bz2
Merge #785
785: rust: track inline module scopes for module file resolution r=CohenArthur a=mathstuf The set of inline modules is required to find the expected location of a module file. Track this information with an RAII object (`InlineModuleStackScope`) and pass it down to any out-of-line modules so that, when requested, the set of inline modules can be added to the search path. Signed-off-by: Ben Boeckel <mathstuf@gmail.com> --- Note that this does not include a test case because I have no idea how to mark up this for all the warnings that come out (#676): ```diff diff --git a/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs b/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs new file mode 100644 index 00000000000..f099d61e04a --- /dev/null +++ b/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs `@@` -0,0 +1,3 `@@` +pub fn f() -> u32 { + 1 +} diff --git a/gcc/testsuite/rust/compile/mod_missing_middle.rs b/gcc/testsuite/rust/compile/mod_missing_middle.rs new file mode 100644 index 00000000000..d9cdf0a54f1 --- /dev/null +++ b/gcc/testsuite/rust/compile/mod_missing_middle.rs `@@` -0,0 +1,11 `@@` +pub mod missing_middle { + pub mod sub; +} ``` Observed warnings: ``` /home/boeckb/code/depot/group-compilers/gcc/src-gccrs/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs:1:5: warning: unused name 'f' /home/boeckb/code/depot/group-compilers/gcc/src-gccrs/gcc/testsuite/rust/compile/mod_missing_middle.rs:2:9: warning: unused name 'sub' /home/boeckb/code/depot/group-compilers/gcc/src-gccrs/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs:1:5: warning: unused name 'sub::f' /home/boeckb/code/depot/group-compilers/gcc/src-gccrs/gcc/testsuite/rust/compile/mod_missing_middle.rs:2:9: warning: unused name 'missing_middle::sub' /home/boeckb/code/depot/group-compilers/gcc/src-gccrs/gcc/testsuite/rust/compile/mod_missing_middle.rs:1:5: warning: unused name 'missing_middle' /home/boeckb/code/depot/group-compilers/gcc/src-gccrs/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs:1:5: warning: unused name 'missing_middle::sub::f' ``` Fixes: #645 Here is a checklist to help you with your PR. - \[x] GCC development requires copyright assignment or the Developer's Certificate of Origin sign-off, see https://gcc.gnu.org/contribute.html or https://gcc.gnu.org/dco.html - \[x] Read contributing guidlines - \[x] `make check-rust` passes locally - \[x] Run `clang-format` (leaving to CI) - \[x] Added any relevant test cases to `gcc/testsuite/rust/` (see above) Co-authored-by: Ben Boeckel <mathstuf@gmail.com>
Diffstat (limited to 'gcc/rust/ast')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc71
-rw-r--r--gcc/rust/ast/rust-item.h11
2 files changed, 26 insertions, 56 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index a189d8c..8780853 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -3984,53 +3984,11 @@ file_exists (const std::string path)
static std::string
filename_from_path_attribute (std::vector<Attribute> &outer_attrs)
{
- Attribute path_attr = Attribute::create_empty ();
- for (auto attr : outer_attrs)
- {
- if (attr.get_path ().as_string () == "path")
- {
- path_attr = attr;
- break;
- }
- }
-
- // We didn't find a path attribute. This is not an error, there simply isn't
- // one present
- if (path_attr.is_empty ())
- return "";
-
- // Here, we found a path attribute, but it has no associated string. This is
- // invalid
- if (!path_attr.has_attr_input ())
- {
- rust_error_at (
- path_attr.get_locus (),
- // Split the format string so that -Wformat-diag does not complain...
- "path attributes must contain a filename: '%s'", "#[path = \"file\"]");
- return "";
- }
-
- auto path_value = path_attr.get_attr_input ().as_string ();
-
- // At this point, the 'path' is of the following format: '= "<file.rs>"'
- // We need to remove the equal sign and only keep the actual filename.
- // In order to do this, we can simply go through the string until we find
- // a character that is not an equal sign or whitespace
- auto filename_begin = path_value.find_first_not_of ("=\t ");
-
- auto path = path_value.substr (filename_begin);
-
- // On windows, the path might mix '/' and '\' separators. Replace the
- // UNIX-like separators by MSDOS separators to make sure the path will resolve
- // properly.
- //
- // Source: rustc compiler
- // (https://github.com/rust-lang/rust/blob/9863bf51a52b8e61bcad312f81b5193d53099f9f/compiler/rustc_expand/src/module.rs#L174)
-#if defined(HAVE_DOS_BASED_FILE_SYSTEM)
- path.replace ('/', '\\');
-#endif /* HAVE_DOS_BASED_FILE_SYSTEM */
-
- return path;
+ // An out-of-line module cannot have inner attributes. Additionally, the
+ // default name is specified as `""` so that the caller can detect the case
+ // of "no path given" and use the default path logic (`name.rs` or
+ // `name/mod.rs`).
+ return extract_module_path ({}, outer_attrs, "");
}
void
@@ -4057,6 +4015,13 @@ Module::process_file_path ()
current_directory_name
= including_fname.substr (0, dir_slash_pos) + file_separator;
+ // Handle inline module declarations adding path components.
+ for (auto const &name : module_scope)
+ {
+ current_directory_name.append (name);
+ current_directory_name.append (file_separator);
+ }
+
auto path_string = filename_from_path_attribute (get_outer_attrs ());
if (!path_string.empty ())
{
@@ -4070,12 +4035,13 @@ Module::process_file_path ()
// current file is titled `mod.rs`.
// First, we search for <directory>/<module_name>.rs
- bool file_mod_found
- = file_exists (current_directory_name + expected_file_path);
+ std::string file_mod_path = current_directory_name + expected_file_path;
+ bool file_mod_found = file_exists (file_mod_path);
// Then, search for <directory>/<module_name>/mod.rs
- current_directory_name += module_name + file_separator;
- bool dir_mod_found = file_exists (current_directory_name + expected_dir_path);
+ std::string dir_mod_path
+ = current_directory_name + module_name + file_separator + expected_dir_path;
+ bool dir_mod_found = file_exists (dir_mod_path);
bool multiple_candidates_found = file_mod_found && dir_mod_found;
bool no_candidates_found = !file_mod_found && !dir_mod_found;
@@ -4093,8 +4059,7 @@ Module::process_file_path ()
if (no_candidates_found || multiple_candidates_found)
return;
- module_file = file_mod_found ? expected_file_path
- : current_directory_name + expected_dir_path;
+ module_file = std::move (file_mod_found ? file_mod_path : dir_mod_path);
}
void
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 39411f8..f952dcc 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -991,6 +991,8 @@ private:
std::vector<Attribute> inner_attrs;
// bool has_items;
std::vector<std::unique_ptr<Item>> items;
+ // Names of including inline modules (immediate parent is last in the list)
+ std::vector<std::string> module_scope;
// Filename the module refers to. Empty string on LOADED modules or if an
// error occured when dealing with UNLOADED modules
@@ -1013,11 +1015,12 @@ public:
// Unloaded module constructor
Module (Identifier module_name, Visibility visibility,
std::vector<Attribute> outer_attrs, Location locus,
- std::string outer_filename)
+ std::string outer_filename, std::vector<std::string> module_scope)
: VisItem (std::move (visibility), std::move (outer_attrs)),
module_name (module_name), locus (locus), kind (ModuleKind::UNLOADED),
outer_filename (outer_filename), inner_attrs (std::vector<Attribute> ()),
- items (std::vector<std::unique_ptr<Item>> ())
+ items (std::vector<std::unique_ptr<Item>> ()),
+ module_scope (std::move (module_scope))
{}
// Loaded module constructor, with items
@@ -1035,7 +1038,8 @@ public:
// Copy constructor with vector clone
Module (Module const &other)
: VisItem (other), module_name (other.module_name), locus (other.locus),
- kind (other.kind), inner_attrs (other.inner_attrs)
+ kind (other.kind), inner_attrs (other.inner_attrs),
+ module_scope (other.module_scope)
{
// We need to check whether we are copying a loaded module or an unloaded
// one. In the second case, clear the `items` vector.
@@ -1054,6 +1058,7 @@ public:
locus = other.locus;
kind = other.kind;
inner_attrs = other.inner_attrs;
+ module_scope = other.module_scope;
// Likewise, we need to clear the `items` vector in case the other module is
// unloaded