[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