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;
+}
