From b7bb6a9832958abb076dcd9207c7457a7bec6201 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 14 Oct 2021 12:32:43 +0100 Subject: [PATCH] Add boiler plate for TyTy::ClosureType This adds all the nesecary boiler plate to introduce the ClosureType. More work is needed to be make this actually useable for type resolution. Addresses #195 --- gcc/rust/backend/rust-compile-context.h | 2 + gcc/rust/backend/rust-compile-tyty.h | 2 + gcc/rust/typecheck/rust-hir-const-fold.h | 2 + gcc/rust/typecheck/rust-substitution-mapper.h | 19 +++++ gcc/rust/typecheck/rust-tyty-call.h | 2 + gcc/rust/typecheck/rust-tyty-cast.h | 39 ++++++++++ gcc/rust/typecheck/rust-tyty-cmp.h | 43 +++++++++++ gcc/rust/typecheck/rust-tyty-coercion.h | 41 +++++++++++ gcc/rust/typecheck/rust-tyty-rules.h | 39 ++++++++++ gcc/rust/typecheck/rust-tyty-visitor.h | 2 + gcc/rust/typecheck/rust-tyty.cc | 67 +++++++++++++++++ gcc/rust/typecheck/rust-tyty.h | 71 +++++++++++++++++++ 12 files changed, 329 insertions(+) diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 7a4344ec493a..0da21989c477 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -661,6 +661,8 @@ class TyTyResolveCompile : public TyTy::TyVisitor ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type); } + void visit (TyTy::ClosureType &type) override { gcc_unreachable (); } + private: TyTyResolveCompile (Context *ctx, bool trait_object_mode) : ctx (ctx), trait_object_mode (trait_object_mode), translated (nullptr) diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index 40b297c59f99..c544a45e9296 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -239,6 +239,8 @@ class TyTyCompile : public TyTy::TyVisitor void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } + void visit (TyTy::ClosureType &) override { gcc_unreachable (); } + private: TyTyCompile (::Backend *backend) : backend (backend), translated (nullptr), diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h index 14664340d2b5..d8fbd8d4a931 100644 --- a/gcc/rust/typecheck/rust-hir-const-fold.h +++ b/gcc/rust/typecheck/rust-hir-const-fold.h @@ -193,6 +193,8 @@ class ConstFoldType : public TyTy::TyVisitor void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } + void visit (TyTy::ClosureType &) override { gcc_unreachable (); } + private: ConstFoldType (::Backend *backend) : backend (backend), translated (backend->error_type ()) diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index 13496ff22b83..a6e7e8080c26 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -138,6 +138,7 @@ class SubstMapper : public TyTy::TyVisitor void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } + void visit (TyTy::ClosureType &) override { gcc_unreachable (); } private: SubstMapper (HirId ref, HIR::GenericArgs *generics, Location locus) @@ -217,6 +218,11 @@ class SubstMapperInternal : public TyTy::TyVisitor resolved = type.handle_substitions (mappings); } + void visit (TyTy::ClosureType &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 (); } @@ -271,6 +277,14 @@ class SubstMapperFromExisting : public TyTy::TyVisitor resolved = to_sub->handle_substitions (type.get_substitution_arguments ()); } + void visit (TyTy::ClosureType &type) override + { + rust_assert (type.was_substituted ()); + + TyTy::ClosureType *to_sub = static_cast (receiver); + resolved = to_sub->handle_substitions (type.get_substitution_arguments ()); + } + void visit (TyTy::InferType &) override { gcc_unreachable (); } void visit (TyTy::TupleType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } @@ -323,6 +337,11 @@ class GetUsedSubstArgs : public TyTy::TyVisitor args = type.get_substitution_arguments (); } + void visit (TyTy::ClosureType &type) override + { + args = type.get_substitution_arguments (); + } + void visit (TyTy::InferType &) override {} void visit (TyTy::TupleType &) override {} void visit (TyTy::FnPtr &) override {} diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index 906110ad8954..2eeebd0a3011 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -65,6 +65,7 @@ class TypeCheckCallExpr : private TyVisitor // call fns void visit (FnType &type) override; void visit (FnPtr &type) override; + void visit (ClosureType &type) override { gcc_unreachable (); } private: TypeCheckCallExpr (HIR::CallExpr &c, Resolver::TypeCheckContext *context) @@ -116,6 +117,7 @@ class TypeCheckMethodCallExpr : private TyVisitor // call fns void visit (FnType &type) override; + void visit (ClosureType &type) override { gcc_unreachable (); } private: TypeCheckMethodCallExpr (HIR::MethodCallExpr &c, diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h index fa50992ab9c7..8165bbd8ffa8 100644 --- a/gcc/rust/typecheck/rust-tyty-cast.h +++ b/gcc/rust/typecheck/rust-tyty-cast.h @@ -329,6 +329,17 @@ class BaseCastRules : public TyVisitor type.as_string ().c_str ()); } + virtual void visit (ClosureType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "invalid cast [%s] to [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + protected: BaseCastRules (BaseType *base) : mappings (Analysis::Mappings::get ()), @@ -590,6 +601,19 @@ class InferCastRules : public BaseCastRules BaseCastRules::visit (type); } + void visit (ClosureType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseCastRules::visit (type); + } + private: BaseType *get_base () override { return base; } @@ -749,6 +773,21 @@ class FnptrCastRules : public BaseCastRules FnPtr *base; }; +class ClosureCastRules : public BaseCastRules +{ + using Rust::TyTy::BaseCastRules::visit; + +public: + ClosureCastRules (ClosureType *base) : BaseCastRules (base), base (base) {} + + // TODO + +private: + BaseType *get_base () override { return base; } + + ClosureType *base; +}; + class ArrayCastRules : public BaseCastRules { using Rust::TyTy::BaseCastRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index 030f702e05f8..519501fa02ca 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -391,6 +391,22 @@ class BaseCmp : public TyConstVisitor } } + virtual void visit (const ClosureType &type) override + { + ok = false; + if (emit_error_flag) + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus + = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + } + protected: BaseCmp (const BaseType *base, bool emit_errors) : mappings (Analysis::Mappings::get ()), @@ -651,6 +667,19 @@ class InferCmp : public BaseCmp BaseCmp::visit (type); } + void visit (const ClosureType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + ok = true; + return; + } + + BaseCmp::visit (type); + } + private: const BaseType *get_base () const override { return base; } const InferType *base; @@ -792,6 +821,20 @@ class FnptrCmp : public BaseCmp const FnPtr *base; }; +class ClosureCmp : public BaseCmp +{ + using Rust::TyTy::BaseCmp::visit; + +public: + ClosureCmp (const ClosureType *base, bool emit_errors) + : BaseCmp (base, emit_errors), base (base) + {} + +private: + const BaseType *get_base () const override { return base; } + const ClosureType *base; +}; + class ArrayCmp : public BaseCmp { using Rust::TyTy::BaseCmp::visit; diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h index 885368791f68..f4592f47e2c6 100644 --- a/gcc/rust/typecheck/rust-tyty-coercion.h +++ b/gcc/rust/typecheck/rust-tyty-coercion.h @@ -343,6 +343,17 @@ class BaseCoercionRules : public TyVisitor type.as_string ().c_str ()); } + virtual void visit (ClosureType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + protected: BaseCoercionRules (BaseType *base) : mappings (Analysis::Mappings::get ()), @@ -605,6 +616,19 @@ class InferCoercionRules : public BaseCoercionRules BaseCoercionRules::visit (type); } + void visit (ClosureType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseCoercionRules::visit (type); + } + private: BaseType *get_base () override { return base; } @@ -764,6 +788,23 @@ class FnptrCoercionRules : public BaseCoercionRules FnPtr *base; }; +class ClosureCoercionRules : public BaseCoercionRules +{ + using Rust::TyTy::BaseCoercionRules::visit; + +public: + ClosureCoercionRules (ClosureType *base) + : BaseCoercionRules (base), base (base) + {} + + // TODO + +private: + BaseType *get_base () override { return base; } + + ClosureType *base; +}; + class ArrayCoercionRules : public BaseCoercionRules { using Rust::TyTy::BaseCoercionRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index b235ff08b3e5..67ab7d4c8bd7 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -364,6 +364,17 @@ class BaseRules : public TyVisitor type.as_string ().c_str ()); } + virtual void visit (ClosureType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + protected: BaseRules (BaseType *base) : mappings (Analysis::Mappings::get ()), @@ -625,6 +636,19 @@ class InferRules : public BaseRules BaseRules::visit (type); } + void visit (ClosureType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseRules::visit (type); + } + private: BaseType *get_base () override { return base; } @@ -784,6 +808,21 @@ class FnptrRules : public BaseRules FnPtr *base; }; +class ClosureRules : public BaseRules +{ + using Rust::TyTy::BaseRules::visit; + +public: + ClosureRules (ClosureType *base) : BaseRules (base), base (base) {} + + // TODO + +private: + BaseType *get_base () override { return base; } + + ClosureType *base; +}; + class ArrayRules : public BaseRules { using Rust::TyTy::BaseRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index a51edf49cf94..fb91f2d28cc2 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -49,6 +49,7 @@ class TyVisitor virtual void visit (PlaceholderType &type) = 0; virtual void visit (ProjectionType &type) = 0; virtual void visit (DynamicObjectType &type) = 0; + virtual void visit (ClosureType &type) = 0; }; class TyConstVisitor @@ -76,6 +77,7 @@ class TyConstVisitor virtual void visit (const PlaceholderType &type) = 0; virtual void visit (const ProjectionType &type) = 0; virtual void visit (const DynamicObjectType &type) = 0; + virtual void visit (const ClosureType &type) = 0; }; } // namespace TyTy diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 3f0d8a361956..f08d8cb200d2 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -1111,6 +1111,73 @@ FnPtr::clone () const result_type, get_combined_refs ()); } +void +ClosureType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureType::accept_vis (TyConstVisitor &vis) const +{ + vis.visit (*this); +} + +std::string +ClosureType::as_string () const +{ + return "TODO"; +} + +BaseType * +ClosureType::unify (BaseType *other) +{ + ClosureRules r (this); + return r.unify (other); +} + +bool +ClosureType::can_eq (const BaseType *other, bool emit_errors) const +{ + ClosureCmp r (this, emit_errors); + return r.can_eq (other); +} + +BaseType * +ClosureType::coerce (BaseType *other) +{ + ClosureCoercionRules r (this); + return r.coerce (other); +} + +BaseType * +ClosureType::cast (BaseType *other) +{ + ClosureCoercionRules r (this); + return r.coerce (other); +} + +bool +ClosureType::is_equal (const BaseType &other) const +{ + gcc_unreachable (); + return false; +} + +BaseType * +ClosureType::clone () const +{ + return new ClosureType (get_ref (), get_ty_ref (), id, parameter_types, + result_type, clone_substs (), get_combined_refs ()); +} + +ClosureType * +ClosureType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + gcc_unreachable (); + return nullptr; +} + void ArrayType::accept_vis (TyVisitor &vis) { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 22b93fa63ec6..620fdf0ee108 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -66,6 +66,7 @@ enum TypeKind PLACEHOLDER, PROJECTION, DYNAMIC, + CLOSURE, // there are more to add... ERROR }; @@ -140,6 +141,9 @@ class TypeKindFormat case TypeKind::DYNAMIC: return "Dynamic"; + case TypeKind::CLOSURE: + return "Closure"; + case TypeKind::ERROR: return "ERROR"; } @@ -1278,6 +1282,73 @@ class FnPtr : public BaseType TyVar result_type; }; +class ClosureType : public BaseType, public SubstitutionRef +{ +public: + ClosureType (HirId ref, DefId id, std::vector parameter_types, + TyVar result_type, + std::vector subst_refs, + std::set refs = std::set ()) + : BaseType (ref, ref, TypeKind::CLOSURE, refs), + SubstitutionRef (std::move (subst_refs), + SubstitutionArgumentMappings::error ()), + parameter_types (std::move (parameter_types)), + result_type (std::move (result_type)), id (id) + { + LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK; + rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID); + } + + ClosureType (HirId ref, HirId ty_ref, DefId id, + std::vector parameter_types, TyVar result_type, + std::vector subst_refs, + std::set refs = std::set ()) + : BaseType (ref, ty_ref, TypeKind::CLOSURE, refs), + SubstitutionRef (std::move (subst_refs), + SubstitutionArgumentMappings::error ()), + parameter_types (std::move (parameter_types)), + result_type (std::move (result_type)), id (id) + { + LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK; + rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID); + } + + void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; + + std::string as_string () const override; + std::string get_name () const override final { return as_string (); } + + BaseType *unify (BaseType *other) override; + bool can_eq (const BaseType *other, bool emit_errors) const override final; + BaseType *coerce (BaseType *other) override; + BaseType *cast (BaseType *other) override; + + bool is_equal (const BaseType &other) const override; + + BaseType *clone () const final override; + + bool needs_generic_substitutions () const override final + { + return needs_substitution (); + } + + bool supports_substitutions () const override final { return true; } + + bool has_subsititions_defined () const override final + { + return has_substitutions (); + } + + ClosureType * + handle_substitions (SubstitutionArgumentMappings mappings) override final; + +private: + std::vector parameter_types; + TyVar result_type; + DefId id; +}; + class ArrayType : public BaseType { public: