From: Arthur Cohen <[email protected]>
gcc/rust/ChangeLog:
* resolve/rust-early-name-resolver-2.0.cc
(Early::finalize_glob_import): Save prelude
if we find one.
* resolve/rust-name-resolution-context.h: Add field.
* resolve/rust-toplevel-name-resolver-2.0.cc (has_prelude_import): New
function.
(TopLevel::visit): Create a prelude glob import if necessary.
* resolve/rust-toplevel-name-resolver-2.0.h: Allow glob imports to be
prelude imports.
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/3c35188069614f2b01e2c8443ece0024595c4ca4
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4149
.../resolve/rust-early-name-resolver-2.0.cc | 8 +++
.../resolve/rust-name-resolution-context.h | 59 ++++++++++++++++---
.../rust-toplevel-name-resolver-2.0.cc | 13 +++-
.../resolve/rust-toplevel-name-resolver-2.0.h | 18 ++++--
4 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 49ac9c821..9e0e6a258 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -411,6 +411,14 @@ Early::finalize_glob_import (NameResolutionContext &ctx,
rust_assert (container);
+ if (mapping.import_kind.is_prelude)
+ {
+ rust_assert (container.value ()->get_item_kind ()
+ == AST::Item::Kind::Module);
+
+ ctx.prelude = container.value ()->get_node_id ();
+ }
+
GlobbingVisitor (ctx).go (container.value ());
}
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h
b/gcc/rust/resolve/rust-name-resolution-context.h
index 9263e19d6..2d1ce3117 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -560,23 +560,63 @@ public:
if (resolved_nodes.find (Usage (seg_id)) == resolved_nodes.end ())
map_usage (Usage (seg_id), Definition (id));
};
+
+ tl::optional<Rib::Definition> resolved = tl::nullopt;
+
switch (ns)
{
case Namespace::Values:
- return values.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = values.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
case Namespace::Types:
- return types.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = types.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
case Namespace::Macros:
- return macros.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = macros.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
case Namespace::Labels:
- return labels.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = labels.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
default:
rust_unreachable ();
}
+
+ // If it fails, switch to std prelude resolution if it exists
+ if (prelude && !resolved)
+ {
+ // TODO: Factor this with the above
+ switch (ns)
+ {
+ case Namespace::Values:
+ return values.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ case Namespace::Types:
+ return types.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ case Namespace::Macros:
+ return macros.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ case Namespace::Labels:
+ return labels.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ default:
+ rust_unreachable ();
+ }
+ }
+
+ return resolved;
}
template <typename S, typename... Args>
@@ -676,6 +716,9 @@ public:
std::forward<Args> (args)...);
}
+ /* If declared with #[prelude_import], the current standard library module */
+ tl::optional<NodeId> prelude;
+
private:
/* Map of "usage" nodes which have been resolved to a "definition" node */
std::map<Usage, Definition> resolved_nodes;
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index b3dafc480..ed93911fb 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -496,6 +496,16 @@ flatten_glob (const AST::UseTreeGlob &glob,
std::vector<AST::SimplePath> &paths,
paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ()));
}
+static bool
+has_prelude_import (const std::vector<AST::Attribute> &attributes)
+{
+ for (const auto &attr : attributes)
+ if (attr.get_path ().as_string () == "prelude_import")
+ return true;
+
+ return false;
+}
+
void
TopLevel::visit (AST::UseDeclaration &use)
{
@@ -523,7 +533,8 @@ TopLevel::visit (AST::UseDeclaration &use)
for (auto &&glob : glob_path)
imports.emplace_back (
- ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib));
+ ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
+ has_prelude_import (use.get_outer_attrs ())));
for (auto &&rebind : rebind_path)
imports.emplace_back (
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index cc280ec67..b5b0c8b19 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -67,10 +67,10 @@ public:
} kind;
static ImportKind Glob (AST::SimplePath &&to_resolve, Rib &values_rib,
- Rib &types_rib, Rib ¯os_rib)
+ Rib &types_rib, Rib ¯os_rib, bool is_prelude)
{
return ImportKind (Kind::Glob, std::move (to_resolve), values_rib,
- types_rib, macros_rib);
+ types_rib, macros_rib, is_prelude);
}
static ImportKind Simple (AST::SimplePath &&to_resolve, Rib &values_rib,
@@ -84,8 +84,10 @@ public:
AST::UseTreeRebind &&rebind, Rib &values_rib,
Rib &types_rib, Rib ¯os_rib)
{
- return ImportKind (Kind::Rebind, std::move (to_resolve), values_rib,
- types_rib, macros_rib, std::move (rebind));
+ return ImportKind (
+ Kind::Rebind, std::move (to_resolve), values_rib, types_rib, macros_rib,
+ false /* is_prelude: rebind imports can never be preludes */,
+ std::move (rebind));
}
// The path for `Early` to resolve.
@@ -98,13 +100,17 @@ public:
Rib &types_rib;
Rib ¯os_rib;
+ // Can only be true if we are dealing with a glob import with the
+ // #[prelude_import] attribute
+ bool is_prelude = false;
+
private:
ImportKind (Kind kind, AST::SimplePath &&to_resolve, Rib &values_rib,
- Rib &types_rib, Rib ¯os_rib,
+ Rib &types_rib, Rib ¯os_rib, bool is_prelude = false,
tl::optional<AST::UseTreeRebind> &&rebind = tl::nullopt)
: kind (kind), to_resolve (std::move (to_resolve)),
rebind (std::move (rebind)), values_rib (values_rib),
- types_rib (types_rib), macros_rib (macros_rib)
+ types_rib (types_rib), macros_rib (macros_rib), is_prelude (is_prelude)
{}
};
base-commit: 055467b59016b87e1652eb5d3190389bd2f72af5
--
2.52.0