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