diff options
author | Philip Herron <herron.philip@googlemail.com> | 2025-02-16 01:42:05 +0000 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-24 13:07:06 +0100 |
commit | 3e589260b4edf4a1eeb0934de65a8c5d0c6c73b3 (patch) | |
tree | e40b35096dc63525d92022ee6d33ad92880bdd8e | |
parent | 271a348960418b579787858072880f35da47c59c (diff) | |
download | gcc-3e589260b4edf4a1eeb0934de65a8c5d0c6c73b3.zip gcc-3e589260b4edf4a1eeb0934de65a8c5d0c6c73b3.tar.gz gcc-3e589260b4edf4a1eeb0934de65a8c5d0c6c73b3.tar.bz2 |
gccrs: initial setup for new OpaqueType to represent Impl types
This completes the initial setup and boilerplate for the new type in the
typesystem. This is not functional yet but its a big patch already.
gcc/rust/ChangeLog:
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): new tyty::OpaqueType
* backend/rust-compile-type.h: likewise
* checks/errors/borrowck/rust-bir-fact-collector.h: likewise
* checks/errors/borrowck/rust-bir-place.h: likewise
* checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_base_type_privacy):
likewise
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
* typecheck/rust-hir-type-check-type.h: likewise
* typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): likewise
* typecheck/rust-substitution-mapper.h: likewise
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::assemble_sized_builtin): likewise
* typecheck/rust-tyty-call.h: likewise
* typecheck/rust-tyty-cmp.h (class OpaqueCmp): likewise
* typecheck/rust-tyty-variance-analysis-private.h: likewise
* typecheck/rust-tyty-visitor.h: likewise
* typecheck/rust-tyty.cc (TypeKindFormat::to_string): likewise
(BaseType::is_unit): likewise
(BaseType::destructure): likewise
(BaseType::has_substitutions_defined): likewise
(BaseType::needs_generic_substitutions): likewise
(OpaqueType::OpaqueType): likewise
(OpaqueType::can_resolve): likewise
(OpaqueType::accept_vis): likewise
(OpaqueType::as_string): likewise
(OpaqueType::get_name): likewise
(OpaqueType::can_eq): likewise
(OpaqueType::clone): likewise
(OpaqueType::resolve): likewise
(OpaqueType::is_equal): likewise
(OpaqueType::handle_substitions): likewise
* typecheck/rust-tyty.h (enum TypeKind): likewise
(class OpaqueType): likewise
* typecheck/rust-unify.cc (UnifyRules::go): likewise
(UnifyRules::expect_inference_variable): likewise
(UnifyRules::expect_adt): likewise
(UnifyRules::expect_str): likewise
(UnifyRules::expect_reference): likewise
(UnifyRules::expect_pointer): likewise
(UnifyRules::expect_param): likewise
(UnifyRules::expect_array): likewise
(UnifyRules::expect_slice): likewise
(UnifyRules::expect_fndef): likewise
(UnifyRules::expect_fnptr): likewise
(UnifyRules::expect_tuple): likewise
(UnifyRules::expect_bool): likewise
(UnifyRules::expect_char): likewise
(UnifyRules::expect_int): likewise
(UnifyRules::expect_uint): likewise
(UnifyRules::expect_float): likewise
(UnifyRules::expect_isize): likewise
(UnifyRules::expect_usize): likewise
(UnifyRules::expect_placeholder): likewise
(UnifyRules::expect_projection): likewise
(UnifyRules::expect_dyn): likewise
(UnifyRules::expect_opaque): likewise
* typecheck/rust-unify.h: likewise
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
-rw-r--r-- | gcc/rust/backend/rust-compile-type.cc | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-type.h | 1 | ||||
-rw-r--r-- | gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h | 1 | ||||
-rw-r--r-- | gcc/rust/checks/errors/borrowck/rust-bir-place.h | 1 | ||||
-rw-r--r-- | gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 37 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 13 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.cc | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.h | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cmp.h | 33 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-variance-analysis-private.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-visitor.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 152 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 34 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-unify.cc | 89 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-unify.h | 2 |
18 files changed, 372 insertions, 14 deletions
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index 74368a2..d8af1d1 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -731,6 +731,12 @@ TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type) type.get_ident ().locus); } +void +TyTyResolveCompile::visit (const TyTy::OpaqueType &type) +{ + translated = error_mark_node; +} + tree TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type) { diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h index 398d7f8..bc611cf 100644 --- a/gcc/rust/backend/rust-compile-type.h +++ b/gcc/rust/backend/rust-compile-type.h @@ -56,6 +56,7 @@ public: void visit (const TyTy::ProjectionType &) override; void visit (const TyTy::DynamicObjectType &) override; void visit (const TyTy::ClosureType &) override; + void visit (const TyTy::OpaqueType &) override; public: static hashval_t type_hasher (tree type); diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h index 1332ecf..32a4cd7 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h @@ -815,6 +815,7 @@ protected: // Subset helpers. case TyTy::PLACEHOLDER: case TyTy::INFER: case TyTy::PARAM: + case TyTy::OPAQUE: rust_unreachable (); } rust_unreachable (); diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h b/gcc/rust/checks/errors/borrowck/rust-bir-place.h index a1621b7..67ca90b 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h @@ -485,6 +485,7 @@ private: case TyTy::PROJECTION: // TODO: DUNNO case TyTy::CLOSURE: // TODO: DUNNO case TyTy::DYNAMIC: // TODO: dunno + case TyTy::OPAQUE: return false; } rust_unreachable (); diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc index 896c1c4..a537c42 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc @@ -271,6 +271,8 @@ PrivacyReporter::check_base_type_privacy (Analysis::NodeMapping &node_mappings, // We shouldn't have inference types here, ever case TyTy::INFER: return; + case TyTy::OPAQUE: + return; case TyTy::ERROR: return; } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 6a09772..e56fa39 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -674,6 +674,8 @@ TypeCheckType::visit (HIR::TraitObjectType &type) void TypeCheckType::visit (HIR::ParenthesisedType &type) { + // I think this really needs to be a tuple.. but will sort that out when we + // fix the parser issue translated = TypeCheckType::Resolve (type.get_type_in_parens ()); } @@ -724,7 +726,7 @@ TypeCheckType::visit (HIR::ReferenceType &type) translated = new TyTy::ReferenceType (type.get_mappings ().get_hirid (), TyTy::TyVar (base->get_ref ()), type.get_mut (), region.value ()); -} // namespace Resolver +} void TypeCheckType::visit (HIR::RawPointerType &type) @@ -754,6 +756,39 @@ TypeCheckType::visit (HIR::NeverType &type) translated = lookup->clone (); } +void +TypeCheckType::visit (HIR::ImplTraitType &type) +{ + std::vector<TyTy::TypeBoundPredicate> specified_bounds; + for (auto &bound : type.get_type_param_bounds ()) + { + if (bound->get_bound_type () + != HIR::TypeParamBound::BoundType::TRAITBOUND) + continue; + + HIR::TypeParamBound &b = *bound.get (); + HIR::TraitBound &trait_bound = static_cast<HIR::TraitBound &> (b); + + auto binder_pin = context->push_lifetime_binder (); + for (auto &lifetime_param : trait_bound.get_for_lifetimes ()) + { + context->intern_and_insert_lifetime (lifetime_param.get_lifetime ()); + } + + TyTy::TypeBoundPredicate predicate = get_predicate_from_bound ( + trait_bound.get_path (), + tl::nullopt /*this will setup a PLACEHOLDER for self*/); + + if (!predicate.is_error () + && predicate.is_object_safe (true, type.get_locus ())) + specified_bounds.push_back (std::move (predicate)); + } + + translated = new TyTy::OpaqueType (type.get_locus (), + type.get_mappings ().get_hirid (), + specified_bounds); +} + TyTy::ParamType * TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m, bool apply_sized) { diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 558dc5c..fc272e6 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -60,16 +60,11 @@ public: void visit (HIR::NeverType &type) override; void visit (HIR::TraitObjectType &type) override; void visit (HIR::ParenthesisedType &type) override; + void visit (HIR::ImplTraitType &type) override; - void visit (HIR::TypePathSegmentFunction &segment) override - { /* TODO */ - } - void visit (HIR::TraitBound &bound) override - { /* TODO */ - } - void visit (HIR::ImplTraitType &type) override - { /* TODO */ - } + // These dont need to be implemented as they are segments or part of types + void visit (HIR::TypePathSegmentFunction &segment) override {} + void visit (HIR::TraitBound &bound) override {} private: TypeCheckType (HirId id) diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc index 1e15157..212ab3f 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.cc +++ b/gcc/rust/typecheck/rust-substitution-mapper.cc @@ -346,6 +346,11 @@ SubstMapperInternal::visit (TyTy::DynamicObjectType &type) { resolved = type.clone (); } +void +SubstMapperInternal::visit (TyTy::OpaqueType &type) +{ + resolved = type.handle_substitions (mappings); +} // SubstMapperFromExisting diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index bcd93fd..bc54f56 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -63,6 +63,7 @@ public: void visit (TyTy::NeverType &) override { rust_unreachable (); } void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); } void visit (TyTy::ClosureType &) override { rust_unreachable (); } + void visit (TyTy::OpaqueType &) override { rust_unreachable (); } private: SubstMapper (HirId ref, HIR::GenericArgs *generics, @@ -107,6 +108,7 @@ public: void visit (TyTy::StrType &type) override; void visit (TyTy::NeverType &type) override; void visit (TyTy::DynamicObjectType &type) override; + void visit (TyTy::OpaqueType &type) override; private: SubstMapperInternal (HirId ref, TyTy::SubstitutionArgumentMappings &mappings); @@ -146,6 +148,7 @@ public: void visit (TyTy::PlaceholderType &) override { rust_unreachable (); } void visit (TyTy::ProjectionType &) override { rust_unreachable (); } void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); } + void visit (TyTy::OpaqueType &type) override { rust_unreachable (); } private: SubstMapperFromExisting (TyTy::BaseType *concrete, TyTy::BaseType *receiver); @@ -185,6 +188,7 @@ public: void visit (const TyTy::PlaceholderType &) override {} void visit (const TyTy::ProjectionType &) override {} void visit (const TyTy::DynamicObjectType &) override {} + void visit (const TyTy::OpaqueType &type) override {} private: GetUsedSubstArgs (); diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index fc35abb..9187fc6 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -136,6 +136,7 @@ TypeBoundsProbe::assemble_sized_builtin () case TyTy::NEVER: case TyTy::PLACEHOLDER: case TyTy::PROJECTION: + case TyTy::OPAQUE: assemble_builtin_candidate (LangItem::Kind::SIZED); break; diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index 00ac655..c42fdcd 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -61,6 +61,7 @@ public: void visit (ProjectionType &) override { rust_unreachable (); } void visit (DynamicObjectType &) override { rust_unreachable (); } void visit (ClosureType &type) override { rust_unreachable (); } + void visit (OpaqueType &type) override { rust_unreachable (); } // tuple-structs void visit (ADTType &type) override; diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index 7088b58..c897c13 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -431,6 +431,22 @@ public: } } + virtual void visit (const OpaqueType &type) override + { + ok = false; + if (emit_error_flag) + { + location_t ref_locus = mappings.lookup_location (type.get_ref ()); + location_t base_locus + = mappings.lookup_location (get_base ()->get_ref ()); + rich_location r (line_table, 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 ()), @@ -1571,6 +1587,23 @@ private: const DynamicObjectType *base; }; +class OpaqueCmp : public BaseCmp +{ + using Rust::TyTy::BaseCmp::visit; + +public: + OpaqueCmp (const OpaqueType *base, bool emit_errors) + : BaseCmp (base, emit_errors), base (base) + {} + + // TODO + +private: + const BaseType *get_base () const override { return base; } + + const OpaqueType *base; +}; + } // namespace TyTy } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h index 450e53e..d36afc8 100644 --- a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h +++ b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h @@ -168,6 +168,8 @@ public: { // TODO } + + void visit (OpaqueType &type) override {} }; /** Per crate context for generic type variance analysis. */ diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 85726ff..4f8e785 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -51,6 +51,7 @@ public: virtual void visit (ProjectionType &type) = 0; virtual void visit (DynamicObjectType &type) = 0; virtual void visit (ClosureType &type) = 0; + virtual void visit (OpaqueType &type) = 0; }; class TyConstVisitor @@ -80,6 +81,7 @@ public: virtual void visit (const ProjectionType &type) = 0; virtual void visit (const DynamicObjectType &type) = 0; virtual void visit (const ClosureType &type) = 0; + virtual void visit (const OpaqueType &type) = 0; }; } // namespace TyTy diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index fe4b8fc..5d5da4d 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -111,6 +111,9 @@ TypeKindFormat::to_string (TypeKind kind) case TypeKind::CLOSURE: return "Closure"; + case TypeKind::OPAQUE: + return "Opaque"; + case TypeKind::ERROR: return "ERROR"; } @@ -217,7 +220,7 @@ BaseType::is_unit () const case FLOAT: case USIZE: case ISIZE: - + case OPAQUE: case STR: case DYNAMIC: case ERROR: @@ -543,6 +546,17 @@ BaseType::destructure () const { x = p->get (); } + // else if (auto p = x->try_as<const OpaqueType> ()) + // { + // auto pr = p->resolve (); + + // rust_debug ("XXXXXX") + + // if (pr == x) + // return pr; + + // x = pr; + // } else { return x; @@ -792,6 +806,7 @@ BaseType::has_substitutions_defined () const case TUPLE: case PARAM: case PLACEHOLDER: + case OPAQUE: return false; case PROJECTION: { @@ -853,6 +868,7 @@ BaseType::needs_generic_substitutions () const case TUPLE: case PARAM: case PLACEHOLDER: + case OPAQUE: return false; case PROJECTION: { @@ -3415,6 +3431,140 @@ ParamType::is_implicit_self_trait () const return is_trait_self; } +// OpaqueType + +OpaqueType::OpaqueType (location_t locus, HirId ref, + std::vector<TypeBoundPredicate> specified_bounds, + std::set<HirId> refs) + : BaseType (ref, ref, KIND, + {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"), + locus}, + specified_bounds, refs) +{} + +OpaqueType::OpaqueType (location_t locus, HirId ref, HirId ty_ref, + std::vector<TypeBoundPredicate> specified_bounds, + std::set<HirId> refs) + : BaseType (ref, ty_ref, KIND, + {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"), + locus}, + specified_bounds, refs) +{} + +bool +OpaqueType::can_resolve () const +{ + return get_ref () != get_ty_ref (); +} + +void +OpaqueType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +void +OpaqueType::accept_vis (TyConstVisitor &vis) const +{ + vis.visit (*this); +} + +std::string +OpaqueType::as_string () const +{ + return get_name (); +} + +std::string +OpaqueType::get_name () const +{ + return "impl " + raw_bounds_as_name (); +} + +bool +OpaqueType::can_eq (const BaseType *other, bool emit_errors) const +{ + OpaqueCmp r (this, emit_errors); + return r.can_eq (other); +} + +BaseType * +OpaqueType::clone () const +{ + return new OpaqueType (ident.locus, get_ref (), get_ty_ref (), + get_specified_bounds (), get_combined_refs ()); +} + +BaseType * +OpaqueType::resolve () const +{ + TyVar var (get_ty_ref ()); + BaseType *r = var.get_tyty (); + + while (r->get_kind () == TypeKind::OPAQUE) + { + OpaqueType *rr = static_cast<OpaqueType *> (r); + if (!rr->can_resolve ()) + break; + + TyVar v (rr->get_ty_ref ()); + BaseType *n = v.get_tyty (); + + // fix infinite loop + if (r == n) + break; + + r = n; + } + + if (r->get_kind () == TypeKind::OPAQUE && (r->get_ref () == r->get_ty_ref ())) + return TyVar (r->get_ty_ref ()).get_tyty (); + + return r; +} + +bool +OpaqueType::is_equal (const BaseType &other) const +{ + auto other2 = static_cast<const OpaqueType &> (other); + if (can_resolve () != other2.can_resolve ()) + return false; + + if (can_resolve ()) + return resolve ()->can_eq (other2.resolve (), false); + + return bounds_compatible (other, UNDEF_LOCATION, false); +} + +OpaqueType * +OpaqueType::handle_substitions (SubstitutionArgumentMappings &subst_mappings) +{ + // SubstitutionArg arg = SubstitutionArg::error (); + // bool ok = subst_mappings.get_argument_for_symbol (this, &arg); + // if (!ok || arg.is_error ()) + // return this; + + // OpaqueType *p = static_cast<OpaqueType *> (clone ()); + // subst_mappings.on_param_subst (*p, arg); + + // // there are two cases one where we substitute directly to a new PARAM and + // // otherwise + // if (arg.get_tyty ()->get_kind () == TyTy::TypeKind::PARAM) + // { + // p->set_ty_ref (arg.get_tyty ()->get_ref ()); + // return p; + // } + + // // this is the new subst that this needs to pass + // p->set_ref (mappings.get_next_hir_id ()); + // p->set_ty_ref (arg.get_tyty ()->get_ref ()); + + // return p; + + rust_unreachable (); + return nullptr; +} + // StrType StrType::StrType (HirId ref, std::set<HirId> refs) diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 504a14e..f83caec 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -73,6 +73,7 @@ enum TypeKind PROJECTION, DYNAMIC, CLOSURE, + OPAQUE, // there are more to add... ERROR }; @@ -408,6 +409,39 @@ private: HIR::GenericParam ¶m; }; +class OpaqueType : public BaseType +{ +public: + static constexpr auto KIND = TypeKind::OPAQUE; + + OpaqueType (location_t locus, HirId ref, + std::vector<TypeBoundPredicate> specified_bounds, + std::set<HirId> refs = std::set<HirId> ()); + + OpaqueType (location_t locus, HirId ref, HirId ty_ref, + std::vector<TypeBoundPredicate> specified_bounds, + std::set<HirId> refs = std::set<HirId> ()); + + void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; + + std::string as_string () const override; + + bool can_eq (const BaseType *other, bool emit_errors) const override final; + + BaseType *clone () const final override; + + bool can_resolve () const; + + BaseType *resolve () const; + + std::string get_name () const override final; + + bool is_equal (const BaseType &other) const override; + + OpaqueType *handle_substitions (SubstitutionArgumentMappings &mappings); +}; + class StructFieldType { public: diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc index b779e7d..294b677 100644 --- a/gcc/rust/typecheck/rust-unify.cc +++ b/gcc/rust/typecheck/rust-unify.cc @@ -189,7 +189,7 @@ UnifyRules::go () == TyTy::InferType::GENERAL; bool expected_is_concrete = ltype->is_concrete () && !lhs_is_general_infer_var; - bool rneeds_infer = expected_is_concrete && rgot_param; + bool rneeds_infer = expected_is_concrete && (rgot_param); bool lgot_param = ltype->get_kind () == TyTy::TypeKind::PARAM; bool rhs_is_infer_var = rtype->get_kind () == TyTy::TypeKind::INFER; @@ -199,7 +199,7 @@ UnifyRules::go () == TyTy::InferType::GENERAL; bool receiver_is_concrete = rtype->is_concrete () && !rhs_is_general_infer_var; - bool lneeds_infer = receiver_is_concrete && lgot_param; + bool lneeds_infer = receiver_is_concrete && (lgot_param); if (rneeds_infer) { @@ -312,6 +312,9 @@ UnifyRules::go () case TyTy::CLOSURE: return expect_closure (static_cast<TyTy::ClosureType *> (ltype), rtype); + case TyTy::OPAQUE: + return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype); + case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -400,7 +403,8 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype, case TyTy::PLACEHOLDER: case TyTy::PROJECTION: case TyTy::DYNAMIC: - case TyTy::CLOSURE: { + case TyTy::CLOSURE: + case TyTy::OPAQUE: { bool is_valid = (ltype->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); if (is_valid) @@ -528,6 +532,7 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -572,6 +577,7 @@ UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -642,6 +648,7 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -712,6 +719,7 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -773,6 +781,7 @@ UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -832,6 +841,7 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -890,6 +900,7 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -980,6 +991,7 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1096,6 +1108,7 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1166,6 +1179,7 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1213,6 +1227,7 @@ UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1260,6 +1275,7 @@ UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1314,6 +1330,7 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1368,6 +1385,7 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1422,6 +1440,7 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1469,6 +1488,7 @@ UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1516,6 +1536,7 @@ UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype) case TyTy::PROJECTION: case TyTy::DYNAMIC: case TyTy::CLOSURE: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1581,6 +1602,7 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype, case TyTy::USIZE: case TyTy::ISIZE: case TyTy::NEVER: + case TyTy::OPAQUE: if (infer_flag) return rtype->clone (); gcc_fallthrough (); @@ -1632,6 +1654,7 @@ UnifyRules::expect_projection (TyTy::ProjectionType *ltype, case TyTy::ISIZE: case TyTy::NEVER: case TyTy::PLACEHOLDER: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1690,6 +1713,7 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype) case TyTy::NEVER: case TyTy::PLACEHOLDER: case TyTy::PROJECTION: + case TyTy::OPAQUE: case TyTy::ERROR: return new TyTy::ErrorType (0); } @@ -1760,6 +1784,65 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype) case TyTy::PLACEHOLDER: case TyTy::PROJECTION: case TyTy::DYNAMIC: + case TyTy::OPAQUE: + case TyTy::ERROR: + return new TyTy::ErrorType (0); + } + return new TyTy::ErrorType (0); +} + +TyTy::BaseType * +UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype) +{ + switch (rtype->get_kind ()) + { + case TyTy::INFER: { + TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype); + bool is_valid + = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL; + if (is_valid) + return ltype->clone (); + } + break; + + case TyTy::OPAQUE: { + auto &type = *static_cast<TyTy::OpaqueType *> (rtype); + if (ltype->num_specified_bounds () != type.num_specified_bounds ()) + { + return new TyTy::ErrorType (0); + } + + if (!ltype->bounds_compatible (type, locus, true)) + { + return new TyTy::ErrorType (0); + } + + return ltype->clone (); + } + break; + + case TyTy::CLOSURE: + case TyTy::SLICE: + case TyTy::PARAM: + case TyTy::POINTER: + case TyTy::STR: + case TyTy::ADT: + case TyTy::REF: + case TyTy::ARRAY: + case TyTy::FNDEF: + case TyTy::FNPTR: + case TyTy::TUPLE: + case TyTy::BOOL: + case TyTy::CHAR: + case TyTy::INT: + case TyTy::UINT: + case TyTy::FLOAT: + case TyTy::USIZE: + case TyTy::ISIZE: + case TyTy::NEVER: + case TyTy::PLACEHOLDER: + case TyTy::PROJECTION: + case TyTy::DYNAMIC: case TyTy::ERROR: return new TyTy::ErrorType (0); } diff --git a/gcc/rust/typecheck/rust-unify.h b/gcc/rust/typecheck/rust-unify.h index 20f7b4e..5ff3b7c 100644 --- a/gcc/rust/typecheck/rust-unify.h +++ b/gcc/rust/typecheck/rust-unify.h @@ -82,6 +82,8 @@ protected: TyTy::BaseType *rtype); TyTy::BaseType *expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype); + TyTy::BaseType *expect_opaque (TyTy::OpaqueType *ltype, + TyTy::BaseType *rtype); private: UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs, |