Skip to content

Commit 96fc83f

Browse files
authored
Merge pull request #67451 from rjmccall/translate-expansion-pattern-for-layout-5.9
[5.9] Translate the pattern type of a pack expansion when emitting type metadata for layout
2 parents 28d4c80 + 53d5038 commit 96fc83f

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

lib/IRGen/MetadataRequest.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3259,20 +3259,30 @@ llvm::Function *irgen::getOrCreateTypeMetadataAccessFunction(IRGenModule &IGM,
32593259
}
32603260

32613261
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.
32693279
///
32703280
/// NOTE: If you modify the special cases in this, you should update
32713281
/// isTypeMetadataForLayoutAccessible in SIL.cpp.
3272-
class EmitTypeMetadataRefForLayout
3273-
: public CanTypeVisitor<EmitTypeMetadataRefForLayout, CanType> {
3282+
class GetFormalTypeWithSameLayout
3283+
: public CanTypeVisitor<GetFormalTypeWithSameLayout, CanType> {
32743284
public:
3275-
EmitTypeMetadataRefForLayout() {}
3285+
GetFormalTypeWithSameLayout() {}
32763286

32773287
/// For most types, we can just emit the usual metadata.
32783288
CanType visitType(CanType t) { return t; }
@@ -3293,15 +3303,14 @@ class EmitTypeMetadataRefForLayout
32933303
}
32943304

32953305
CanType visitPackType(CanPackType ty) {
3296-
llvm_unreachable("");
3306+
llvm_unreachable("requesting type metadata for a pack type?");
32973307
}
32983308

32993309
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());
33053314
}
33063315

33073316
CanType visitTupleType(CanTupleType ty) {
@@ -3399,7 +3408,7 @@ IRGenFunction::emitTypeMetadataRefForLayout(SILType ty,
33993408

34003409
// Map to a layout equivalent AST type.
34013410
auto layoutEquivalentType =
3402-
EmitTypeMetadataRefForLayout().visit(ty.getASTType());
3411+
GetFormalTypeWithSameLayout().visit(ty.getASTType());
34033412
auto response = emitTypeMetadataRef(layoutEquivalentType, request);
34043413
setScopedLocalTypeMetadataForLayout(ty.getObjectType(), response);
34053414
return response.getMetadata();

test/IRGen/variadic_generics.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,19 @@ bb0:
183183
%len = pack_length $Pack{repeat each T, repeat each T, Int, Float, String}
184184
return %len : $Builtin.Word
185185
}
186+
187+
// Translate the pattern type of a pack expansion type when
188+
// emitting tuple type metadata for layout. rdar://110971671
189+
190+
// CHECK-LABEL: define{{.*}} @test_pack_expansion_for_layout
191+
// CHECK: [[PACK_LEN:%.*]] = add [[INT]] %0, 1
192+
// CHECK-NEXT: [[VANISHES:%.*]] = icmp eq [[INT]] [[PACK_LEN]], 1
193+
// CHECK-NEXT: br i1 [[VANISHES]],
194+
// CHECK: call swiftcc %swift.metadata_response @swift_getTupleTypeMetadata(
195+
sil @test_pack_expansion_for_layout : $<each T> () -> () {
196+
bb0:
197+
%tuple = alloc_stack $(Int, repeat () async throws -> each T)
198+
dealloc_stack %tuple : $*(Int, repeat () async throws -> each T)
199+
%result = tuple ()
200+
return %result : $()
201+
}

0 commit comments

Comments
 (0)