diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index 778553e5b37..b17ac954167 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -22,6 +22,8 @@
 #include "rust-compile-base.h"
 #include "rust-compile-intrinsic.h"
 #include "rust-compile-type.h"
+#include "rust-diagnostics.h"
+#include "rust-hir-full-decls.h"
 
 namespace Rust {
 namespace Compile {
@@ -152,6 +154,11 @@ public:
     reference = address_expression (fndecl, ref_locus);
   }
 
+  void visit (HIR::ExternalTypeItem &type) override
+  {
+    rust_sorry_at (type.get_locus (), "extern types are not supported yet");
+  }
+
 private:
   CompileExternItem (Context *ctx, TyTy::BaseType *concrete,
 		     location_t ref_locus)
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index d6390392d7f..6a990e25c43 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -189,6 +189,7 @@ protected:
   void visit (HIR::ImplBlock &impl) override { rust_unreachable (); }
   void visit (HIR::ExternalStaticItem &item) override { rust_unreachable (); }
   void visit (HIR::ExternalFunctionItem &item) override { rust_unreachable (); }
+  void visit (HIR::ExternalTypeItem &item) override { rust_unreachable (); }
   void visit (HIR::ExternBlock &block) override { rust_unreachable (); }
   void visit (HIR::LiteralPattern &pattern) override { rust_unreachable (); }
   void visit (HIR::IdentifierPattern &pattern) override { rust_unreachable (); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index b19bfdf855e..18f2f5e11d1 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -155,6 +155,7 @@ public:
   void visit (HIR::ImplBlock &impl) override {}
   void visit (HIR::ExternalStaticItem &item) override {}
   void visit (HIR::ExternalFunctionItem &item) override {}
+  void visit (HIR::ExternalTypeItem &item) override {}
   void visit (HIR::ExternBlock &block) override {}
   void visit (HIR::LiteralPattern &pattern) override {}
   void visit (HIR::IdentifierPattern &pattern) override {}
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index aaf8fc0c3f6..886ae18d314 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -714,6 +714,10 @@ void
 ConstChecker::visit (ExternalFunctionItem &)
 {}
 
+void
+ConstChecker::visit (ExternalTypeItem &)
+{}
+
 void
 ConstChecker::visit (ExternBlock &block)
 {
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index a645da8b7c0..a9bf087a993 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -162,6 +162,7 @@ private:
   virtual void visit (ImplBlock &impl) override;
   virtual void visit (ExternalStaticItem &item) override;
   virtual void visit (ExternalFunctionItem &item) override;
+  virtual void visit (ExternalTypeItem &item) override;
   virtual void visit (ExternBlock &block) override;
   virtual void visit (LiteralPattern &pattern) override;
   virtual void visit (IdentifierPattern &pattern) override;
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 4bad20b58d3..b8c25f9a592 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -783,6 +783,10 @@ void
 UnsafeChecker::visit (ExternalFunctionItem &)
 {}
 
+void
+UnsafeChecker::visit (ExternalTypeItem &)
+{}
+
 void
 UnsafeChecker::visit (ExternBlock &block)
 {
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index fee4d62fe43..27659f5141a 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -144,6 +144,7 @@ private:
   virtual void visit (ImplBlock &impl) override;
   virtual void visit (ExternalStaticItem &item) override;
   virtual void visit (ExternalFunctionItem &item) override;
+  virtual void visit (ExternalTypeItem &item) override;
   virtual void visit (ExternBlock &block) override;
   virtual void visit (LiteralPattern &pattern) override;
   virtual void visit (IdentifierPattern &pattern) override;
diff --git a/gcc/rust/hir/rust-ast-lower-extern.h b/gcc/rust/hir/rust-ast-lower-extern.h
index cee480bb9ed..e495b16632d 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -114,6 +114,11 @@ public:
       function.get_outer_attrs (), function.get_locus ());
   }
 
+  void visit (AST::ExternalTypeItem &type) override
+  {
+    rust_sorry_at (type.get_locus (), "extern types are not implemented yet");
+  }
+
 private:
   ASTLoweringExternItem () : translated (nullptr) {}
 
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 2fdf769c0de..38c2db1d6cd 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1999,6 +1999,16 @@ Dump::visit (ExternalFunctionItem &e)
   end ("ExternalFunctionItem");
 }
 
+void
+Dump::visit (ExternalTypeItem &e)
+{
+  begin ("ExternalTypeItem");
+
+  do_externalitem (e);
+
+  end ("ExternalTypeItem");
+}
+
 void
 Dump::visit (ExternBlock &e)
 {
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index a48394a4bca..6363eb4c604 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -201,6 +201,7 @@ private:
 
   virtual void visit (ExternalStaticItem &) override;
   virtual void visit (ExternalFunctionItem &) override;
+  virtual void visit (ExternalTypeItem &) override;
   virtual void visit (ExternBlock &) override;
 
   virtual void visit (LiteralPattern &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 96293ce8314..d01535e75d3 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -177,6 +177,7 @@ class ExternalItem;
 class ExternalStaticItem;
 struct NamedFunctionParam;
 class ExternalFunctionItem;
+class ExternalTypeItem;
 class ExternBlock;
 
 // rust-pattern.h
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 1d067fca5be..40093a2ad93 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2859,6 +2859,7 @@ public:
   {
     Static,
     Function,
+    Type,
   };
 
   virtual ~ExternalItem () {}
@@ -3084,11 +3085,13 @@ public:
 
   // Copy constructor with clone
   ExternalFunctionItem (ExternalFunctionItem const &other)
-    : ExternalItem (other), return_type (other.return_type->clone_type ()),
-      where_clause (other.where_clause),
+    : ExternalItem (other), where_clause (other.where_clause),
       function_params (other.function_params),
       has_variadics (other.has_variadics)
   {
+    if (other.return_type)
+      return_type = other.return_type->clone_type ();
+
     generic_params.reserve (other.generic_params.size ());
     for (const auto &e : other.generic_params)
       generic_params.push_back (e->clone_generic_param ());
@@ -3098,11 +3101,14 @@ public:
   ExternalFunctionItem &operator= (ExternalFunctionItem const &other)
   {
     ExternalItem::operator= (other);
-    return_type = other.return_type->clone_type ();
+
     where_clause = other.where_clause;
     function_params = other.function_params;
     has_variadics = other.has_variadics;
 
+    if (other.return_type)
+      return_type = other.return_type->clone_type ();
+
     generic_params.reserve (other.generic_params.size ());
     for (const auto &e : other.generic_params)
       generic_params.push_back (e->clone_generic_param ());
@@ -3144,6 +3150,33 @@ protected:
   }
 };
 
+class ExternalTypeItem : public ExternalItem
+{
+  ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
+		    Visibility vis, AST::AttrVec outer_attrs, location_t locus)
+    : ExternalItem (std::move (mappings), std::move (item_name),
+		    std::move (vis), std::move (outer_attrs), locus)
+  {}
+
+  ExternalTypeItem (ExternalTypeItem const &other) : ExternalItem (other) {}
+
+  ExternalTypeItem (ExternalTypeItem &&other) = default;
+  ExternalTypeItem &operator= (ExternalTypeItem &&other) = default;
+
+  std::string as_string () const override;
+
+  void accept_vis (HIRFullVisitor &vis) override;
+  void accept_vis (HIRExternalItemVisitor &vis) override;
+
+  ExternKind get_extern_kind () override { return ExternKind::Type; }
+
+protected:
+  ExternalTypeItem *clone_external_item_impl () const override
+  {
+    return new ExternalTypeItem (*this);
+  }
+};
+
 // An extern block HIR node
 class ExternBlock : public VisItem, public WithInnerAttrs
 {
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 4e7a97bd972..ae9d23f2e00 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -114,6 +114,7 @@ public:
   virtual void visit (ImplBlock &impl) = 0;
   virtual void visit (ExternalStaticItem &item) = 0;
   virtual void visit (ExternalFunctionItem &item) = 0;
+  virtual void visit (ExternalTypeItem &item) = 0;
   virtual void visit (ExternBlock &block) = 0;
   virtual void visit (LiteralPattern &pattern) = 0;
   virtual void visit (IdentifierPattern &pattern) = 0;
@@ -255,6 +256,7 @@ public:
 
   virtual void visit (ExternalStaticItem &) override {}
   virtual void visit (ExternalFunctionItem &) override {}
+  virtual void visit (ExternalTypeItem &) override {}
   virtual void visit (ExternBlock &) override {}
 
   virtual void visit (LiteralPattern &) override {}
@@ -306,6 +308,7 @@ class HIRExternalItemVisitor
 public:
   virtual void visit (ExternalStaticItem &item) = 0;
   virtual void visit (ExternalFunctionItem &item) = 0;
+  virtual void visit (ExternalTypeItem &item) = 0;
 };
 
 class HIRTraitItemVisitor
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index fb0a9c388ae..3eb8838eb9d 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -3256,6 +3256,19 @@ ExternalFunctionItem::as_string () const
   return str;
 }
 
+std::string
+ExternalTypeItem::as_string () const
+{
+  std::string str = ExternalItem::as_string ();
+
+  str += "type ";
+
+  // add name
+  str += get_item_name ().as_string ();
+
+  return str;
+}
+
 std::string
 NamedFunctionParam::as_string () const
 {
@@ -4272,6 +4285,12 @@ ExternalFunctionItem::accept_vis (HIRFullVisitor &vis)
   vis.visit (*this);
 }
 
+void
+ExternalTypeItem::accept_vis (HIRFullVisitor &vis)
+{
+  vis.visit (*this);
+}
+
 void
 ExternBlock::accept_vis (HIRFullVisitor &vis)
 {
@@ -4542,6 +4561,12 @@ ExternalFunctionItem::accept_vis (HIRExternalItemVisitor &vis)
   vis.visit (*this);
 }
 
+void
+ExternalTypeItem::accept_vis (HIRExternalItemVisitor &vis)
+{
+  vis.visit (*this);
+}
+
 void
 ExternalStaticItem::accept_vis (HIRExternalItemVisitor &vis)
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 6b4141a4270..8a9a3f35a32 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-hir-type-check-implitem.h"
+#include "rust-diagnostics.h"
 #include "rust-hir-type-check-base.h"
 #include "rust-hir-type-check-type.h"
 #include "rust-hir-type-check-expr.h"
@@ -183,6 +184,134 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
   resolved = fnType;
 }
 
+void
+TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
+{
+  rust_sorry_at (type.get_locus (), "extern types are not supported yet");
+  //  auto binder_pin = context->push_clean_lifetime_resolver ();
+
+  //  std::vector<TyTy::SubstitutionParamMapping> substitutions;
+  //  if (function.has_generics ())
+  //    {
+  //      for (auto &generic_param : function.get_generic_params ())
+  // {
+  //   switch (generic_param.get ()->get_kind ())
+  //     {
+  //     case HIR::GenericParam::GenericKind::LIFETIME:
+  //       context->intern_and_insert_lifetime (
+  // 	static_cast<HIR::LifetimeParam &> (*generic_param)
+  // 	  .get_lifetime ());
+  //       // TODO: handle bounds
+  //       break;
+  //     case HIR::GenericParam::GenericKind::CONST:
+  //       // FIXME: Skipping Lifetime and Const completely until better
+  //       // handling.
+  //       break;
+
+  //       case HIR::GenericParam::GenericKind::TYPE: {
+  // 	auto param_type
+  // 	  = TypeResolveGenericParam::Resolve (generic_param.get ());
+  // 	context->insert_type (generic_param->get_mappings (),
+  // 			      param_type);
+
+  // 	substitutions.push_back (TyTy::SubstitutionParamMapping (
+  // 	  static_cast<HIR::TypeParam &> (*generic_param), param_type));
+  //       }
+  //       break;
+  //     }
+  // }
+  //    }
+
+  //  TyTy::RegionConstraints region_constraints;
+  //  if (function.has_where_clause ())
+  //    {
+  //      for (auto &where_clause_item : function.get_where_clause ().get_items
+  //      ())
+  // {
+  //   ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+  // 				   region_constraints);
+  // }
+  //    }
+
+  //  TyTy::BaseType *ret_type = nullptr;
+  //  if (!function.has_return_type ())
+  //    ret_type
+  //      = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid
+  //      ());
+  //  else
+  //    {
+  //      auto resolved
+  // = TypeCheckType::Resolve (function.get_return_type ().get ());
+  //      if (resolved == nullptr)
+  // {
+  //   rust_error_at (function.get_locus (),
+  // 		 "failed to resolve return type");
+  //   return;
+  // }
+
+  //      ret_type = resolved->clone ();
+  //      ret_type->set_ref (
+  // function.get_return_type ()->get_mappings ().get_hirid ());
+  //    }
+
+  //  std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
+  //  for (auto &param : function.get_function_params ())
+  //    {
+  //      // get the name as well required for later on
+  //      auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
+
+  //      // these are implicit mappings and not used
+  //      auto crate_num = mappings->get_current_crate ();
+  //      Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id
+  //      (),
+  // 			     mappings->get_next_hir_id (crate_num),
+  // 			     UNKNOWN_LOCAL_DEFID);
+
+  //      HIR::IdentifierPattern *param_pattern
+  // = new HIR::IdentifierPattern (mapping, param.get_param_name (),
+  // 			      UNDEF_LOCATION, false, Mutability::Imm,
+  // 			      std::unique_ptr<HIR::Pattern> (nullptr));
+
+  //      params.push_back (
+  // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
+  // 					     param_tyty));
+
+  //      context->insert_type (param.get_mappings (), param_tyty);
+
+  //      // FIXME do we need error checking for patterns here?
+  //      // see https://github.com/Rust-GCC/gccrs/issues/995
+  //    }
+
+  //  uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
+  //  if (function.is_variadic ())
+  //    {
+  //      flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
+  //      if (parent.get_abi () != Rust::ABI::C)
+  // {
+  //   rust_error_at (
+  //     function.get_locus (), ErrorCode::E0045,
+  //     "C-variadic function must have C or cdecl calling convention");
+  // }
+  //    }
+
+  //  RustIdent ident{
+  //    CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
+  // 		    function.get_item_name ().as_string ()),
+  //    function.get_locus ()};
+
+  //  auto fnType = new TyTy::FnType (
+  //    function.get_mappings ().get_hirid (),
+  //    function.get_mappings ().get_defid (),
+  //    function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
+  //    std::move (params), ret_type, std::move (substitutions),
+  //    TyTy::SubstitutionArgumentMappings::empty (
+  //      context->get_lifetime_resolver ().get_num_bound_regions ()),
+  //    region_constraints);
+
+  //  context->insert_type (function.get_mappings (), fnType);
+  //  resolved = fnType;
+}
+
 TypeCheckImplItem::TypeCheckImplItem (
   HIR::ImplBlock *parent, TyTy::BaseType *self,
   std::vector<TyTy::SubstitutionParamMapping> substitutions)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 541b7280c1b..64eb208d15d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -34,6 +34,7 @@ public:
 
   void visit (HIR::ExternalStaticItem &item) override;
   void visit (HIR::ExternalFunctionItem &function) override;
+  void visit (HIR::ExternalTypeItem &type) override;
 
 private:
   TypeCheckTopLevelExternItem (const HIR::ExternBlock &parent);
