Skip to content

Commit

Permalink
rust: track inline module scopes for module file resolution
Browse files Browse the repository at this point in the history
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: Rust-GCC#635

Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
  • Loading branch information
mathstuf committed Nov 1, 2021
1 parent ca0b06f commit 4a0e85c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
9 changes: 8 additions & 1 deletion gcc/rust/ast/rust-ast-full-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <directory>/<module_name>.rs
bool file_mod_found
= file_exists (current_directory_name + expected_file_path);
Expand All @@ -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;
}

Expand Down
12 changes: 9 additions & 3 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,8 @@ class Module : public VisItem
std::vector<Attribute> inner_attrs;
// bool has_items;
std::vector<std::unique_ptr<Item>> items;
// Names of including inline modules (immediate parent is last in the list)
std::vector<std::string> module_scope;

// Filename the module refers to. Empty string on LOADED modules or if an
// error occured when dealing with UNLOADED modules
Expand All @@ -1013,11 +1015,13 @@ class Module : public VisItem
// Unloaded module constructor
Module (Identifier module_name, Visibility visibility,
std::vector<Attribute> outer_attrs, Location locus,
std::string outer_filename)
std::string outer_filename,
std::vector<std::string> 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<Attribute> ()),
items (std::vector<std::unique_ptr<Item>> ())
items (std::vector<std::unique_ptr<Item>> ()),
module_scope (std::move (module_scope))
{}

// Loaded module constructor, with items
Expand All @@ -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.
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion gcc/rust/parse/rust-parse-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2105,10 +2105,12 @@ Parser<ManagedTokenSource>::parse_module (AST::Visibility vis,
return std::unique_ptr<AST::Module> (
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 ();

Expand Down
20 changes: 20 additions & 0 deletions gcc/rust/parse/rust-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,26 @@ template <typename ManagedTokenSource> class Parser
ManagedTokenSource lexer;
// The error list.
std::vector<Error> 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<std::string> inline_module_stack;
};
} // namespace Rust

Expand Down

0 comments on commit 4a0e85c

Please sign in to comment.