diff options
author | CohenArthur <arthur.cohen@epita.fr> | 2021-09-10 10:40:11 +0200 |
---|---|---|
committer | CohenArthur <arthur.cohen@epita.fr> | 2021-09-10 10:53:16 +0200 |
commit | d5b259a3fd40ab9ec4d9f76b50d77eb595067f81 (patch) | |
tree | cae07ec30aefc20d4b6fd3c4cb512a53ee624629 | |
parent | e93393d007276a3335839741f45865bc05787869 (diff) | |
download | gcc-d5b259a3fd40ab9ec4d9f76b50d77eb595067f81.zip gcc-d5b259a3fd40ab9ec4d9f76b50d77eb595067f81.tar.gz gcc-d5b259a3fd40ab9ec4d9f76b50d77eb595067f81.tar.bz2 |
modules: Fix usage of path attributes and early returns
path attributes were used wrongly in two ways:
1/ The attribute's value would still contain extra data such as an equal
sign and whitespaces, which need to be discarded in order to fetch the
proper file path.
2/ #[path]s are relative to the directory where the current source file
is located. So we actually need to compute them later on down the line,
once the including directory has been figured out.
Another issue was that in the case that no candidates were found, or too
many were founds, the function `process_file_path` would still return
"successfully" despite erroring out. This causes the function to return
early and thus not assign any string to the `module_file` member.
We also have the ability to emit an error for the module's location,
which looks better for the user, instead of using a new `Location()`
like the session manager does (because it can't do otherwise)
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 28 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/extern_mod2.rs | 19 |
2 files changed, 34 insertions, 13 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 9b11498..b1572e1 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -4010,7 +4010,15 @@ filename_from_path_attribute (std::vector<Attribute> &outer_attrs) return ""; } - auto path = path_attr.get_attr_input ().as_string (); + 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 @@ -4022,7 +4030,7 @@ filename_from_path_attribute (std::vector<Attribute> &outer_attrs) path.replace ('/', '\\'); #endif /* HAVE_DOS_BASED_FILE_SYSTEM */ - return path_attr.get_attr_input ().as_string (); + return path; } void @@ -4031,10 +4039,6 @@ Module::process_file_path () rust_assert (kind == Module::ModuleKind::UNLOADED); rust_assert (module_file.empty ()); - auto path_string = filename_from_path_attribute (get_outer_attrs ()); - if (!path_string.empty ()) - return; - // 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); @@ -4053,6 +4057,13 @@ Module::process_file_path () current_directory_name = including_fname.substr (0, dir_slash_pos) + file_separator; + auto path_string = filename_from_path_attribute (get_outer_attrs ()); + if (!path_string.empty ()) + { + module_file = current_directory_name + path_string; + return; + } + // FIXME: We also have to search for // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via // the concept of `DirOwnernship`, which is based on whether or not the @@ -4079,6 +4090,9 @@ Module::process_file_path () rust_error_at (locus, "no candidate found for module %s", module_name.c_str ()); + if (no_candidates_found || multiple_candidates_found) + return; + module_file = file_mod_found ? expected_file_path : current_directory_name + expected_dir_path; } @@ -4098,7 +4112,7 @@ Module::load_items () if (file_wrap.get_raw () == nullptr) { - rust_error_at (Location (), "cannot open module file %s: %m", + rust_error_at (get_locus (), "cannot open module file %s: %m", module_file.c_str ()); return; } diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs index f3379e3..4984d5d 100644 --- a/gcc/testsuite/rust/compile/torture/extern_mod2.rs +++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs @@ -3,14 +3,21 @@ #[path = "modules/valid_path.rs"] mod not_a_valid_path; -// #[path] -// FIXME: This is wrong -// mod error; +#[path ="modules/valid_path.rs"] +mod path_without_extra_equal; + +#[path= "modules/valid_path.rs"] +mod no_leading_equal; + +#[path = "modules/valid_path.rs"] +mod extra_spaces; + +#[path] // { dg-error "path attributes must contain a filename" } +mod error; // { dg-error "no candidate found" } // This is "valid", and should only error out when parsing // the file -// FIXME: Fix path attribute expanding -// #[path = "not_a_valid_file.rs"] -// mod another_error; +#[path = "not_a_valid_file.rs"] +mod another_error; // { dg-error "No such file or directory" } fn main() {} |