From: Pierre-Emmanuel Patry <[email protected]>

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]>
---
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/db9ca74be59e4e22f0ecdee4889c6e4ba866986c

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4758

 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 97f575d30..18b4cf4f0 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 33680141a..388af2e61 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 698bb1e8a..741a86fd8 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 181762760..318cf2ca5 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 8311d6dd8..f9a277ce1 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 db973be17..cc24439c8 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
-- 
2.55.0

Reply via email to