@@ -91,29 +91,23 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF,
91
91
}
92
92
93
93
static SILValue emitConstructorMetatypeArg (SILGenFunction &SGF,
94
- ValueDecl *ctor ) {
94
+ ValueDecl *decl ) {
95
95
// In addition to the declared arguments, the constructor implicitly takes
96
96
// 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 ();
105
101
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);
109
105
VD->setSpecifier (ParamSpecifier::Default);
110
- VD->setInterfaceType (metatype );
106
+ VD->setInterfaceType (metatypeTy );
111
107
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 )),
114
110
VD);
115
-
116
- return SGF.AllocatorMetatype ;
117
111
}
118
112
119
113
// FIXME: Consolidate this with SILGenProlog
@@ -273,7 +267,8 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
273
267
static void
274
268
emitApplyOfInitAccessor (SILGenFunction &SGF, SILLocation loc,
275
269
AccessorDecl *accessor, SILValue selfValue,
276
- SILType selfTy, RValue &&initialValue) {
270
+ Type selfIfaceTy, SILType selfTy,
271
+ RValue &&initialValue) {
277
272
SmallVector<SILValue> arguments;
278
273
279
274
auto emitFieldReference = [&](VarDecl *field, bool forInit = false ) {
@@ -297,6 +292,10 @@ emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc,
297
292
arguments.push_back (emitFieldReference (property));
298
293
}
299
294
295
+ // The `self` metatype.
296
+ auto metatypeTy = MetatypeType::get (accessor->mapTypeIntoContext (selfIfaceTy));
297
+ arguments.push_back (SGF.B .createMetatype (loc, SGF.getLoweredType (metatypeTy)));
298
+
300
299
SubstitutionMap subs;
301
300
if (auto *env =
302
301
accessor->getDeclContext ()->getGenericEnvironmentOfContext ()) {
@@ -387,7 +386,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
387
386
loweredParams));
388
387
}
389
388
390
- emitConstructorMetatypeArg (SGF, ctor);
389
+ SGF. AllocatorMetatype = emitConstructorMetatypeArg (SGF, ctor);
391
390
(void ) loweredParams.claimNext ();
392
391
loweredParams.finish ();
393
392
@@ -418,8 +417,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
418
417
assert (elti != eltEnd &&
419
418
" number of args does not match number of fields" );
420
419
421
- emitApplyOfInitAccessor (SGF, Loc, initAccessor, resultSlot, selfTy,
422
- std::move (*elti));
420
+ emitApplyOfInitAccessor (SGF, Loc, initAccessor, resultSlot,
421
+ selfIfaceTy, selfTy, std::move (*elti));
423
422
++elti;
424
423
continue ;
425
424
}
@@ -666,7 +665,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
666
665
ctor->getEffectiveThrownErrorType (),
667
666
ctor->getThrowsLoc (),
668
667
/* ignored parameters*/ 1 );
669
- emitConstructorMetatypeArg (*this , ctor);
668
+ AllocatorMetatype = emitConstructorMetatypeArg (*this , ctor);
670
669
671
670
// Make sure we've hopped to the right global actor, if any.
672
671
if (ctor->hasAsync ()) {
@@ -897,7 +896,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
897
896
}
898
897
899
898
// Emit the metatype argument.
900
- emitConstructorMetatypeArg (*this , element);
899
+ AllocatorMetatype = emitConstructorMetatypeArg (*this , element);
901
900
(void ) loweredParams.claimNext ();
902
901
loweredParams.finish ();
903
902
@@ -957,7 +956,8 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
957
956
if (ctor->requiresUnavailableDeclABICompatibilityStubs ())
958
957
emitApplyOfUnavailableCodeReached ();
959
958
960
- SILValue selfMetaValue = emitConstructorMetatypeArg (*this , ctor);
959
+ AllocatorMetatype = emitConstructorMetatypeArg (*this , ctor);
960
+ SILValue selfMetaValue = AllocatorMetatype;
961
961
962
962
// Allocate the "self" value.
963
963
VarDecl *selfDecl = ctor->getImplicitSelfDecl ();
@@ -1758,25 +1758,30 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) {
1758
1758
1759
1759
// Emit `newValue` argument.
1760
1760
emitBasicProlog (accessor,
1761
- accessor->getParameters (), /* selfParam=*/ nullptr ,
1761
+ accessor->getParameters (),
1762
+ /* selfParam=*/ nullptr ,
1762
1763
TupleType::getEmpty (F.getASTContext ()),
1763
1764
/* errorType=*/ llvm::None,
1764
1765
/* throwsLoc=*/ SourceLoc (),
1765
1766
/* ignored parameters*/
1766
- accessedProperties.size ());
1767
+ accessedProperties.size () + 1 );
1767
1768
1768
1769
// Emit arguments for all `accesses` properties.
1769
1770
if (!accessedProperties.empty ()) {
1770
1771
auto propertyIter = accessedProperties.begin ();
1771
1772
auto propertyArgs = accessorTy->getParameters ().slice (
1772
- accessorTy->getNumParameters () - accessedProperties.size ());
1773
+ accessorTy->getNumParameters () - accessedProperties.size () - 1 ,
1774
+ accessedProperties.size ());
1773
1775
1774
1776
for (const auto &argument : propertyArgs) {
1775
1777
createArgument (*propertyIter, getSILTypeInContext (argument, accessorTy));
1776
1778
++propertyIter;
1777
1779
}
1778
1780
}
1779
1781
1782
+ // Emit `self` argument.
1783
+ emitConstructorMetatypeArg (*this , accessor);
1784
+
1780
1785
prepareEpilog (accessor,
1781
1786
accessor->getResultInterfaceType (),
1782
1787
accessor->getEffectiveThrownErrorType (),
0 commit comments