diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-27 10:37:29 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-27 10:37:29 +0000 |
commit | a5a0287f529934634c50ce7e187d7d8a676fbef7 (patch) | |
tree | 3db35b7ca1f10df66a244056e36752dd843793bf /gcc | |
parent | 40042ce11fc5d7f62e31be99e82bf6a0db83234a (diff) | |
parent | 602f5e90c2e1392bd02407095052ee2fde470154 (diff) | |
download | gcc-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.cc | 54 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 2 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 2 | ||||
-rw-r--r-- | gcc/rust/lex/rust-lex.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/extern_mod2.rs | 14 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/modules/valid_path.rs | 1 |
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() {} |