aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-08-27 10:37:29 +0000
committerGitHub <noreply@github.com>2021-08-27 10:37:29 +0000
commita5a0287f529934634c50ce7e187d7d8a676fbef7 (patch)
tree3db35b7ca1f10df66a244056e36752dd843793bf /gcc
parent40042ce11fc5d7f62e31be99e82bf6a0db83234a (diff)
parent602f5e90c2e1392bd02407095052ee2fde470154 (diff)
downloadgcc-a5a0287f529934634c50ce7e187d7d8a676fbef7.zip
gcc-a5a0287f529934634c50ce7e187d7d8a676fbef7.tar.gz
gcc-a5a0287f529934634c50ce7e187d7d8a676fbef7.tar.bz2
Merge #646
646: Resolve module filename from path attribute r=philberty a=CohenArthur Allow for the user to specify the path of a module using the `#[path]` attribute Co-authored-by: CohenArthur <arthur.cohen@epita.fr>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc54
-rw-r--r--gcc/rust/ast/rust-ast.h2
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc2
-rw-r--r--gcc/rust/lex/rust-lex.h6
-rw-r--r--gcc/testsuite/rust/compile/extern_mod2.rs14
-rw-r--r--gcc/testsuite/rust/compile/modules/valid_path.rs1
6 files changed, 72 insertions, 7 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index 6033ce9..c18d4c4 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -4061,17 +4061,59 @@ file_exists (const std::string path)
return access (path.c_str (), F_OK) != -1;
}
-// FIXME: This function should also check if the module has a `path` outer
-// attribute and fetch the path from here in that case, i.e:
-// ```
-// #[path="<dir>/<subdir>/<file>.rs"]
-// mod <mod_name>;
-// ```
+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 = path_attr.get_attr_input ().as_string ();
+
+ // 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_attr.get_attr_input ().as_string ();
+}
+
std::string
Module::get_filename ()
{
rust_assert (kind == Module::ModuleKind::UNLOADED);
+ auto path_string = filename_from_path_attribute (get_outer_attrs ());
+ if (!path_string.empty ())
+ return path_string;
+
// This corresponds to the path of the file 'including' the module. So the
// file that contains the 'mod <file>;' directive
std::string including_fname (outer_filename);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index e376488..1efcc86 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -457,6 +457,8 @@ public:
Location get_locus () const { return locus; }
+ AttrInput &get_attr_input () const { return *attr_input; }
+
/* e.g.:
#![crate_type = "lib"]
#[test]
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 4998dc8..316eb13 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -2039,6 +2039,8 @@ public:
else
{
std::string mod_file = module.get_filename ();
+ if (!mod_file.empty ())
+ rust_debug ("Module filename found: %s", mod_file.c_str ());
}
// strip items if required
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index 1b37a9c..4b2feae 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -35,11 +35,15 @@ public:
RAIIFile &operator= (const RAIIFile &other) = delete;
// have to specify setting file to nullptr, otherwise unintended fclose occurs
- RAIIFile (RAIIFile &&other) : file (other.file) { other.file = nullptr; }
+ RAIIFile (RAIIFile &&other) : file (other.file), filename (other.filename)
+ {
+ other.file = nullptr;
+ }
RAIIFile &operator= (RAIIFile &&other)
{
close ();
file = other.file;
+ filename = other.filename;
other.file = nullptr;
return *this;
diff --git a/gcc/testsuite/rust/compile/extern_mod2.rs b/gcc/testsuite/rust/compile/extern_mod2.rs
new file mode 100644
index 0000000..67c8a13
--- /dev/null
+++ b/gcc/testsuite/rust/compile/extern_mod2.rs
@@ -0,0 +1,14 @@
+#[path = "modules/valid_path.rs"]
+mod not_a_valid_path;
+
+#[path] // { dg-error "path attributes must contain a filename" }
+mod error; // { dg-error "no candidate found for module error" }
+
+// This is "valid", and should only error out when parsing
+// the file
+// FIXME: Add a dg-error directive on the `mod another_error` line once module expansion
+// is added
+#[path = "not_a_valid_file.rs"]
+mod another_error;
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/modules/valid_path.rs b/gcc/testsuite/rust/compile/modules/valid_path.rs
new file mode 100644
index 0000000..6a1519c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/modules/valid_path.rs
@@ -0,0 +1 @@
+fn unused() {}