@@ -297,9 +297,10 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
297297 IsNonAccessing : 1
298298 );
299299
300- SWIFT_INLINE_BITFIELD_FULL (ErasureExpr, ImplicitConversionExpr, 32 ,
300+ SWIFT_INLINE_BITFIELD_FULL (ErasureExpr, ImplicitConversionExpr, 32 + 20 ,
301301 : NumPadBits,
302- NumConformances : 32
302+ NumConformances : 32 ,
303+ NumArgumentConversions : 20
303304 );
304305
305306 SWIFT_INLINE_BITFIELD_FULL (UnresolvedSpecializeExpr, Expr, 32 ,
@@ -3244,20 +3245,35 @@ class CollectionUpcastConversionExpr : public ImplicitConversionExpr {
32443245// / "Appropriate kind" means e.g. a concrete/existential metatype if the
32453246// / result is an existential metatype.
32463247class ErasureExpr final : public ImplicitConversionExpr,
3247- private llvm::TrailingObjects<ErasureExpr, ProtocolConformanceRef> {
3248+ private llvm::TrailingObjects<ErasureExpr, ProtocolConformanceRef,
3249+ CollectionUpcastConversionExpr::ConversionPair> {
32483250 friend TrailingObjects;
3251+ using ConversionPair = CollectionUpcastConversionExpr::ConversionPair;
32493252
32503253 ErasureExpr (Expr *subExpr, Type type,
3251- ArrayRef<ProtocolConformanceRef> conformances)
3254+ ArrayRef<ProtocolConformanceRef> conformances,
3255+ ArrayRef<ConversionPair> argConversions)
32523256 : ImplicitConversionExpr(ExprKind::Erasure, subExpr, type) {
32533257 Bits.ErasureExpr .NumConformances = conformances.size ();
32543258 std::uninitialized_copy (conformances.begin (), conformances.end (),
32553259 getTrailingObjects<ProtocolConformanceRef>());
3260+
3261+ Bits.ErasureExpr .NumArgumentConversions = argConversions.size ();
3262+ std::uninitialized_copy (argConversions.begin (), argConversions.end (),
3263+ getTrailingObjects<ConversionPair>());
32563264 }
32573265
32583266public:
32593267 static ErasureExpr *create (ASTContext &ctx, Expr *subExpr, Type type,
3260- ArrayRef<ProtocolConformanceRef> conformances);
3268+ ArrayRef<ProtocolConformanceRef> conformances,
3269+ ArrayRef<ConversionPair> argConversions);
3270+
3271+ size_t numTrailingObjects (OverloadToken<ProtocolConformanceRef>) const {
3272+ return Bits.ErasureExpr .NumConformances ;
3273+ }
3274+ size_t numTrailingObjects (OverloadToken<ConversionPair>) const {
3275+ return Bits.ErasureExpr .NumArgumentConversions ;
3276+ }
32613277
32623278 // / Retrieve the mapping specifying how the type of the subexpression
32633279 // / maps to the resulting existential type. If the resulting existential
@@ -3274,6 +3290,30 @@ class ErasureExpr final : public ImplicitConversionExpr,
32743290 Bits.ErasureExpr .NumConformances };
32753291 }
32763292
3293+ // / Retrieve the conversion expressions mapping requirements from any
3294+ // / parameterized existentials involved in this erasure.
3295+ // /
3296+ // / If the destination type is not a parameterized protocol type,
3297+ // / this array will be empty
3298+ ArrayRef<ConversionPair> getArgumentConversions () const {
3299+ return {getTrailingObjects<ConversionPair>(),
3300+ Bits.ErasureExpr .NumArgumentConversions };
3301+ }
3302+
3303+ // / Retrieve the conversion expressions mapping requirements from any
3304+ // / parameterized existentials involved in this erasure.
3305+ // /
3306+ // / If the destination type is not a parameterized protocol type,
3307+ // / this array will be empty
3308+ MutableArrayRef<ConversionPair> getArgumentConversions () {
3309+ return {getTrailingObjects<ConversionPair>(),
3310+ Bits.ErasureExpr .NumArgumentConversions };
3311+ }
3312+
3313+ void setArgumentConversion (unsigned i, const ConversionPair &p) {
3314+ getArgumentConversions ()[i] = p;
3315+ }
3316+
32773317 static bool classof (const Expr *E) {
32783318 return E->getKind () == ExprKind::Erasure;
32793319 }
0 commit comments