Skip to content

Commit ba67c52

Browse files
committed
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. Signed-off-by: Ben Boeckel <[email protected]>
1 parent 1be610a commit ba67c52

File tree

8 files changed

+56
-11
lines changed

8 files changed

+56
-11
lines changed

gcc/rust/ast/rust-ast-full-test.cc

+12-6
Original file line numberDiff line numberDiff line change
@@ -4069,13 +4069,20 @@ Module::process_file_path ()
40694069
// the concept of `DirOwnernship`, which is based on whether or not the
40704070
// current file is titled `mod.rs`.
40714071

4072+
// Handle inline module declarations adding path components.
4073+
for (auto const &name : module_scope)
4074+
{
4075+
current_directory_name.append (name);
4076+
current_directory_name.append (file_separator);
4077+
}
4078+
40724079
// First, we search for <directory>/<module_name>.rs
4073-
bool file_mod_found
4074-
= file_exists (current_directory_name + expected_file_path);
4080+
std::string file_mod_path = current_directory_name + expected_file_path;
4081+
bool file_mod_found = file_exists (file_mod_path);
40754082

40764083
// Then, search for <directory>/<module_name>/mod.rs
4077-
current_directory_name += module_name + file_separator;
4078-
bool dir_mod_found = file_exists (current_directory_name + expected_dir_path);
4084+
std::string dir_mod_path = current_directory_name + module_name + file_separator + expected_dir_path;
4085+
bool dir_mod_found = file_exists (dir_mod_path);
40794086

40804087
bool multiple_candidates_found = file_mod_found && dir_mod_found;
40814088
bool no_candidates_found = !file_mod_found && !dir_mod_found;
@@ -4093,8 +4100,7 @@ Module::process_file_path ()
40934100
if (no_candidates_found || multiple_candidates_found)
40944101
return;
40954102

4096-
module_file = file_mod_found ? expected_file_path
4097-
: current_directory_name + expected_dir_path;
4103+
module_file = std::move (file_mod_found ? file_mod_path : dir_mod_path);
40984104
}
40994105

41004106
void

gcc/rust/ast/rust-item.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,8 @@ class Module : public VisItem
991991
std::vector<Attribute> inner_attrs;
992992
// bool has_items;
993993
std::vector<std::unique_ptr<Item>> items;
994+
// Names of including inline modules (immediate parent is last in the list)
995+
std::vector<std::string> module_scope;
994996

995997
// Filename the module refers to. Empty string on LOADED modules or if an
996998
// error occured when dealing with UNLOADED modules
@@ -1013,11 +1015,12 @@ class Module : public VisItem
10131015
// Unloaded module constructor
10141016
Module (Identifier module_name, Visibility visibility,
10151017
std::vector<Attribute> outer_attrs, Location locus,
1016-
std::string outer_filename)
1018+
std::string outer_filename, std::vector<std::string> module_scope)
10171019
: VisItem (std::move (visibility), std::move (outer_attrs)),
10181020
module_name (module_name), locus (locus), kind (ModuleKind::UNLOADED),
10191021
outer_filename (outer_filename), inner_attrs (std::vector<Attribute> ()),
1020-
items (std::vector<std::unique_ptr<Item>> ())
1022+
items (std::vector<std::unique_ptr<Item>> ()),
1023+
module_scope (std::move (module_scope))
10211024
{}
10221025

10231026
// Loaded module constructor, with items
@@ -1035,7 +1038,8 @@ class Module : public VisItem
10351038
// Copy constructor with vector clone
10361039
Module (Module const &other)
10371040
: VisItem (other), module_name (other.module_name), locus (other.locus),
1038-
kind (other.kind), inner_attrs (other.inner_attrs)
1041+
kind (other.kind), inner_attrs (other.inner_attrs),
1042+
module_scope (other.module_scope)
10391043
{
10401044
// We need to check whether we are copying a loaded module or an unloaded
10411045
// one. In the second case, clear the `items` vector.
@@ -1054,6 +1058,7 @@ class Module : public VisItem
10541058
locus = other.locus;
10551059
kind = other.kind;
10561060
inner_attrs = other.inner_attrs;
1061+
module_scope = other.module_scope;
10571062

10581063
// Likewise, we need to clear the `items` vector in case the other module is
10591064
// unloaded

gcc/rust/parse/rust-parse-impl.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -2104,11 +2104,13 @@ Parser<ManagedTokenSource>::parse_module (AST::Visibility vis,
21042104
// Construct an external module
21052105
return std::unique_ptr<AST::Module> (
21062106
new AST::Module (std::move (name), std::move (vis),
2107-
std::move (outer_attrs), locus,
2108-
lexer.get_filename ()));
2107+
std::move (outer_attrs), locus, lexer.get_filename (),
2108+
inline_module_stack));
21092109
case LEFT_CURLY: {
21102110
lexer.skip_token ();
21112111

2112+
InlineModuleStackScope scope (*this, name);
2113+
21122114
// parse inner attributes
21132115
AST::AttrVec inner_attrs = parse_inner_attributes ();
21142116

gcc/rust/parse/rust-parse.h

+15
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,21 @@ template <typename ManagedTokenSource> class Parser
622622
ManagedTokenSource lexer;
623623
// The error list.
624624
std::vector<Error> error_table;
625+
626+
class InlineModuleStackScope
627+
{
628+
private:
629+
Parser &parser;
630+
631+
public:
632+
InlineModuleStackScope (Parser &parser, std::string name) : parser (parser)
633+
{
634+
parser.inline_module_stack.emplace_back (std::move (name));
635+
}
636+
~InlineModuleStackScope () { parser.inline_module_stack.pop_back (); }
637+
};
638+
// The names of inline modules while parsing.
639+
std::vector<std::string> inline_module_stack;
625640
};
626641
} // namespace Rust
627642

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod other;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn f() -> u32 {
2+
2
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn f() -> u32 {
2+
1
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// { dg-additional-options "-w" }
2+
3+
mod missing_middle {
4+
mod sub;
5+
}
6+
7+
mod with_explicit_path {
8+
#[path = "missing_middle/explicit.not.rs"]
9+
mod explicit;
10+
}

0 commit comments

Comments
 (0)