[gccrs,COMMIT] gccrs: Make `extern crate self` resolve to current crate

Message ID 20260603120621.3103-1-gerris.rs@gmail.com
State Committed
Headers
Series [gccrs,COMMIT] gccrs: Make `extern crate self` resolve to current crate |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

gerris.rs@gmail.com June 3, 2026, 12:06 p.m. UTC
  From: Yap Zhi Heng <yapzhhg@gmail.com>

gcc/rust/ChangeLog:

	* resolve/rust-default-resolver.h (DefaultResolver): Add new visited_crates
	member for recursion protection.
	* resolve/rust-default-resolver.cc (DefaultResolver::visit(ExternCrate)):
	Make references of `self` resolve to the current crate.

Signed-off-by: Yap Zhi Heng <yapzhhg@gmail.com>
---
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/367269fd522a923bd1e8de3f58f7228d6f45bc35

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/4570

 gcc/rust/resolve/rust-default-resolver.cc       | 15 +++++++++++++--
 gcc/rust/resolve/rust-default-resolver.h        |  3 +++
 gcc/testsuite/rust/compile/extern_crate_self.rs |  6 ++++++
 3 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/extern_crate_self.rs


base-commit: 16a37ba94b143f0f1e9987d0380fca1ae309406f
  

Patch

diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
index 098c81e9b..3b724c9e6 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -31,6 +31,11 @@  namespace Resolver2_0 {
 void
 DefaultResolver::visit (AST::Crate &crate)
 {
+  // Guard against infinite recursion: `extern crate self;` resolves to the
+  // current crate, causing visit(AST::Crate) to call itself infinitely.
+  if (!visited_crates.insert (crate.get_node_id ()).second)
+    return;
+
   auto inner_fn = [this, &crate] () { AST::DefaultASTVisitor::visit (crate); };
 
   auto &mappings = Analysis::Mappings::get ();
@@ -444,7 +449,11 @@  void
 DefaultResolver::visit (AST::ExternCrate &crate)
 {
   auto &mappings = Analysis::Mappings::get ();
-  auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
+  tl::optional<CrateNum> num_opt;
+  if (crate.get_referenced_crate () == "self")
+    num_opt = mappings.get_current_crate ();
+  else
+    num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
 
   if (!num_opt)
     {
@@ -462,7 +471,9 @@  DefaultResolver::visit (AST::ExternCrate &crate)
 
   auto sub_visitor_2 = [&] () {
     ctx.canonical_ctx.scope_crate (referenced_crate.get_node_id (),
-				   crate.get_referenced_crate (),
+				   crate.get_referenced_crate () == "self"
+				     ? mappings.get_current_crate_name ()
+				     : crate.get_referenced_crate (),
 				   std::move (sub_visitor_1));
   };
 
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
index 55ae2b15f..d3e4e17f8 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -20,6 +20,7 @@ 
 #ifndef RUST_AST_DEFAULT_RESOLVER_H
 #define RUST_AST_DEFAULT_RESOLVER_H
 
+#include "rust-system.h"
 #include "rust-ast-visitor.h"
 #include "rust-name-resolution-context.h"
 
@@ -89,6 +90,8 @@  protected:
   DefaultResolver (NameResolutionContext &ctx) : ctx (ctx) {}
 
   NameResolutionContext &ctx;
+
+  std::set<NodeId> visited_crates;
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/testsuite/rust/compile/extern_crate_self.rs b/gcc/testsuite/rust/compile/extern_crate_self.rs
new file mode 100644
index 000000000..920e52f1e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/extern_crate_self.rs
@@ -0,0 +1,6 @@ 
+#![feature(no_core)]
+#![no_core]
+
+fn main() {
+    extern crate self as my_crate;
+}