aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse
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/parse
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/parse')
-rw-r--r--gcc/rust/parse/rust-parse-impl.h8
-rw-r--r--gcc/rust/parse/rust-parse.cc73
-rw-r--r--gcc/rust/parse/rust-parse.h19
3 files changed, 98 insertions, 2 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 52aba4f..7f0db1b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2104,14 +2104,18 @@ Parser<ManagedTokenSource>::parse_module (AST::Visibility vis,
// Construct an external module
return std::unique_ptr<AST::Module> (
new AST::Module (std::move (name), std::move (vis),
- std::move (outer_attrs), locus,
- lexer.get_filename ()));
+ std::move (outer_attrs), locus, lexer.get_filename (),
+ inline_module_stack));
case LEFT_CURLY: {
lexer.skip_token ();
// parse inner attributes
AST::AttrVec inner_attrs = parse_inner_attributes ();
+ std::string module_path_name
+ = extract_module_path (inner_attrs, outer_attrs, name);
+ InlineModuleStackScope scope (*this, std::move (module_path_name));
+
// parse items
std::vector<std::unique_ptr<AST::Item>> items;
const_TokenPtr tok = lexer.peek_token ();
diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc
index fdad97c..e78de51 100644
--- a/gcc/rust/parse/rust-parse.cc
+++ b/gcc/rust/parse/rust-parse.cc
@@ -46,4 +46,77 @@ along with GCC; see the file COPYING3. If not see
namespace Rust {
+std::string
+extract_module_path (const AST::AttrVec &inner_attrs,
+ const AST::AttrVec &outer_attrs, const std::string &name)
+{
+ AST::Attribute path_attr = AST::Attribute::create_empty ();
+ for (const auto &attr : inner_attrs)
+ {
+ if (attr.get_path ().as_string () == "path")
+ {
+ path_attr = attr;
+ break;
+ }
+ }
+
+ // Here, we found a path attribute, but it has no associated string. This is
+ // invalid
+ if (!path_attr.is_empty () && !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 name;
+ }
+
+ for (const 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 name;
+
+ // 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 name;
+ }
+
+ 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;
+}
+
} // namespace Rust
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 45f00f5..acab7ff 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -622,7 +622,26 @@ private:
ManagedTokenSource lexer;
// The error list.
std::vector<Error> error_table;
+ // The names of inline modules while parsing.
+ std::vector<std::string> inline_module_stack;
+
+ class InlineModuleStackScope
+ {
+ private:
+ Parser &parser;
+
+ public:
+ InlineModuleStackScope (Parser &parser, std::string name) : parser (parser)
+ {
+ parser.inline_module_stack.emplace_back (std::move (name));
+ }
+ ~InlineModuleStackScope () { parser.inline_module_stack.pop_back (); }
+ };
};
+
+std::string
+extract_module_path (const AST::AttrVec &inner_attrs,
+ const AST::AttrVec &outer_attrs, const std::string &name);
} // namespace Rust
// as now template, include implementations of all methods