@@ -38,6 +38,10 @@ class AssociatedImplTrait;
} // namespace Resolver
namespace TyTy {
+class ClosureType;
+class FnPtr;
+class FnType;
+class CallableTypeInterface;
// https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
@@ -242,6 +246,22 @@ protected:
Analysis::Mappings *mappings;
};
+/** Unified interface for all function-like types. */
+class CallableTypeInterface : public BaseType
+{
+public:
+ explicit CallableTypeInterface (HirId ref, HirId ty_ref, TypeKind kind,
+ RustIdent ident,
+ std::set<HirId> refs = std::set<HirId> ())
+ : BaseType (ref, ty_ref, kind, ident, refs)
+ {}
+
+ WARN_UNUSED_RESULT virtual size_t get_num_params () const = 0;
+ WARN_UNUSED_RESULT virtual BaseType *
+ get_param_type_at (size_t index) const = 0;
+ WARN_UNUSED_RESULT virtual BaseType *get_return_type () const = 0;
+};
+
class InferType : public BaseType
{
public:
@@ -736,7 +756,7 @@ private:
ReprOptions repr;
};
-class FnType : public BaseType, public SubstitutionRef
+class FnType : public CallableTypeInterface, public SubstitutionRef
{
public:
static constexpr auto KIND = TypeKind::FNDEF;
@@ -751,7 +771,7 @@ public:
std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ref, TypeKind::FNDEF, ident, refs),
+ : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
SubstitutionRef (std::move (subst_refs),
SubstitutionArgumentMappings::error ()),
params (std::move (params)), type (type), flags (flags),
@@ -766,7 +786,7 @@ public:
std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ty_ref, TypeKind::FNDEF, ident, refs),
+ : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
SubstitutionRef (std::move (subst_refs),
SubstitutionArgumentMappings::error ()),
params (params), type (type), flags (flags), identifier (identifier),
@@ -832,8 +852,6 @@ public:
return params.at (idx);
}
- BaseType *get_return_type () const { return type; }
-
BaseType *clone () const final override;
FnType *
@@ -842,6 +860,21 @@ public:
ABI get_abi () const { return abi; }
uint8_t get_flags () const { return flags; }
+ WARN_UNUSED_RESULT size_t get_num_params () const override
+ {
+ return params.size ();
+ }
+
+ WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
+ {
+ return param_at (index).second;
+ }
+
+ WARN_UNUSED_RESULT BaseType *get_return_type () const override
+ {
+ return type;
+ }
+
private:
std::vector<std::pair<HIR::Pattern *, BaseType *>> params;
BaseType *type;
@@ -851,33 +884,50 @@ private:
ABI abi;
};
-class FnPtr : public BaseType
+class FnPtr : public CallableTypeInterface
{
public:
static constexpr auto KIND = TypeKind::FNPTR;
FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ref, TypeKind::FNPTR,
- {Resolver::CanonicalPath::create_empty (), locus}, refs),
+ : CallableTypeInterface (ref, ref, TypeKind::FNPTR,
+ {Resolver::CanonicalPath::create_empty (), locus},
+ refs),
params (std::move (params)), result_type (result_type)
{}
FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ty_ref, TypeKind::FNPTR,
- {Resolver::CanonicalPath::create_empty (), locus}, refs),
+ : CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
+ {Resolver::CanonicalPath::create_empty (), locus},
+ refs),
params (params), result_type (result_type)
{}
std::string get_name () const override final { return as_string (); }
- BaseType *get_return_type () const { return result_type.get_tyty (); }
+ WARN_UNUSED_RESULT size_t get_num_params () const override
+ {
+ return params.size ();
+ }
+
+ WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
+ {
+ return params.at (index).get_tyty ();
+ }
+
+ WARN_UNUSED_RESULT BaseType *get_return_type () const override
+ {
+ return result_type.get_tyty ();
+ }
+
const TyVar &get_var_return_type () const { return result_type; }
size_t num_params () const { return params.size (); }
- BaseType *param_at (size_t idx) const { return params.at (idx).get_tyty (); }
+ // DEPRECATED: Use get_param_type_at
+ BaseType *param_at (size_t idx) const { return get_param_type_at (idx); }
void accept_vis (TyVisitor &vis) override;
void accept_vis (TyConstVisitor &vis) const override;
@@ -898,19 +948,19 @@ private:
TyVar result_type;
};
-class ClosureType : public BaseType, public SubstitutionRef
+class ClosureType : public CallableTypeInterface, public SubstitutionRef
{
public:
static constexpr auto KIND = TypeKind::CLOSURE;
- ClosureType (HirId ref, DefId id, RustIdent ident,
- TyTy::TupleType *parameters, TyVar result_type,
+ ClosureType (HirId ref, DefId id, RustIdent ident, TupleType *parameters,
+ TyVar result_type,
std::vector<SubstitutionParamMapping> subst_refs,
std::set<NodeId> captures,
std::set<HirId> refs = std::set<HirId> (),
std::vector<TypeBoundPredicate> specified_bounds
= std::vector<TypeBoundPredicate> ())
- : BaseType (ref, ref, TypeKind::CLOSURE, ident, refs),
+ : CallableTypeInterface (ref, ref, TypeKind::CLOSURE, ident, refs),
SubstitutionRef (std::move (subst_refs),
SubstitutionArgumentMappings::error ()),
parameters (parameters), result_type (std::move (result_type)), id (id),
@@ -922,13 +972,13 @@ public:
}
ClosureType (HirId ref, HirId ty_ref, RustIdent ident, DefId id,
- TyTy::TupleType *parameters, TyVar result_type,
+ TupleType *parameters, TyVar result_type,
std::vector<SubstitutionParamMapping> subst_refs,
std::set<NodeId> captures,
std::set<HirId> refs = std::set<HirId> (),
std::vector<TypeBoundPredicate> specified_bounds
= std::vector<TypeBoundPredicate> ())
- : BaseType (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
+ : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
SubstitutionRef (std::move (subst_refs),
SubstitutionArgumentMappings::error ()),
parameters (parameters), result_type (std::move (result_type)), id (id),
@@ -942,6 +992,21 @@ public:
void accept_vis (TyVisitor &vis) override;
void accept_vis (TyConstVisitor &vis) const override;
+ WARN_UNUSED_RESULT size_t get_num_params () const override
+ {
+ return parameters->num_fields ();
+ }
+
+ WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
+ {
+ return parameters->get_field (index);
+ }
+
+ WARN_UNUSED_RESULT BaseType *get_return_type () const override
+ {
+ return result_type.get_tyty ();
+ }
+
std::string as_string () const override;
std::string get_name () const override final { return as_string (); }
@@ -1495,6 +1560,21 @@ private:
DefId item;
};
+template <>
+WARN_UNUSED_RESULT inline bool
+BaseType::is<CallableTypeInterface> () const
+{
+ auto kind = this->get_kind ();
+ return kind == FNPTR || kind == FNDEF || kind == CLOSURE;
+}
+
+template <>
+WARN_UNUSED_RESULT inline bool
+BaseType::is<const CallableTypeInterface> () const
+{
+ return this->is<CallableTypeInterface> ();
+}
+
} // namespace TyTy
} // namespace Rust