@@ -3259,20 +3259,30 @@ llvm::Function *irgen::getOrCreateTypeMetadataAccessFunction(IRGenModule &IGM,
3259
3259
}
3260
3260
3261
3261
namespace {
3262
- // / A visitor class for emitting a reference to type metatype for a
3263
- // / SILType, i.e. a lowered representation type. In general, the type
3264
- // / metadata produced here might not correspond to the formal type that
3265
- // / would belong to the unlowered type. For correctness, it is important
3266
- // / not to cache the result as if it were the metadata for a formal type
3267
- // / unless the type actually cannot possibly be a formal type, e.g. because
3268
- // / it is one of the special lowered type kinds like SILFunctionType.
3262
+ // / A visitor class for rewriting a lowered (SIL) type to a formal
3263
+ // / type with the same type layout that we can fetch metadata for.
3264
+ // / We need type metadata in order to do value operations on some
3265
+ // / lowered types (like allocating or copying them), but we can
3266
+ // / only fetch type metadata for formal types. We can't reliably
3267
+ // / reverse the type lowering process to get the original formal
3268
+ // / type, but we should be able to reliably find a formal type with
3269
+ // / the same layout as a lowered type.
3270
+ // /
3271
+ // / We can't reliably do this on types expressed in terms of builtin
3272
+ // / types, because there aren't type metadata for all builtin types.
3273
+ // / Fortunately, we really shouldn't need type metadata to do value
3274
+ // / operations on builtin types, and we shouldn't ever see compound
3275
+ // / types with them that would require metadata to manipulate (like
3276
+ // / a tuple of a builtin type and a resilient type) --- we can rely
3277
+ // / on stdlib programmers to not write such types, and we can rely on
3278
+ // / SIL transformations not introducing them unnecessarily.
3269
3279
// /
3270
3280
// / NOTE: If you modify the special cases in this, you should update
3271
3281
// / isTypeMetadataForLayoutAccessible in SIL.cpp.
3272
- class EmitTypeMetadataRefForLayout
3273
- : public CanTypeVisitor<EmitTypeMetadataRefForLayout , CanType> {
3282
+ class GetFormalTypeWithSameLayout
3283
+ : public CanTypeVisitor<GetFormalTypeWithSameLayout , CanType> {
3274
3284
public:
3275
- EmitTypeMetadataRefForLayout () {}
3285
+ GetFormalTypeWithSameLayout () {}
3276
3286
3277
3287
// / For most types, we can just emit the usual metadata.
3278
3288
CanType visitType (CanType t) { return t; }
@@ -3293,15 +3303,14 @@ class EmitTypeMetadataRefForLayout
3293
3303
}
3294
3304
3295
3305
CanType visitPackType (CanPackType ty) {
3296
- llvm_unreachable (" " );
3306
+ llvm_unreachable (" requesting type metadata for a pack type? " );
3297
3307
}
3298
3308
3299
3309
CanType visitPackExpansionType (CanPackExpansionType ty) {
3300
- return ty;
3301
- }
3302
-
3303
- CanType visitPackElementType (CanPackElementType ty) {
3304
- llvm_unreachable (" not implemented for PackElementType" );
3310
+ CanType pattern = ty.getPatternType ();
3311
+ CanType loweredPattern = visit (ty.getPatternType ());
3312
+ if (pattern == loweredPattern) return ty;
3313
+ return CanPackExpansionType::get (loweredPattern, ty.getCountType ());
3305
3314
}
3306
3315
3307
3316
CanType visitTupleType (CanTupleType ty) {
@@ -3399,7 +3408,7 @@ IRGenFunction::emitTypeMetadataRefForLayout(SILType ty,
3399
3408
3400
3409
// Map to a layout equivalent AST type.
3401
3410
auto layoutEquivalentType =
3402
- EmitTypeMetadataRefForLayout ().visit (ty.getASTType ());
3411
+ GetFormalTypeWithSameLayout ().visit (ty.getASTType ());
3403
3412
auto response = emitTypeMetadataRef (layoutEquivalentType, request);
3404
3413
setScopedLocalTypeMetadataForLayout (ty.getObjectType (), response);
3405
3414
return response.getMetadata ();
0 commit comments