From a1b065050ba0e19f42d11046e70b1edae33f71e8 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 10 Mar 2022 13:27:38 +0000 Subject: [PATCH 1/3] Add const_ptr lang item mappings const_ptr is a lang item used as part of the slice implemenation this adds it to our mappings so we do not error with an unknown lang item. --- gcc/rust/util/rust-lang-item.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h index cade09d88541..d2765bf201ea 100644 --- a/gcc/rust/util/rust-lang-item.h +++ b/gcc/rust/util/rust-lang-item.h @@ -68,6 +68,9 @@ class RustLangItem RANGE_INCLUSIVE, RANGE_TO_INCLUSIVE, + // https://github.com/rust-lang/rust/blob/master/library/core/src/ptr/const_ptr.rs + CONST_PTR, + UNKNOWN, }; @@ -201,6 +204,10 @@ class RustLangItem { return ItemType::RANGE_TO_INCLUSIVE; } + else if (item.compare ("const_ptr") == 0) + { + return ItemType::CONST_PTR; + } return ItemType::UNKNOWN; } @@ -273,6 +280,8 @@ class RustLangItem return "RangeInclusive"; case RANGE_TO_INCLUSIVE: return "RangeToInclusive"; + case CONST_PTR: + return "const_ptr"; case UNKNOWN: return ""; From a620a228c1d79d4725efd5d6ed5f0ebe398e6787 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 10 Mar 2022 16:19:14 +0000 Subject: [PATCH 2/3] Add missing type-checking for slice types --- gcc/rust/hir/tree/rust-hir-type.h | 2 ++ gcc/rust/typecheck/rust-hir-type-check-type.cc | 10 ++++++++++ gcc/rust/typecheck/rust-hir-type-check-type.h | 6 ++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index 8692dfdba2e3..39bb9d2f8992 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -668,6 +668,8 @@ class SliceType : public TypeNoBounds void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; + std::unique_ptr &get_element_type () { return elem_type; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 9902614e269c..6c6546babe6e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -600,5 +600,15 @@ TypeCheckType::visit (HIR::ArrayType &type) TyTy::TyVar (base->get_ref ())); } +void +TypeCheckType::visit (HIR::SliceType &type) +{ + TyTy::BaseType *base + = TypeCheckType::Resolve (type.get_element_type ().get ()); + translated + = new TyTy::SliceType (type.get_mappings ().get_hirid (), type.get_locus (), + TyTy::TyVar (base->get_ref ())); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 400328c3fb43..ef5d4123d7f0 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -120,6 +120,8 @@ class TypeCheckType : public TypeCheckBase void visit (HIR::ArrayType &type) override; + void visit (HIR::SliceType &type) override; + void visit (HIR::ReferenceType &type) override { TyTy::BaseType *base @@ -338,8 +340,8 @@ class ResolveWhereClauseItem : public TypeCheckBase binding->inherit_bounds (specified_bounds); // When we apply these bounds we must lookup which type this binding - // resolves to, as this is the type which will be used during resolution of - // the block. + // resolves to, as this is the type which will be used during resolution + // of the block. NodeId ast_node_id = binding_type_path->get_mappings ().get_nodeid (); // then lookup the reference_node_id From 894e9d29adadc13e9841f43df32a07939480846d Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 10 Mar 2022 16:17:52 +0000 Subject: [PATCH 3/3] Handle generic Slices and Arrays Slices and Arrays are covariant types which means they can contain elements which bind generics such as ADT or FnTypes. This means substitutions can be recursive and this gives the typechecker a chance to handle this recursion on these types. --- gcc/rust/typecheck/rust-substitution-mapper.h | 12 +++++-- gcc/rust/typecheck/rust-tyty.cc | 32 +++++++++++++++++++ gcc/rust/typecheck/rust-tyty.h | 4 +++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index 0d48bd2532c3..5f1781635cce 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -221,11 +221,19 @@ class SubstMapperInternal : public TyTy::TyVisitor resolved = type.handle_substitions (mappings); } + void visit (TyTy::ArrayType &type) override + { + resolved = type.handle_substitions (mappings); + } + + void visit (TyTy::SliceType &type) override + { + resolved = type.handle_substitions (mappings); + } + // nothing to do for these void visit (TyTy::InferType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } - void visit (TyTy::ArrayType &) override { gcc_unreachable (); } - void visit (TyTy::SliceType &) override { gcc_unreachable (); } void visit (TyTy::BoolType &) override { gcc_unreachable (); } void visit (TyTy::IntType &) override { gcc_unreachable (); } void visit (TyTy::UintType &) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 0a296445d596..8d5cc5e511a2 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -1508,6 +1508,22 @@ ArrayType::clone () const element_type, get_combined_refs ()); } +ArrayType * +ArrayType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + auto mappings_table = Analysis::Mappings::get (); + + ArrayType *ref = static_cast (clone ()); + ref->set_ty_ref (mappings_table->get_next_hir_id ()); + + // might be &T or &ADT so this needs to be recursive + auto base = ref->get_element_type (); + BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings); + ref->element_type = TyVar (concrete->get_ty_ref ()); + + return ref; +} + void SliceType::accept_vis (TyVisitor &vis) { @@ -1581,6 +1597,22 @@ SliceType::clone () const get_combined_refs ()); } +SliceType * +SliceType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + auto mappings_table = Analysis::Mappings::get (); + + SliceType *ref = static_cast (clone ()); + ref->set_ty_ref (mappings_table->get_next_hir_id ()); + + // might be &T or &ADT so this needs to be recursive + auto base = ref->get_element_type (); + BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings); + ref->element_type = TyVar (concrete->get_ty_ref ()); + + return ref; +} + void BoolType::accept_vis (TyVisitor &vis) { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index bf4110baf76e..82262abab092 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -1665,6 +1665,8 @@ class ArrayType : public BaseType HIR::Expr &get_capacity_expr () const { return capacity_expr; } + ArrayType *handle_substitions (SubstitutionArgumentMappings mappings); + private: TyVar element_type; HIR::Expr &capacity_expr; @@ -1710,6 +1712,8 @@ class SliceType : public BaseType return get_element_type ()->is_concrete (); } + SliceType *handle_substitions (SubstitutionArgumentMappings mappings); + private: TyVar element_type; };