aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-02-16 01:42:05 +0000
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-24 13:07:06 +0100
commit3e589260b4edf4a1eeb0934de65a8c5d0c6c73b3 (patch)
treee40b35096dc63525d92022ee6d33ad92880bdd8e
parent271a348960418b579787858072880f35da47c59c (diff)
downloadgcc-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.cc6
-rw-r--r--gcc/rust/backend/rust-compile-type.h1
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h1
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-place.h1
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc37
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h13
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc5
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h4
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc1
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h1
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h33
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis-private.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc152
-rw-r--r--gcc/rust/typecheck/rust-tyty.h34
-rw-r--r--gcc/rust/typecheck/rust-unify.cc89
-rw-r--r--gcc/rust/typecheck/rust-unify.h2
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 &param, 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 &param;
};
+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,