@@ -91,29 +91,23 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF,
9191}
9292
9393static SILValue emitConstructorMetatypeArg (SILGenFunction &SGF,
94- ValueDecl *ctor ) {
94+ ValueDecl *decl ) {
9595 // In addition to the declared arguments, the constructor implicitly takes
9696 // the metatype as its first argument, like a static function.
97- auto ctorFnType = ctor->getInterfaceType ()->castTo <AnyFunctionType>();
98- assert (ctorFnType->getParams ().size () == 1 &&
99- " more than one self parameter?" );
100- auto param = ctorFnType->getParams ()[0 ];
101- assert (!param.isVariadic () && !param.isInOut ());
102- Type metatype = param.getPlainType ();
103- auto *DC = ctor->getInnermostDeclContext ();
104- auto &AC = SGF.getASTContext ();
97+ auto metatypeTy = MetatypeType::get (
98+ decl->getDeclContext ()->getSelfInterfaceType ());
99+ auto *DC = decl->getInnermostDeclContext ();
100+ auto &ctx = SGF.getASTContext ();
105101 auto VD =
106- new (AC ) ParamDecl (SourceLoc (), SourceLoc (),
107- AC .getIdentifier (" $metatype" ), SourceLoc (),
108- AC .getIdentifier (" $metatype" ), DC);
102+ new (ctx ) ParamDecl (SourceLoc (), SourceLoc (),
103+ ctx .getIdentifier (" $metatype" ), SourceLoc (),
104+ ctx .getIdentifier (" $metatype" ), DC);
109105 VD->setSpecifier (ParamSpecifier::Default);
110- VD->setInterfaceType (metatype );
106+ VD->setInterfaceType (metatypeTy );
111107
112- SGF. AllocatorMetatype = SGF.F .begin ()->createFunctionArgument (
113- SGF.getLoweredTypeForFunctionArgument (DC->mapTypeIntoContext (metatype )),
108+ return SGF.F .begin ()->createFunctionArgument (
109+ SGF.getLoweredTypeForFunctionArgument (DC->mapTypeIntoContext (metatypeTy )),
114110 VD);
115-
116- return SGF.AllocatorMetatype ;
117111}
118112
119113// FIXME: Consolidate this with SILGenProlog
@@ -273,7 +267,8 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
273267static void
274268emitApplyOfInitAccessor (SILGenFunction &SGF, SILLocation loc,
275269 AccessorDecl *accessor, SILValue selfValue,
276- SILType selfTy, RValue &&initialValue) {
270+ Type selfIfaceTy, SILType selfTy,
271+ RValue &&initialValue) {
277272 SmallVector<SILValue> arguments;
278273
279274 auto emitFieldReference = [&](VarDecl *field, bool forInit = false ) {
@@ -297,6 +292,10 @@ emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc,
297292 arguments.push_back (emitFieldReference (property));
298293 }
299294
295+ // The `self` metatype.
296+ auto metatypeTy = MetatypeType::get (accessor->mapTypeIntoContext (selfIfaceTy));
297+ arguments.push_back (SGF.B .createMetatype (loc, SGF.getLoweredType (metatypeTy)));
298+
300299 SubstitutionMap subs;
301300 if (auto *env =
302301 accessor->getDeclContext ()->getGenericEnvironmentOfContext ()) {
@@ -387,7 +386,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
387386 loweredParams));
388387 }
389388
390- emitConstructorMetatypeArg (SGF, ctor);
389+ SGF. AllocatorMetatype = emitConstructorMetatypeArg (SGF, ctor);
391390 (void ) loweredParams.claimNext ();
392391 loweredParams.finish ();
393392
@@ -418,8 +417,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
418417 assert (elti != eltEnd &&
419418 " number of args does not match number of fields" );
420419
421- emitApplyOfInitAccessor (SGF, Loc, initAccessor, resultSlot, selfTy,
422- std::move (*elti));
420+ emitApplyOfInitAccessor (SGF, Loc, initAccessor, resultSlot,
421+ selfIfaceTy, selfTy, std::move (*elti));
423422 ++elti;
424423 continue ;
425424 }
@@ -666,7 +665,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
666665 ctor->getEffectiveThrownErrorType (),
667666 ctor->getThrowsLoc (),
668667 /* ignored parameters*/ 1 );
669- emitConstructorMetatypeArg (*this , ctor);
668+ AllocatorMetatype = emitConstructorMetatypeArg (*this , ctor);
670669
671670 // Make sure we've hopped to the right global actor, if any.
672671 if (ctor->hasAsync ()) {
@@ -897,7 +896,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
897896 }
898897
899898 // Emit the metatype argument.
900- emitConstructorMetatypeArg (*this , element);
899+ AllocatorMetatype = emitConstructorMetatypeArg (*this , element);
901900 (void ) loweredParams.claimNext ();
902901 loweredParams.finish ();
903902
@@ -957,7 +956,8 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
957956 if (ctor->requiresUnavailableDeclABICompatibilityStubs ())
958957 emitApplyOfUnavailableCodeReached ();
959958
960- SILValue selfMetaValue = emitConstructorMetatypeArg (*this , ctor);
959+ AllocatorMetatype = emitConstructorMetatypeArg (*this , ctor);
960+ SILValue selfMetaValue = AllocatorMetatype;
961961
962962 // Allocate the "self" value.
963963 VarDecl *selfDecl = ctor->getImplicitSelfDecl ();
@@ -1758,25 +1758,30 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) {
17581758
17591759 // Emit `newValue` argument.
17601760 emitBasicProlog (accessor,
1761- accessor->getParameters (), /* selfParam=*/ nullptr ,
1761+ accessor->getParameters (),
1762+ /* selfParam=*/ nullptr ,
17621763 TupleType::getEmpty (F.getASTContext ()),
17631764 /* errorType=*/ llvm::None,
17641765 /* throwsLoc=*/ SourceLoc (),
17651766 /* ignored parameters*/
1766- accessedProperties.size ());
1767+ accessedProperties.size () + 1 );
17671768
17681769 // Emit arguments for all `accesses` properties.
17691770 if (!accessedProperties.empty ()) {
17701771 auto propertyIter = accessedProperties.begin ();
17711772 auto propertyArgs = accessorTy->getParameters ().slice (
1772- accessorTy->getNumParameters () - accessedProperties.size ());
1773+ accessorTy->getNumParameters () - accessedProperties.size () - 1 ,
1774+ accessedProperties.size ());
17731775
17741776 for (const auto &argument : propertyArgs) {
17751777 createArgument (*propertyIter, getSILTypeInContext (argument, accessorTy));
17761778 ++propertyIter;
17771779 }
17781780 }
17791781
1782+ // Emit `self` argument.
1783+ emitConstructorMetatypeArg (*this , accessor);
1784+
17801785 prepareEpilog (accessor,
17811786 accessor->getResultInterfaceType (),
17821787 accessor->getEffectiveThrownErrorType (),
0 commit comments