https://gcc.gnu.org/g:13be1e80194088730f09dc546f2d0e89322ef878
commit r17-4315-g13be1e80194088730f09dc546f2d0e89322ef878 Author: Philip Herron <[email protected]> Date: Sun Aug 30 23:32:32 2026 +0100 gccrs: Implement extern types by reusing ADT with an extern kind 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 <[email protected]> Diff: --- gcc/rust/backend/rust-compile-extern.h | 10 +++++++++- gcc/rust/backend/rust-compile-type.cc | 4 ++++ .../checks/errors/rust-hir-pattern-analysis.cc | 2 ++ gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 23 ++++++++++++++++++++-- gcc/rust/typecheck/rust-tyty-bounds.cc | 10 +++++++++- gcc/rust/typecheck/rust-tyty.h | 3 ++- gcc/testsuite/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(-) diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h index b2237b77c246..824d312143c5 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 1a815b9ffebf..56f9e9424342 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 ef5ae34d3cbf..33461d918141 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 57f1718e9500..9d8f8385ecac 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 8760eb1a0a84..f72ee57f93a5 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 45888e48fd38..4e1cd301edfa 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 000000000000..271c3ee902bd --- /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 000000000000..256af5b95d2c --- /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 0313d9dbade4..e2b354478afc 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]
