1111// ===----------------------------------------------------------------------===//
1212
1313#include " ArgumentSource.h"
14+ #include " Conversion.h"
1415#include " Initialization.h"
1516#include " LValue.h"
1617#include " RValue.h"
@@ -901,72 +902,71 @@ static ManagedValue emitSelfForMemberInit(SILGenFunction &SGF, SILLocation loc,
901902 SGFAccessKind::Write);
902903}
903904
904- static LValue emitLValueForMemberInit (SILGenFunction &SGF, SILLocation loc,
905- VarDecl *selfDecl,
906- VarDecl *property) {
907- CanType selfFormalType = selfDecl->getType ()->getCanonicalType ();
908- auto self = emitSelfForMemberInit (SGF, loc, selfDecl);
909- return SGF.emitPropertyLValue (loc, self, selfFormalType, property,
910- LValueOptions (), SGFAccessKind::Write,
911- AccessSemantics::DirectToStorage);
912- }
913-
914- // / Emit a member initialization for the members described in the
915- // / given pattern from the given source value.
916- static void emitMemberInit (SILGenFunction &SGF, VarDecl *selfDecl,
917- Pattern *pattern, RValue &&src) {
905+ // FIXME: Can emitMemberInit() share code with InitializationForPattern in
906+ // SILGenDecl.cpp? Note that this version operates on stored properties of
907+ // types, whereas the former only knows how to handle local bindings, but
908+ // we could generalize it.
909+ static InitializationPtr
910+ emitMemberInit (SILGenFunction &SGF, VarDecl *selfDecl, Pattern *pattern) {
918911 switch (pattern->getKind ()) {
919912 case PatternKind::Paren:
920913 return emitMemberInit (SGF, selfDecl,
921- cast<ParenPattern>(pattern)->getSubPattern (),
922- std::move (src));
914+ cast<ParenPattern>(pattern)->getSubPattern ());
923915
924916 case PatternKind::Tuple: {
917+ TupleInitialization *init = new TupleInitialization ();
925918 auto tuple = cast<TuplePattern>(pattern);
926- auto fields = tuple->getElements ();
927-
928- SmallVector<RValue, 4 > elements;
929- std::move (src).extractElements (elements);
930- for (unsigned i = 0 , n = fields.size (); i != n; ++i) {
931- emitMemberInit (SGF, selfDecl, fields[i].getPattern (),
932- std::move (elements[i]));
919+ for (auto &elt : tuple->getElements ()) {
920+ init->SubInitializations .push_back (
921+ emitMemberInit (SGF, selfDecl, elt.getPattern ()));
933922 }
934- break ;
923+ return InitializationPtr (init) ;
935924 }
936925
937926 case PatternKind::Named: {
938927 auto named = cast<NamedPattern>(pattern);
939- // Form the lvalue referencing this member.
940- FormalEvaluationScope scope (SGF);
941- LValue memberRef = emitLValueForMemberInit (SGF, pattern, selfDecl,
942- named->getDecl ());
943928
944- // Assign to it.
945- SGF.emitAssignToLValue (pattern, std::move (src), std::move (memberRef));
946- return ;
929+ auto self = emitSelfForMemberInit (SGF, pattern, selfDecl);
930+
931+ auto *field = named->getDecl ();
932+
933+ auto selfTy = self.getType ();
934+ auto fieldTy =
935+ selfTy.getFieldType (field, SGF.SGM .M , SGF.getTypeExpansionContext ());
936+ SILValue slot;
937+
938+ if (auto *structDecl = dyn_cast<StructDecl>(field->getDeclContext ())) {
939+ slot = SGF.B .createStructElementAddr (pattern, self.forward (SGF), field,
940+ fieldTy.getAddressType ());
941+ } else {
942+ assert (isa<ClassDecl>(field->getDeclContext ()));
943+ slot = SGF.B .createRefElementAddr (pattern, self.forward (SGF), field,
944+ fieldTy.getAddressType ());
945+ }
946+
947+ return InitializationPtr (new KnownAddressInitialization (slot));
947948 }
948949
949950 case PatternKind::Any:
950- return ;
951+ return InitializationPtr ( new BlackHoleInitialization ()); ;
951952
952953 case PatternKind::Typed:
953954 return emitMemberInit (SGF, selfDecl,
954- cast<TypedPattern>(pattern)->getSubPattern (),
955- std::move (src));
955+ cast<TypedPattern>(pattern)->getSubPattern ());
956956
957957 case PatternKind::Binding:
958958 return emitMemberInit (SGF, selfDecl,
959- cast<BindingPattern>(pattern)->getSubPattern (),
960- std::move (src));
959+ cast<BindingPattern>(pattern)->getSubPattern ());
961960
962961#define PATTERN (Name, Parent )
963962#define REFUTABLE_PATTERN (Name, Parent ) case PatternKind::Name:
964963#include " swift/AST/PatternNodes.def"
965- llvm_unreachable (" Refutable pattern in pattern binding" );
964+ llvm_unreachable (" Refutable pattern in stored property pattern binding" );
966965 }
967966}
968967
969- static Type getInitializationTypeInContext (
968+ static std::pair<AbstractionPattern, CanType>
969+ getInitializationTypeInContext (
970970 DeclContext *fromDC, DeclContext *toDC,
971971 Pattern *pattern) {
972972 auto interfaceType = pattern->getType ()->mapTypeOutOfContext ();
@@ -981,9 +981,53 @@ static Type getInitializationTypeInContext(
981981 }
982982 }
983983
984- auto resultType = toDC->mapTypeIntoContext (interfaceType);
984+ AbstractionPattern origType (
985+ fromDC->getGenericSignatureOfContext ().getCanonicalSignature (),
986+ interfaceType->getCanonicalType ());
987+
988+ auto substType = toDC->mapTypeIntoContext (interfaceType)->getCanonicalType ();
985989
986- return resultType;
990+ return std::make_pair (origType, substType);
991+ }
992+
993+ static void
994+ emitAndStoreInitialValueInto (SILGenFunction &SGF,
995+ SILLocation loc,
996+ PatternBindingDecl *pbd, unsigned i,
997+ SubstitutionMap subs,
998+ AbstractionPattern origType,
999+ CanType substType,
1000+ Initialization *init) {
1001+ bool injectIntoWrapper = false ;
1002+ if (auto singleVar = pbd->getSingleVar ()) {
1003+ auto originalVar = singleVar->getOriginalWrappedProperty ();
1004+ if (originalVar &&
1005+ originalVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
1006+ injectIntoWrapper = true ;
1007+ }
1008+ }
1009+
1010+ SGFContext C = (injectIntoWrapper ? SGFContext () : SGFContext (init));
1011+
1012+ RValue result = SGF.emitApplyOfStoredPropertyInitializer (
1013+ pbd->getExecutableInit (i),
1014+ pbd->getAnchoringVarDecl (i),
1015+ subs, substType, origType, C);
1016+
1017+ // need to store result into the init if its in context
1018+
1019+ // If we have the backing storage for a property with an attached
1020+ // property wrapper initialized with `=`, inject the value into an
1021+ // instance of the wrapper.
1022+ if (injectIntoWrapper) {
1023+ auto *singleVar = pbd->getSingleVar ();
1024+ result = maybeEmitPropertyWrapperInitFromValue (
1025+ SGF, pbd->getExecutableInit (i),
1026+ singleVar, subs, std::move (result));
1027+ }
1028+
1029+ if (!result.isInContext ())
1030+ std::move (result).forwardInto (SGF, loc, init);
9871031}
9881032
9891033void SILGenFunction::emitMemberInitializers (DeclContext *dc,
@@ -1001,35 +1045,51 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
10011045 if (!init) continue ;
10021046
10031047 auto *varPattern = pbd->getPattern (i);
1048+
10041049 // Cleanup after this initialization.
10051050 FullExpr scope (Cleanups, varPattern);
10061051
10071052 // Get the type of the initialization result, in terms
10081053 // of the constructor context's archetypes.
1009- CanType resultType = getInitializationTypeInContext (
1010- pbd->getDeclContext (), dc, varPattern)->getCanonicalType ();
1011- AbstractionPattern origResultType (resultType);
1012-
1013- // FIXME: Can emitMemberInit() share code with
1014- // InitializationForPattern in SILGenDecl.cpp?
1015- RValue result = emitApplyOfStoredPropertyInitializer (
1016- init, pbd->getAnchoringVarDecl (i), subs,
1017- resultType, origResultType,
1018- SGFContext ());
1019-
1020- // If we have the backing storage for a property with an attached
1021- // property wrapper initialized with `=`, inject the value into an
1022- // instance of the wrapper.
1023- if (auto singleVar = pbd->getSingleVar ()) {
1024- auto originalVar = singleVar->getOriginalWrappedProperty ();
1025- if (originalVar &&
1026- originalVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
1027- result = maybeEmitPropertyWrapperInitFromValue (
1028- *this , init, singleVar, subs, std::move (result));
1029- }
1054+ auto resultType = getInitializationTypeInContext (
1055+ pbd->getDeclContext (), dc, varPattern);
1056+ AbstractionPattern origType = resultType.first ;
1057+ CanType substType = resultType.second ;
1058+
1059+ // Figure out what we're initializing.
1060+ auto memberInit = emitMemberInit (*this , selfDecl, varPattern);
1061+
1062+ // This whole conversion thing is about eliminating the
1063+ // paired orig-to-subst subst-to-orig conversions that
1064+ // will happen if the storage is at a different abstraction
1065+ // level than the constructor. When emitApply() is used
1066+ // to call the stored property initializer, it naturally
1067+ // wants to convert the result back to the most substituted
1068+ // abstraction level. To undo this, we use a converting
1069+ // initialization and rely on the peephole that optimizes
1070+ // out the redundant conversion.
1071+ auto loweredResultTy = getLoweredType (origType, substType);
1072+ auto loweredSubstTy = getLoweredType (substType);
1073+
1074+ if (loweredResultTy != loweredSubstTy) {
1075+ Conversion conversion = Conversion::getSubstToOrig (
1076+ origType, substType,
1077+ loweredResultTy);
1078+
1079+ ConvertingInitialization convertingInit (conversion,
1080+ SGFContext (memberInit.get ()));
1081+
1082+ emitAndStoreInitialValueInto (*this , varPattern, pbd, i, subs,
1083+ origType, substType, &convertingInit);
1084+
1085+ auto finalValue = convertingInit.finishEmission (
1086+ *this , varPattern, ManagedValue::forInContext ());
1087+ if (!finalValue.isInContext ())
1088+ finalValue.forwardInto (*this , varPattern, memberInit.get ());
1089+ } else {
1090+ emitAndStoreInitialValueInto (*this , varPattern, pbd, i, subs,
1091+ origType, substType, memberInit.get ());
10301092 }
1031-
1032- emitMemberInit (*this , selfDecl, varPattern, std::move (result));
10331093 }
10341094 }
10351095 }
0 commit comments