[gccrs COMMIT] gccrs: Implement extern types by reusing ADT with an extern kind

gerris.rs@gmail.com gerris.rs@gmail.com
Mon Aug 31 22:10:07 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

This reused out ADTType to capture these extern opaque types with a new
ADTKind of extern.

gcc/rust/ChangeLog:

	* backend/rust-compile-extern.h: compile it down
	* backend/rust-compile-type.cc (TyTyResolveCompile::visit): make empty struct
	* checks/errors/rust-hir-pattern-analysis.cc (PlaceInfo::specialize): add missng case
	* typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit): create adt
	* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::assemble_marker_builtins): not sized
	* typecheck/rust-tyty.h: new kind

gcc/testsuite/ChangeLog:

	* rust/compile/extern_type_item_resolve.rs: it works
	* rust/compile/extern-type-unsized.rs: New test.
	* rust/compile/extern-type.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.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/2ff0fc955bae6b07bfc663a063ff96b6e5b04bdc

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

 gcc/rust/backend/rust-compile-extern.h        | 10 +++++++-
 gcc/rust/backend/rust-compile-type.cc         |  4 ++++
 .../errors/rust-hir-pattern-analysis.cc       |  2 ++
 .../typecheck/rust-hir-type-check-implitem.cc | 23 +++++++++++++++++--
 gcc/rust/typecheck/rust-tyty-bounds.cc        | 10 +++++++-
 gcc/rust/typecheck/rust-tyty.h                |  3 ++-
 .../rust/compile/extern-type-unsized.rs       | 16 +++++++++++++
 gcc/testsuite/rust/compile/extern-type.rs     | 13 +++++++++++
 .../rust/compile/extern_type_item_resolve.rs  |  1 -
 9 files changed, 76 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/extern-type-unsized.rs
 create mode 100644 gcc/testsuite/rust/compile/extern-type.rs

diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index b2237b77c..824d31214 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -204,7 +204,15 @@ public:
 
   void visit (HIR::ExternalTypeItem &type) override
   {
-    rust_sorry_at (type.get_locus (), "extern types are not supported yet");
+    TyTy::BaseType *lookup = nullptr;
+    if (!ctx->get_tyctx ()->lookup_type (type.get_mappings ().get_hirid (),
+					 &lookup))
+      {
+	rust_error_at (type.get_locus (), "failed to resolve type");
+	return;
+      }
+
+    TyTyResolveCompile::compile (ctx, lookup);
   }
 
 private:
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index 1a815b9ff..56f9e9424 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -342,6 +342,10 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
 
       type_record = build_vector_type (inner_type, variant.num_fields ());
     }
+  else if (type.get_adt_kind () == TyTy::ADTType::ADTKind::EXTERN)
+    {
+      type_record = Backend::struct_type ({});
+    }
   else if (!type.is_enum ())
     {
       rust_assert (type.number_of_variants () == 1);
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index ef5ae34d3..33461d918 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -978,6 +978,8 @@ PlaceInfo::specialize (const Constructor &c) const
 	      // TODO: support unions
 	      rust_unreachable ();
 	    }
+	  case TyTy::ADTType::ADTKind::EXTERN:
+	    return {};
 	  }
       }
       break;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 57f1718e9..9d8f8385e 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-canonical-path.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-full-decls.h"
 #include "rust-hir-pattern.h"
@@ -169,8 +170,26 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 void
 TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
 {
-  rust_sorry_at (type.get_locus (), "extern types are not supported yet");
-  // TODO
+  CanonicalPath path
+    = CanonicalPath::new_seg (type.get_mappings ().get_nodeid (),
+			      type.get_item_name ().as_string ());
+
+  RustIdent ident{path, type.get_locus ()};
+
+  TyTy::ADTType::ReprOptions repr;
+  std::vector<TyTy::VariantDef *> variants;
+  TyTy::RegionConstraints region_constraints;
+  std::vector<TyTy::SubstitutionParamMapping> substitutions;
+
+  auto *extern_type = new TyTy::ADTType (
+    type.get_mappings ().get_defid (), type.get_mappings ().get_hirid (),
+    type.get_mappings ().get_hirid (), type.get_item_name ().as_string (),
+    ident, TyTy::ADTType::ADTKind::EXTERN, std::move (variants),
+    std::move (substitutions), repr,
+    TyTy::SubstitutionArgumentMappings::empty (0), region_constraints);
+
+  context->insert_type (type.get_mappings (), extern_type);
+  resolved = extern_type;
 }
 
 TypeCheckImplItem::TypeCheckImplItem (
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 8760eb1a0..f72ee57f9 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -22,6 +22,7 @@
 #include "rust-substitution-mapper.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-type-util.h"
+#include "rust-tyty.h"
 
 namespace Rust {
 namespace Resolver {
@@ -170,12 +171,19 @@ TypeBoundsProbe::assemble_marker_builtins ()
       // FIXME str and slice need to be moved and test cases updated
     case TyTy::SLICE:
     case TyTy::STR:
-    case TyTy::ADT:
     case TyTy::TUPLE:
       // FIXME add extra checks
       assemble_builtin_candidate (LangItem::Kind::SIZED);
       break;
 
+    case TyTy::ADT:
+      {
+	const auto &adt = *static_cast<const TyTy::ADTType *> (raw);
+	if (adt.get_adt_kind () != TyTy::ADTType::ADTKind::EXTERN)
+	  assemble_builtin_candidate (LangItem::Kind::SIZED);
+      }
+      break;
+
     case TyTy::CONST:
     case TyTy::DYNAMIC:
     case TyTy::ERROR:
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 45888e48f..4e1cd301e 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -917,7 +917,8 @@ public:
     STRUCT_STRUCT,
     TUPLE_STRUCT,
     UNION,
-    ENUM
+    ENUM,
+    EXTERN
   };
 
   enum ReprKind
diff --git a/gcc/testsuite/rust/compile/extern-type-unsized.rs b/gcc/testsuite/rust/compile/extern-type-unsized.rs
new file mode 100644
index 000000000..271c3ee90
--- /dev/null
+++ b/gcc/testsuite/rust/compile/extern-type-unsized.rs
@@ -0,0 +1,16 @@
+#![feature(extern_types, lang_items, no_core)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+extern "C" {
+    type Opaque;
+}
+
+fn require_sized<T>() {}
+
+fn main() {
+    require_sized::<Opaque>();
+    // { dg-error "bounds not satisfied for Opaque .Sized. is not satisfied" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/extern-type.rs b/gcc/testsuite/rust/compile/extern-type.rs
new file mode 100644
index 000000000..256af5b95
--- /dev/null
+++ b/gcc/testsuite/rust/compile/extern-type.rs
@@ -0,0 +1,13 @@
+#![feature(no_core, extern_types)]
+#![no_core]
+
+extern "C" {
+    type Opaque;
+}
+
+fn takes_ptr(_ptr: *const Opaque) {}
+
+fn main() {
+    let ptr = 0 as *const Opaque;
+    takes_ptr(ptr);
+}
diff --git a/gcc/testsuite/rust/compile/extern_type_item_resolve.rs b/gcc/testsuite/rust/compile/extern_type_item_resolve.rs
index 0313d9dba..e2b354478 100644
--- a/gcc/testsuite/rust/compile/extern_type_item_resolve.rs
+++ b/gcc/testsuite/rust/compile/extern_type_item_resolve.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-compile-until=typecheck" }
 #![feature(no_core, extern_types)]
 #![no_core]
 

base-commit: 9b2b2ebeaa814bb86c8da2996e74b2c8b6ed0a4a
-- 
2.55.0



More information about the Gcc-rust mailing list