From 4a0e85cb085fedb541f5a07c65c17509f301f126 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 31 Oct 2021 19:59:37 -0400 Subject: [PATCH] rust: track inline module scopes for module file resolution 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. Fixes: #635 Signed-off-by: Ben Boeckel --- gcc/rust/ast/rust-ast-full-test.cc | 9 ++++++++- gcc/rust/ast/rust-item.h | 12 +++++++++--- gcc/rust/parse/rust-parse-impl.h | 4 +++- gcc/rust/parse/rust-parse.h | 20 ++++++++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index a189d8c029be..534c4dff2c84 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -4069,6 +4069,13 @@ Module::process_file_path () // the concept of `DirOwnernship`, which is based on whether or not the // current file is titled `mod.rs`. + // Handle inline module declarations adding path components. + for (auto const& name : module_scope) + { + current_directory_name.append (name); + current_directory_name.append (file_separator); + } + // First, we search for /.rs bool file_mod_found = file_exists (current_directory_name + expected_file_path); @@ -4093,7 +4100,7 @@ Module::process_file_path () if (no_candidates_found || multiple_candidates_found) return; - module_file = file_mod_found ? expected_file_path + module_file = file_mod_found ? current_directory_name + expected_file_path : current_directory_name + expected_dir_path; } diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 39411f8adedf..f1247ba557ec 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -991,6 +991,8 @@ class Module : public VisItem std::vector inner_attrs; // bool has_items; std::vector> items; + // Names of including inline modules (immediate parent is last in the list) + std::vector 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,13 @@ class Module : public VisItem // Unloaded module constructor Module (Identifier module_name, Visibility visibility, std::vector outer_attrs, Location locus, - std::string outer_filename) + std::string outer_filename, + std::vector 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 ()), - items (std::vector> ()) + items (std::vector> ()), + module_scope (std::move (module_scope)) {} // Loaded module constructor, with items @@ -1035,7 +1039,8 @@ class Module : public VisItem // 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 +1059,7 @@ class Module : public VisItem 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 diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 52aba4f22485..da2e62a4a2a8 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -2105,10 +2105,12 @@ Parser::parse_module (AST::Visibility vis, return std::unique_ptr ( new AST::Module (std::move (name), std::move (vis), std::move (outer_attrs), locus, - lexer.get_filename ())); + lexer.get_filename (), inline_module_stack)); case LEFT_CURLY: { lexer.skip_token (); + InlineModuleStackScope scope (*this, name); + // parse inner attributes AST::AttrVec inner_attrs = parse_inner_attributes (); diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 45f00f570534..1bbcbe613da7 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -622,6 +622,26 @@ template class Parser ManagedTokenSource lexer; // The error list. std::vector error_table; + + class InlineModuleStackScope + { + private: + Parser& parser; + public: + InlineModuleStackScope(Parser& parser, std::string name) + : parser(parser) + { + rust_debug ("pushing module scope for %s", name.c_str ()); + parser.inline_module_stack.emplace_back (std::move (name)); + } + ~InlineModuleStackScope() + { + rust_debug ("popping module scope for %s", parser.inline_module_stack.rbegin ()->c_str ()); + parser.inline_module_stack.pop_back (); + } + }; + // The names of inline modules while parsing. + std::vector inline_module_stack; }; } // namespace Rust