From: Arthur Cohen Date: Wed, 10 Sep 2025 07:07:55 +0000 (+0200) Subject: gccrs: nr: Add prelude field to NRCtx, and fill it upon encountering a prelude. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84fb4681805247a114edc37e9a5667fea29fe0f7;p=thirdparty%2Fgcc.git 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 --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc index 49ac9c821d8..9e0e6a25878 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 9263e19d6d8..2d1ce3117b5 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 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 @@ -676,6 +716,9 @@ public: std::forward (args)...); } + /* If declared with #[prelude_import], the current standard library module */ + tl::optional prelude; + private: /* Map of "usage" nodes which have been resolved to a "definition" node */ std::map 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 b3dafc4800c..ed93911fbab 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 &paths, paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ())); } +static bool +has_prelude_import (const std::vector &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 cc280ec67ff..b5b0c8b1982 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 &&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) {} };