@@ -990,6 +990,35 @@ namespace {
990990 return IGM.typeLayoutCache .getOrCreateResilientEntry (T);
991991 }
992992
993+ auto decl = T.getASTType ()->getStructOrBoundGenericStruct ();
994+ auto rawLayout = decl->getAttrs ().getAttribute <RawLayoutAttr>();
995+
996+ // If we have a raw layout struct who is fixed size, it means the
997+ // layout of the struct is fully concrete.
998+ if (rawLayout) {
999+ // Defer to this fixed type info for type layout if the raw layout
1000+ // specifies size and alignment.
1001+ if (rawLayout->getSizeAndAlignment ()) {
1002+ return IGM.typeLayoutCache .getOrCreateTypeInfoBasedEntry (*this , T);
1003+ }
1004+
1005+ auto likeType = rawLayout->getResolvedLikeType (decl)->getCanonicalType ();
1006+ SILType loweredLikeType = IGM.getLoweredType (likeType);
1007+
1008+ // The given struct type T that we're building is fully concrete, but
1009+ // our like type is still in terms of the potential archetype of the
1010+ // type.
1011+ auto subs = T.getASTType ()->getContextSubstitutionMap (
1012+ IGM.getSwiftModule (), decl);
1013+
1014+ loweredLikeType = loweredLikeType.subst (IGM.getSILModule (), subs);
1015+
1016+ // Array like raw layouts are still handled correctly even though the
1017+ // type layout entry is only that of the like type.
1018+ return IGM.getTypeInfo (loweredLikeType)
1019+ .buildTypeLayoutEntry (IGM, loweredLikeType, useStructLayouts);
1020+ }
1021+
9931022 std::vector<TypeLayoutEntry *> fields;
9941023 for (auto &field : getFields ()) {
9951024 auto fieldTy = field.getType (IGM, T);
@@ -1082,27 +1111,19 @@ namespace {
10821111 return IGM.typeLayoutCache .getOrCreateResilientEntry (T);
10831112 }
10841113
1085- std::vector<TypeLayoutEntry *> fields;
1086- for (auto &field : getFields ()) {
1087- auto fieldTy = field.getType (IGM, T);
1088- fields.push_back (
1089- field.getTypeInfo ().buildTypeLayoutEntry (IGM, fieldTy, useStructLayouts));
1090- }
1091-
10921114 auto decl = T.getASTType ()->getStructOrBoundGenericStruct ();
10931115 auto rawLayout = decl->getAttrs ().getAttribute <RawLayoutAttr>();
10941116
10951117 // If we have a raw layout struct who is non-fixed size, it means the
10961118 // layout of the struct is dependent on the archetype of the thing it's
10971119 // like.
10981120 if (rawLayout) {
1099- SILType loweredLikeType;
1121+ // Note: We don't have to handle the size and alignment case here for
1122+ // raw layout because those are always fixed, so only dependent layouts
1123+ // will be non-fixed.
11001124
1101- if (auto likeType = rawLayout->getResolvedScalarLikeType (decl)) {
1102- loweredLikeType = IGM.getLoweredType (*likeType);
1103- } else if (auto likeArray = rawLayout->getResolvedArrayLikeTypeAndCount (decl)) {
1104- loweredLikeType = IGM.getLoweredType (likeArray->first );
1105- }
1125+ auto likeType = rawLayout->getResolvedLikeType (decl)->getCanonicalType ();
1126+ SILType loweredLikeType = IGM.getLoweredType (likeType);
11061127
11071128 // The given struct type T that we're building may be in a generic
11081129 // environment that is different than that which was built our
@@ -1113,10 +1134,18 @@ namespace {
11131134
11141135 loweredLikeType = loweredLikeType.subst (IGM.getSILModule (), subs);
11151136
1116- return IGM.getTypeInfo (loweredLikeType).buildTypeLayoutEntry (IGM,
1117- loweredLikeType, useStructLayouts);
1137+ // Array like raw layouts are still handled correctly even though the
1138+ // type layout entry is only that of the like type.
1139+ return IGM.getTypeInfo (loweredLikeType)
1140+ .buildTypeLayoutEntry (IGM, loweredLikeType, useStructLayouts);
11181141 }
11191142
1143+ std::vector<TypeLayoutEntry *> fields;
1144+ for (auto &field : getFields ()) {
1145+ auto fieldTy = field.getType (IGM, T);
1146+ fields.push_back (
1147+ field.getTypeInfo ().buildTypeLayoutEntry (IGM, fieldTy, useStructLayouts));
1148+ }
11201149 assert (!fields.empty () &&
11211150 " Empty structs should not be NonFixedStructTypeInfo" );
11221151
0 commit comments