https://gcc.gnu.org/g:84fb4681805247a114edc37e9a5667fea29fe0f7
commit r16-6835-g84fb4681805247a114edc37e9a5667fea29fe0f7 Author: Arthur Cohen <[email protected]> Date: Wed Sep 10 09:07:55 2025 +0200 gccrs: nr: Add prelude field to NRCtx, and fill it upon encountering a prelude. 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. Diff: --- gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 8 +++ gcc/rust/resolve/rust-name-resolution-context.h | 59 +++++++++++++++++++--- .../resolve/rust-toplevel-name-resolver-2.0.cc | 13 ++++- gcc/rust/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 49ac9c821d88..9e0e6a258789 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 9263e19d6d85..2d1ce3117b57 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 b3dafc4800c5..ed93911fbab1 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 cc280ec67ff2..b5b0c8b19820 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) {} };
