https://gcc.gnu.org/g:5dbfd003e489475801b9283b532ea47e65525c09
commit r17-5698-g5dbfd003e489475801b9283b532ea47e65525c09 Author: Pierre-Emmanuel Patry <[email protected]> Date: Tue Sep 29 12:22:32 2026 +0200 gccrs: Insert extern crates within extern prelude Extern crates were not inserted within the extern prelude. gcc/rust/ChangeLog: * ast/rust-ast.cc (Crate::inject_extern_crate): Inject extern crates at the beginning of the crate instead of the end. * resolve/rust-forever-stack.h: Add function prototype to insert a crate within the extern prelude. * resolve/rust-forever-stack.hxx: Add function to insert extern crate within extern prelude. * resolve/rust-name-resolution-context.cc (NameResolutionContext::insert_crate_in_prelude): Insert extern crate within all extern prelude namespaces. * resolve/rust-name-resolution-context.h: Add function prototype. * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Inject extern crate within extern prelude during top level nr. Signed-off-by: Pierre-Emmanuel Patry <[email protected]> Diff: --- gcc/rust/ast/rust-ast.cc | 4 +++- gcc/rust/resolve/rust-forever-stack.h | 2 ++ gcc/rust/resolve/rust-forever-stack.hxx | 12 ++++++++++++ gcc/rust/resolve/rust-name-resolution-context.cc | 9 +++++++++ gcc/rust/resolve/rust-name-resolution-context.h | 5 +++++ gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 4 ++++ 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 97f575d3075a..18b4cf4f0581 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -242,7 +242,9 @@ Crate::inject_extern_crate (std::string name) AST::ExternCrate (name, AST::Visibility::create_public (UNKNOWN_LOCATION), {}, UNKNOWN_LOCATION)); auto node_id = extern_crate->get_node_id (); - items.push_back (std::move (extern_crate)); + // We need to insert the new crate at the top of the file as its + // definition must be resolved before any module. + items.insert (items.begin (), std::move (extern_crate)); return node_id; } diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index 33680141ab23..388af2e611fc 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -640,6 +640,8 @@ public: tl::expected<NodeId, DuplicateNameError> insert_variant (Identifier name, NodeId id); + void insert_crate_in_prelude (Identifier crate_name, NodeId crate_id); + /** * Insert a new shadowable definition in the innermost `Rib` in this stack * diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 698bb1e8a2bb..741a86fd83fc 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -203,6 +203,18 @@ ForeverStack<Namespace::Values>::insert_variant (Identifier name, NodeId node) Rib::Definition::NonShadowable (node, true)); } +template <Namespace N> +void +ForeverStack<N>::insert_crate_in_prelude (Identifier crate_name, NodeId id) +{ + auto &extern_prelude_rib = extern_prelude.rib (N); + auto inner = insert_inner (extern_prelude_rib, crate_name, + Rib::Definition::NonShadowable (id)); + + if (inner) + map_usage (Usage (inner.value ()), Definition (id)); +} + template <Namespace N> inline void ForeverStack<N>::insert_lang_prelude (Identifier name, NodeId id) diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc b/gcc/rust/resolve/rust-name-resolution-context.cc index 1817627600ce..318cf2ca517f 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.cc +++ b/gcc/rust/resolve/rust-name-resolution-context.cc @@ -276,6 +276,15 @@ NameResolutionContext::insert_globbed (Identifier name, NodeId id, Namespace ns) } } +void +NameResolutionContext::insert_crate_in_prelude (Identifier name, NodeId id) +{ + values.insert_crate_in_prelude (name, id); + types.insert_crate_in_prelude (name, id); + macros.insert_crate_in_prelude (name, id); + labels.insert_crate_in_prelude (name, id); +} + // TODO: Maybe this should take a NamespacedDefinition as argument? void NameResolutionContext::map_usage (Usage usage, Definition definition, diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index 8311d6dd85b8..f9a277ce11a4 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -500,6 +500,11 @@ public: tl::expected<NodeId, DuplicateNameError> insert_globbed (Identifier name, NodeId id, Namespace ns); + // Crate are supposed to be injected before any other module because we want + // the name collision error to be reported on the offending module which has a + // real source location, this function should therefore not fail. + void insert_crate_in_prelude (Identifier name, NodeId id); + /** * Run a lambda in a "scoped" context, meaning that a new `Rib` will be pushed * before executing the lambda and then popped. This is useful for all kinds 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 db973be1701d..cc24439c8779 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc @@ -146,6 +146,10 @@ TopLevel::visit (AST::ExternCrate &crate) insert_or_error_out (name, crate, Namespace::Types); DefaultResolver::visit (crate); + + // Insert the crate within the extern prelude only after the scope has been + // created + ctx.insert_crate_in_prelude (name, crate.get_node_id ()); } void
