diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-09-15 20:47:03 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-09-17 15:46:42 +0100 |
commit | ecb777cc8df55a024add203e858486eadcc3aa62 (patch) | |
tree | 950da3dd68add54317bea943cbea44e7f7e5a768 | |
parent | 384cc64dab40edca1f59f369e162df89aa1e91f8 (diff) | |
download | gcc-ecb777cc8df55a024add203e858486eadcc3aa62.zip gcc-ecb777cc8df55a024add203e858486eadcc3aa62.tar.gz gcc-ecb777cc8df55a024add203e858486eadcc3aa62.tar.bz2 |
Add building blocks for Dynamic object types
This is the stub implementation for dynamic object types within the type
system. More work is needed to actually support dynamic trait objects.
The next change requires us to support type coercions in for arguments
to functions such as a fat-reference to a type being coerced into this
dynamic trait object for dynamic dispatch.
Addresses: #197
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-tyty.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-const-fold.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 16 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.h | 56 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cast.h | 38 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cmp.h | 56 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-coercion.h | 57 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 66 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-visitor.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 73 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 53 |
14 files changed, 394 insertions, 35 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 3a92c32..7d2f32d 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -610,6 +610,8 @@ public: translated = ctx->get_backend ()->unit_type (); } + void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } + private: TyTyResolveCompile (Context *ctx) : ctx (ctx), translated (nullptr) {} diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index 1a5747a..40b297c 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -237,6 +237,8 @@ public: translated = backend->unit_type (); } + void visit (TyTy::DynamicObjectType &) 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 1bff7ef..1466434 100644 --- a/gcc/rust/typecheck/rust-hir-const-fold.h +++ b/gcc/rust/typecheck/rust-hir-const-fold.h @@ -191,6 +191,8 @@ public: void visit (TyTy::NeverType &) override { gcc_unreachable (); } + void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } + private: ConstFoldType (::Backend *backend) : backend (backend), translated (backend->error_type ()) diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index b54a403..c660521 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -221,5 +221,21 @@ TypeCheckType::resolve_segments ( gcc_unreachable (); } +void +TypeCheckType::visit (HIR::TraitObjectTypeOneBound &type) +{ + std::vector<TyTy::TypeBoundPredicate> specified_bounds; + + HIR::TraitBound &trait_bound = type.get_trait_bound (); + TraitReference *trait = resolve_trait_path (trait_bound.get_path ()); + TyTy::TypeBoundPredicate predicate (trait->get_mappings ().get_defid (), + trait_bound.get_locus ()); + + specified_bounds.push_back (std::move (predicate)); + + translated = new TyTy::DynamicObjectType (type.get_mappings ().get_hirid (), + std::move (specified_bounds)); +} + } // 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 c02a369..1f97a4e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -146,6 +146,8 @@ public: TyTy::InferType::InferTypeKind::GENERAL); } + void visit (HIR::TraitObjectTypeOneBound &type) override; + private: TypeCheckType (std::vector<TyTy::SubstitutionParamMapping> *subst_mappings) : TypeCheckBase (), subst_mappings (subst_mappings), translated (nullptr) diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index 28cbeb8..13496ff 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -137,6 +137,7 @@ public: void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } + void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } private: SubstMapper (HirId ref, HIR::GenericArgs *generics, Location locus) @@ -230,6 +231,7 @@ public: void visit (TyTy::CharType &) override { gcc_unreachable (); } void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } + void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } private: SubstMapperInternal (HirId ref, TyTy::SubstitutionArgumentMappings &mappings) @@ -288,6 +290,7 @@ public: void visit (TyTy::NeverType &) override { gcc_unreachable (); } void visit (TyTy::PlaceholderType &) override { gcc_unreachable (); } void visit (TyTy::ProjectionType &) override { gcc_unreachable (); } + void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); } private: SubstMapperFromExisting (TyTy::BaseType *concrete, TyTy::BaseType *receiver) @@ -339,6 +342,7 @@ public: void visit (TyTy::NeverType &) override {} void visit (TyTy::PlaceholderType &) override {} void visit (TyTy::ProjectionType &) override {} + void visit (TyTy::DynamicObjectType &) override {} private: GetUsedSubstArgs () : args (TyTy::SubstitutionArgumentMappings::error ()) {} diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index 4e74e59..906110a 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -39,24 +39,25 @@ public: return checker.resolved; } - void visit (InferType &type) override { gcc_unreachable (); } - void visit (TupleType &type) override { gcc_unreachable (); } - void visit (ArrayType &type) override { gcc_unreachable (); } - void visit (BoolType &type) override { gcc_unreachable (); } - void visit (IntType &type) override { gcc_unreachable (); } - void visit (UintType &type) override { gcc_unreachable (); } - void visit (FloatType &type) override { gcc_unreachable (); } - void visit (USizeType &type) override { gcc_unreachable (); } - void visit (ISizeType &type) override { gcc_unreachable (); } - void visit (ErrorType &type) override { gcc_unreachable (); } - void visit (CharType &type) override { gcc_unreachable (); } - void visit (ReferenceType &type) override { gcc_unreachable (); } - void visit (PointerType &type) override { gcc_unreachable (); } + void visit (InferType &) override { gcc_unreachable (); } + void visit (TupleType &) override { gcc_unreachable (); } + void visit (ArrayType &) override { gcc_unreachable (); } + void visit (BoolType &) override { gcc_unreachable (); } + void visit (IntType &) override { gcc_unreachable (); } + void visit (UintType &) override { gcc_unreachable (); } + void visit (FloatType &) override { gcc_unreachable (); } + void visit (USizeType &) override { gcc_unreachable (); } + void visit (ISizeType &) override { gcc_unreachable (); } + void visit (ErrorType &) override { gcc_unreachable (); } + void visit (CharType &) override { gcc_unreachable (); } + void visit (ReferenceType &) override { gcc_unreachable (); } + void visit (PointerType &) override { gcc_unreachable (); } void visit (ParamType &) override { gcc_unreachable (); } void visit (StrType &) override { gcc_unreachable (); } void visit (NeverType &) override { gcc_unreachable (); } void visit (PlaceholderType &) override { gcc_unreachable (); } void visit (ProjectionType &) override { gcc_unreachable (); } + void visit (DynamicObjectType &) override { gcc_unreachable (); } // tuple-structs void visit (ADTType &type) override; @@ -89,25 +90,26 @@ public: return checker.resolved; } - void visit (InferType &type) override { gcc_unreachable (); } - void visit (TupleType &type) override { gcc_unreachable (); } - void visit (ArrayType &type) override { gcc_unreachable (); } - void visit (BoolType &type) override { gcc_unreachable (); } - void visit (IntType &type) override { gcc_unreachable (); } - void visit (UintType &type) override { gcc_unreachable (); } - void visit (FloatType &type) override { gcc_unreachable (); } - void visit (USizeType &type) override { gcc_unreachable (); } - void visit (ISizeType &type) override { gcc_unreachable (); } - void visit (ErrorType &type) override { gcc_unreachable (); } - void visit (ADTType &type) override { gcc_unreachable (); }; - void visit (CharType &type) override { gcc_unreachable (); } - void visit (ReferenceType &type) override { gcc_unreachable (); } - void visit (PointerType &type) override { gcc_unreachable (); } + void visit (InferType &) override { gcc_unreachable (); } + void visit (TupleType &) override { gcc_unreachable (); } + void visit (ArrayType &) override { gcc_unreachable (); } + void visit (BoolType &) override { gcc_unreachable (); } + void visit (IntType &) override { gcc_unreachable (); } + void visit (UintType &) override { gcc_unreachable (); } + void visit (FloatType &) override { gcc_unreachable (); } + void visit (USizeType &) override { gcc_unreachable (); } + void visit (ISizeType &) override { gcc_unreachable (); } + void visit (ErrorType &) override { gcc_unreachable (); } + void visit (ADTType &) override { gcc_unreachable (); }; + void visit (CharType &) override { gcc_unreachable (); } + void visit (ReferenceType &) override { gcc_unreachable (); } + void visit (PointerType &) override { gcc_unreachable (); } void visit (ParamType &) override { gcc_unreachable (); } void visit (StrType &) override { gcc_unreachable (); } void visit (NeverType &) override { gcc_unreachable (); } void visit (PlaceholderType &) override { gcc_unreachable (); } void visit (ProjectionType &) override { gcc_unreachable (); } + void visit (DynamicObjectType &) override { gcc_unreachable (); } // FIXME void visit (FnPtr &type) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h index 51c9791..fa50992 100644 --- a/gcc/rust/typecheck/rust-tyty-cast.h +++ b/gcc/rust/typecheck/rust-tyty-cast.h @@ -318,6 +318,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (DynamicObjectType &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 ()), @@ -566,6 +577,19 @@ public: BaseCastRules::visit (type); } + void visit (DynamicObjectType &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; } @@ -1273,6 +1297,20 @@ private: PlaceholderType *base; }; +class DynamicCastRules : public BaseCastRules +{ + using Rust::TyTy::BaseCastRules::visit; + +public: + DynamicCastRules (DynamicObjectType *base) : BaseCastRules (base), base (base) + {} + +private: + BaseType *get_base () override { return base; } + + DynamicObjectType *base; +}; + } // namespace TyTy } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index 100e384..030f702 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -375,6 +375,22 @@ public: ok = true; } + virtual void visit (const DynamicObjectType &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 ()), @@ -622,6 +638,19 @@ public: BaseCmp::visit (type); } + void visit (const DynamicObjectType &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; @@ -1231,6 +1260,33 @@ private: const PlaceholderType *base; }; +class DynamicCmp : public BaseCmp +{ + using Rust::TyTy::BaseCmp::visit; + +public: + DynamicCmp (const DynamicObjectType *base, bool emit_errors) + : BaseCmp (base, emit_errors), base (base) + {} + + void visit (const DynamicObjectType &type) override + { + if (base->num_specified_bounds () != type.num_specified_bounds ()) + { + BaseCmp::visit (type); + return; + } + + Location ref_locus = mappings->lookup_location (type.get_ref ()); + ok = base->bounds_compatible (type, ref_locus, false); + } + +private: + const BaseType *get_base () const override { return base; } + + const DynamicObjectType *base; +}; + } // namespace TyTy } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h index f12ffb4..2d59e88 100644 --- a/gcc/rust/typecheck/rust-tyty-coercion.h +++ b/gcc/rust/typecheck/rust-tyty-coercion.h @@ -331,6 +331,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (DynamicObjectType &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 ()), @@ -580,6 +591,19 @@ public: BaseCoercionRules::visit (type); } + void visit (DynamicObjectType &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; } @@ -1308,6 +1332,39 @@ private: PlaceholderType *base; }; +class DynamicCoercionRules : public BaseCoercionRules +{ + using Rust::TyTy::BaseCoercionRules::visit; + +public: + DynamicCoercionRules (DynamicObjectType *base) + : BaseCoercionRules (base), base (base) + {} + + void visit (DynamicObjectType &type) override + { + if (base->num_specified_bounds () != type.num_specified_bounds ()) + { + BaseCoercionRules::visit (type); + return; + } + + Location ref_locus = mappings->lookup_location (type.get_ref ()); + if (!base->bounds_compatible (type, ref_locus, true)) + { + BaseCoercionRules::visit (type); + return; + } + + resolved = base->clone (); + } + +private: + BaseType *get_base () override { return base; } + + DynamicObjectType *base; +}; + } // namespace TyTy } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index db7d8c0..62689cf 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -353,6 +353,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (DynamicObjectType &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 ()), @@ -601,6 +612,19 @@ public: BaseRules::visit (type); } + void visit (DynamicObjectType &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; } @@ -1314,6 +1338,48 @@ private: PlaceholderType *base; }; +class DynamicRules : public BaseRules +{ + using Rust::TyTy::BaseRules::visit; + +public: + DynamicRules (DynamicObjectType *base) : BaseRules (base), base (base) {} + + void visit (InferType &type) override + { + if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL) + { + BaseRules::visit (type); + return; + } + + resolved = base->clone (); + } + + void visit (DynamicObjectType &type) override + { + if (base->num_specified_bounds () != type.num_specified_bounds ()) + { + BaseRules::visit (type); + return; + } + + Location ref_locus = mappings->lookup_location (type.get_ref ()); + if (!base->bounds_compatible (type, ref_locus, true)) + { + BaseRules::visit (type); + return; + } + + resolved = base->clone (); + } + +private: + BaseType *get_base () override { return base; } + + DynamicObjectType *base; +}; + } // namespace TyTy } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 0e9a58b..a51edf4 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -48,6 +48,7 @@ public: virtual void visit (NeverType &type) = 0; virtual void visit (PlaceholderType &type) = 0; virtual void visit (ProjectionType &type) = 0; + virtual void visit (DynamicObjectType &type) = 0; }; class TyConstVisitor @@ -74,6 +75,7 @@ public: virtual void visit (const NeverType &type) = 0; virtual void visit (const PlaceholderType &type) = 0; virtual void visit (const ProjectionType &type) = 0; + virtual void visit (const DynamicObjectType &type) = 0; }; } // namespace TyTy diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index ef981cc..69fb8c4 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -63,7 +63,8 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const } bool -BaseType::bounds_compatible (const BaseType &other, Location locus) const +BaseType::bounds_compatible (const BaseType &other, Location locus, + bool emit_error) const { std::vector<std::reference_wrapper<const TypeBoundPredicate>> unsatisfied_bounds; @@ -89,8 +90,9 @@ BaseType::bounds_compatible (const BaseType &other, Location locus) const missing_preds += ", "; } - rust_error_at (r, "bounds not satisfied for %s %<%s%> is not satisfied", - other.get_name ().c_str (), missing_preds.c_str ()); + if (emit_error) + rust_error_at (r, "bounds not satisfied for %s %<%s%> is not satisfied", + other.get_name ().c_str (), missing_preds.c_str ()); } return unsatisfied_bounds.size () == 0; @@ -2257,6 +2259,71 @@ ProjectionType::handle_substitions (SubstitutionArgumentMappings subst_mappings) return projection; } +void +DynamicObjectType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +void +DynamicObjectType::accept_vis (TyConstVisitor &vis) const +{ + vis.visit (*this); +} + +std::string +DynamicObjectType::as_string () const +{ + return "dyn [" + raw_bounds_as_string () + "]"; +} + +BaseType * +DynamicObjectType::unify (BaseType *other) +{ + DynamicRules r (this); + return r.unify (other); +} + +bool +DynamicObjectType::can_eq (const BaseType *other, bool emit_errors) const +{ + DynamicCmp r (this, emit_errors); + return r.can_eq (other); +} + +BaseType * +DynamicObjectType::coerce (BaseType *other) +{ + DynamicCoercionRules r (this); + return r.coerce (other); +} + +BaseType * +DynamicObjectType::cast (BaseType *other) +{ + DynamicCastRules r (this); + return r.cast (other); +} + +BaseType * +DynamicObjectType::clone () const +{ + return new DynamicObjectType (get_ref (), get_ty_ref (), specified_bounds, + get_combined_refs ()); +} + +bool +DynamicObjectType::is_equal (const BaseType &other) const +{ + if (get_kind () != other.get_kind ()) + return false; + + if (num_specified_bounds () != other.num_specified_bounds ()) + return false; + + return bounds_compatible (other, Location (), false); +} + // rust-tyty-call.h void diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index a7eb132..90057de 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -57,6 +57,7 @@ enum TypeKind NEVER, PLACEHOLDER, PROJECTION, + DYNAMIC, // there are more to add... ERROR }; @@ -128,6 +129,9 @@ public: case TypeKind::PROJECTION: return "Projection"; + case TypeKind::DYNAMIC: + return "Dynamic"; + case TypeKind::ERROR: return "ERROR"; } @@ -173,13 +177,20 @@ public: return specified_bounds; } - std::string bounds_as_string () const + size_t num_specified_bounds () const { return specified_bounds.size (); } + + std::string raw_bounds_as_string () const { std::string buf; for (auto &b : specified_bounds) - buf += b.as_string () + ", "; + buf += b.as_string () + " + "; + + return buf; + } - return "bounds:[" + buf + "]"; + std::string bounds_as_string () const + { + return "bounds:[" + raw_bounds_as_string () + "]"; } protected: @@ -253,7 +264,8 @@ public: bool satisfies_bound (const TypeBoundPredicate &predicate) const; - bool bounds_compatible (const BaseType &other, Location locus) const; + bool bounds_compatible (const BaseType &other, Location locus, + bool emit_error) const; void inherit_bounds (const BaseType &other); @@ -608,7 +620,7 @@ public: } else { - if (!param->bounds_compatible (*type, locus)) + if (!param->bounds_compatible (*type, locus, true)) return; } @@ -1813,6 +1825,37 @@ private: DefId item; }; +class DynamicObjectType : public BaseType +{ +public: + DynamicObjectType (HirId ref, + std::vector<TypeBoundPredicate> specified_bounds, + std::set<HirId> refs = std::set<HirId> ()) + : BaseType (ref, ref, TypeKind::DYNAMIC, specified_bounds, refs) + {} + + DynamicObjectType (HirId ref, HirId ty_ref, + std::vector<TypeBoundPredicate> specified_bounds, + std::set<HirId> refs = std::set<HirId> ()) + : BaseType (ref, ty_ref, TypeKind::DYNAMIC, specified_bounds, refs) + {} + + void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; + + std::string as_string () const override; + + 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; + + std::string get_name () const override final { return as_string (); } +}; + } // namespace TyTy } // namespace Rust |