@@ -297,31 +297,31 @@ class RecordTypeInfoImpl : public Base,
297297 std::function<void
298298 (const TypeInfo &, SILType, Address, Address)> body) const {
299299 if (rawLayout->shouldMoveAsLikeType ()) {
300- // Because we have a rawlayout attribute, we know this has to be a struct.
301- auto structDecl = T.getStructOrBoundGenericStruct ();
302-
303- if (auto likeType = rawLayout->getResolvedScalarLikeType (structDecl)) {
304- auto astT = T.getASTType ();
305- auto subs = astT->getContextSubstitutionMap ();
306- auto loweredLikeType = IGF.IGM .getLoweredType (likeType->subst (subs));
307- auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
308-
300+ auto likeType = T.getRawLayoutSubstitutedLikeType ();
301+ auto loweredLikeType = IGF.IGM .getLoweredType (likeType);
302+ auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
303+
304+ // Fixup src/dest address element types because currently they are in
305+ // terms of the raw layout type's [n x i8] where we're at a point to use
306+ // the like type's concrete storage type.
307+ src = Address (src.getAddress (), likeTypeInfo.getStorageType (),
308+ src.getAlignment ());
309+ dest = Address (dest.getAddress (), likeTypeInfo.getStorageType (),
310+ dest.getAlignment ());
311+
312+ // If we're a scalar, then we only need to run the body once.
313+ if (rawLayout->getScalarLikeType ()) {
309314 body (likeTypeInfo, loweredLikeType, dest, src);
310315 }
311316
312- if (auto likeArray = rawLayout->getResolvedArrayLikeTypeAndCount (structDecl)) {
313- auto likeType = likeArray->first ;
314- auto countType = likeArray->second ;
315-
316- auto astT = T.getASTType ();
317- auto subs = astT->getContextSubstitutionMap ();
318- auto loweredLikeType = IGF.IGM .getLoweredType (likeType.subst (subs));
319- auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
320- countType = countType.subst (subs);
317+ // Otherwise, emit a loop that calls body N times where N is the count
318+ // of the array variant. This could be generic in which case we need to
319+ // pull the value out of metadata or it could be a constant integer.
320+ if (rawLayout->getArrayLikeTypeAndCount ()) {
321+ auto countType = T.getRawLayoutSubstitutedCountType ()->getCanonicalType ();
321322
322- IGF.emitLoopOverElements (likeTypeInfo, loweredLikeType,
323- countType->getCanonicalType (), dest, src,
324- [&](Address dest, Address src) {
323+ IGF.emitLoopOverElements (likeTypeInfo, loweredLikeType, countType,
324+ dest, src, [&](Address dest, Address src) {
325325 body (likeTypeInfo, loweredLikeType, dest, src);
326326 });
327327 }
@@ -555,6 +555,23 @@ class RecordTypeInfoImpl : public Base,
555555 auto fType = field.getType (collector.IGF .IGM , T);
556556 field.getTypeInfo ().collectMetadataForOutlining (collector, fType );
557557 }
558+
559+ // If we're a raw layout type, collect metadata from our like type and count
560+ // as well.
561+ if (auto likeType = T.getRawLayoutSubstitutedLikeType ()) {
562+ auto loweredLikeType = collector.IGF .IGM .getLoweredType (likeType);
563+ collector.IGF .IGM .getTypeInfo (loweredLikeType)
564+ .collectMetadataForOutlining (collector, loweredLikeType);
565+
566+ if (auto countType = T.getRawLayoutSubstitutedCountType ()) {
567+ if (countType->isValueParameter ()) {
568+ auto loweredCountType = collector.IGF .IGM .getLoweredType (countType);
569+ collector.IGF .IGM .getTypeInfo (loweredCountType)
570+ .collectMetadataForOutlining (collector, loweredCountType);
571+ }
572+ }
573+ }
574+
558575 collector.collectTypeMetadata (T);
559576 }
560577};
0 commit comments