@@ -1293,75 +1293,159 @@ void TypeChecker::completePropertyBehaviorStorage(VarDecl *VD,
12931293 ConcreteDeclRef (Context, Storage->getSetter (), MemberSubs));
12941294}
12951295
1296- void TypeChecker::completePropertyBehaviorInitialValue (VarDecl *VD,
1297- VarDecl *BehaviorInitialValue ,
1296+ void TypeChecker::completePropertyBehaviorParameter (VarDecl *VD,
1297+ FuncDecl *BehaviorParameter ,
12981298 NormalProtocolConformance *BehaviorConformance,
12991299 ArrayRef<Substitution> SelfInterfaceSubs,
13001300 ArrayRef<Substitution> SelfContextSubs) {
1301- // Create a property to witness the requirement.
1301+ // Create a method to witness the requirement.
13021302 auto DC = VD->getDeclContext ();
13031303 SmallString<64 > NameBuf = VD->getName ().str ();
1304- NameBuf += " .initialValue" ;
1305- auto InitialValueName = Context.getIdentifier (NameBuf);
1306- // TODO: non-static initialValue
1307- assert (BehaviorInitialValue->isStatic ());
1308- auto *InitialValue = new (Context) VarDecl (/* static*/ true ,
1309- /* let*/ false ,
1310- VD->getLoc (),
1311- InitialValueName,
1312- SelfContextSubs[1 ].getReplacement (),
1313- DC);
1314- InitialValue->setInterfaceType (SelfInterfaceSubs[1 ].getReplacement ());
1315- InitialValue->setUserAccessible (false );
1316- // Mark the vardecl to be final, implicit, and private. In a class, this
1317- // prevents it from being dynamically dispatched.
1318- if (VD->getDeclContext ()->getAsClassOrClassExtensionContext ())
1319- makeFinal (Context, InitialValue);
1320- InitialValue->setImplicit ();
1321- InitialValue->setAccessibility (Accessibility::Private);
1322- InitialValue->setIsBeingTypeChecked ();
1304+ NameBuf += " .parameter" ;
1305+ auto ParameterBaseName = Context.getIdentifier (NameBuf);
13231306
1324- addMemberToContextIfNeeded (InitialValue, DC);
1307+ // Substitute the requirement type into the conforming context.
1308+ auto sig = BehaviorConformance->getProtocol ()->getGenericSignatureOfContext ();
1309+ auto ParameterTy = BehaviorParameter->getInterfaceType ()
1310+ ->castTo <AnyFunctionType>()
1311+ ->getResult ();
13251312
1326- Pattern *InitialPBDPattern = new (Context) NamedPattern (InitialValue,
1327- /* implicit*/ true );
1328- InitialPBDPattern = new (Context) TypedPattern (InitialPBDPattern,
1329- TypeLoc::withoutLoc (SelfContextSubs[1 ].getReplacement ()),
1330- /* implicit*/ true );
1331- auto *InitialPBD = PatternBindingDecl::create (Context,
1332- /* staticloc*/ SourceLoc (),
1333- StaticSpellingKind::KeywordStatic,
1334- VD->getLoc (),
1335- InitialPBDPattern, nullptr ,
1336- VD->getDeclContext ());
1337- InitialPBD->setImplicit ();
1338- InitialPBD->setInitializerChecked (0 );
1339- addMemberToContextIfNeeded (InitialPBD, VD->getDeclContext (), VD);
1313+ TypeSubstitutionMap interfaceMap = sig->getSubstitutionMap (SelfInterfaceSubs);
1314+ auto SubstInterfaceTy = ParameterTy.subst (VD->getModuleContext (),
1315+ interfaceMap, SubstOptions ());
1316+ assert (SubstInterfaceTy && " storage type substitution failed?!" );
13401317
1341- // Create a getter.
1342- auto Get = createGetterPrototype (InitialValue, *this );
1343- addMemberToContextIfNeeded (Get, DC);
1318+ TypeSubstitutionMap contextMap = sig->getSubstitutionMap (SelfContextSubs);
1319+ auto SubstContextTy = ParameterTy.subst (VD->getModuleContext (),
1320+ contextMap, SubstOptions ());
1321+ assert (SubstContextTy && " storage type substitution failed?!" );
1322+
1323+ auto SubstBodyResultTy = SubstContextTy->castTo <AnyFunctionType>()
1324+ ->getResult ();
13441325
1345- // Take the initializer from the PatternBindingDecl for VD.
1346- auto *InitValue = VD->getParentInitializer ();
1347- auto PBD = VD->getParentPatternBinding ();
1348- unsigned entryIndex = PBD->getPatternEntryIndexForVarDecl (VD);
1349- PBD->setInit (entryIndex, nullptr );
1350- PBD->setInitializerChecked (entryIndex);
1326+ // Add the Self type back to the interface and context types.
1327+ if (DC->isTypeContext ()) {
1328+ if (DC->isGenericContext ()) {
1329+ auto genericSig = DC->getGenericSignatureOfContext ();
1330+ SubstInterfaceTy = GenericFunctionType::get (genericSig,
1331+ DC->getSelfInterfaceType (),
1332+ SubstInterfaceTy,
1333+ AnyFunctionType::ExtInfo ());
1334+ auto genericParams = DC->getGenericParamsOfContext ();
1335+ SubstContextTy = PolymorphicFunctionType::get (DC->getSelfTypeInContext (),
1336+ SubstContextTy,
1337+ genericParams);
1338+ } else {
1339+ SubstInterfaceTy = FunctionType::get (DC->getSelfInterfaceType (),
1340+ SubstInterfaceTy);
1341+ SubstContextTy = FunctionType::get (DC->getSelfTypeInContext (),
1342+ SubstContextTy);
1343+ }
1344+ }
1345+
1346+ // Borrow the parameters from the requirement declaration.
1347+ SmallVector<ParameterList *, 2 > ParamLists;
1348+ if (DC->isTypeContext ()) {
1349+ auto self = new (Context) ParamDecl (/* let*/ true , SourceLoc (), SourceLoc (),
1350+ Identifier (), SourceLoc (),
1351+ Context.Id_self ,
1352+ DC->getSelfTypeInContext (), DC);
1353+ self->setInterfaceType (DC->getSelfInterfaceType ());
1354+ self->setImplicit ();
1355+
1356+ ParamLists.push_back (ParameterList::create (Context, SourceLoc (),
1357+ self, SourceLoc ()));
1358+ ParamLists.back ()->get (0 )->setImplicit ();
1359+ }
1360+
1361+ assert (BehaviorParameter->getParameterLists ().size () == 2 );
1362+ SmallVector<ParamDecl *, 4 > Params;
1363+ SmallVector<Identifier, 4 > NameComponents;
1364+
1365+ auto *DeclaredParams = BehaviorParameter->getParameterList (1 );
1366+ for (unsigned i : indices (*DeclaredParams)) {
1367+ auto declaredParam = DeclaredParams->get (i);
1368+ auto declaredParamTy = declaredParam->getInterfaceType ();
1369+ auto interfaceTy = declaredParamTy.subst (DC->getParentModule (),
1370+ interfaceMap,
1371+ SubstOptions ());
1372+ assert (interfaceTy);
1373+ auto contextTy = declaredParamTy.subst (DC->getParentModule (),
1374+ contextMap, SubstOptions ());
1375+ assert (contextTy);
1376+
1377+ SmallString<64 > ParamNameBuf;
1378+ {
1379+ llvm::raw_svector_ostream names (ParamNameBuf);
1380+ names << " %arg." << i;
1381+ }
1382+ auto param = new (Context) ParamDecl (/* let*/ true , SourceLoc (), SourceLoc (),
1383+ Identifier (),
1384+ SourceLoc (),
1385+ Context.getIdentifier (ParamNameBuf),
1386+ contextTy, DC);
1387+ param->setInterfaceType (interfaceTy);
1388+ param->setImplicit ();
1389+ Params.push_back (param);
1390+ NameComponents.push_back (Identifier ());
1391+ }
1392+ ParamLists.push_back (ParameterList::create (Context, Params));
1393+
1394+ auto *Parameter = FuncDecl::create (Context, SourceLoc (),
1395+ StaticSpellingKind::None,
1396+ SourceLoc (),
1397+ DeclName (Context, ParameterBaseName,
1398+ NameComponents),
1399+ SourceLoc (), SourceLoc (),
1400+ SourceLoc (), nullptr , SubstContextTy,
1401+ ParamLists,
1402+ TypeLoc::withoutLoc (SubstBodyResultTy),
1403+ DC);
1404+
1405+ Parameter->setInterfaceType (SubstInterfaceTy);
1406+ // Mark the method to be final, implicit, and private. In a class, this
1407+ // prevents it from being dynamically dispatched.
1408+ if (DC->getAsClassOrClassExtensionContext ())
1409+ makeFinal (Context, Parameter);
1410+ Parameter->setImplicit ();
1411+ Parameter->setAccessibility (Accessibility::Private);
1412+ Parameter->setIsBeingTypeChecked ();
1413+ Parameter->setBodyResultType (SubstBodyResultTy);
13511414
13521415 // Recontextualize any closure declcontexts nested in the initializer to
1353- // realize that they are in the getter function.
1354- InitValue->walk (RecontextualizeClosures (Get));
1416+ // realize that they are in the parameter function.
1417+ assert (VD->getBehavior ()->Param );
1418+ VD->getBehavior ()->Param ->walk (RecontextualizeClosures (Parameter));
1419+
1420+ // Apply and return the closure in the function context.
1421+ SmallVector<Expr *, 4 > argRefs;
1422+ SmallVector<Identifier, 4 > argNames;
1423+ for (unsigned i : indices (Params)) {
1424+ auto param = Params[i];
1425+ auto expr = new (Context) DeclRefExpr (param, DeclNameLoc (),
1426+ /* implicit*/ true );
1427+ argRefs.push_back (expr);
1428+ argNames.push_back (DeclaredParams->get (i)->getName ());
1429+ }
1430+ auto argTuple = TupleExpr::create (Context, SourceLoc (), argRefs,
1431+ argNames,
1432+ {}, SourceLoc (),
1433+ /* trailing closure*/ false ,
1434+ /* implicit*/ true );
1435+ auto apply = new (Context) CallExpr (VD->getBehavior ()->Param , argTuple,
1436+ /* implicit*/ true );
13551437
13561438 // Return the expression value.
1357- auto Ret = new (Context) ReturnStmt (SourceLoc (), InitValue ,
1358- /* implicit*/ true );
1439+ auto Ret = new (Context) ReturnStmt (SourceLoc (), apply ,
1440+ /* implicit*/ true );
13591441 auto Body = BraceStmt::create (Context, SourceLoc (), ASTNode (Ret),
13601442 SourceLoc (), /* implicit*/ true );
1361- Get ->setBody (Body);
1443+ Parameter ->setBody (Body);
13621444
1363- InitialValue->makeComputed (SourceLoc (), Get, nullptr , nullptr , SourceLoc ());
1364- InitialValue->setIsBeingTypeChecked (false );
1445+ Parameter->setIsBeingTypeChecked (false );
1446+ typeCheckDecl (Parameter, true );
1447+ typeCheckDecl (Parameter, false );
1448+ addMemberToContextIfNeeded (Parameter, DC);
13651449
13661450 // Add the witnesses to the conformance.
13671451 ArrayRef<Substitution> MemberSubs;
@@ -1370,10 +1454,8 @@ void TypeChecker::completePropertyBehaviorInitialValue(VarDecl *VD,
13701454 ->getForwardingSubstitutions (Context);
13711455 }
13721456
1373- BehaviorConformance->setWitness (BehaviorInitialValue,
1374- ConcreteDeclRef (Context, InitialValue, MemberSubs));
1375- BehaviorConformance->setWitness (BehaviorInitialValue->getGetter (),
1376- ConcreteDeclRef (Context, Get, MemberSubs));
1457+ BehaviorConformance->setWitness (BehaviorParameter,
1458+ ConcreteDeclRef (Context, Parameter, MemberSubs));
13771459}
13781460
13791461void TypeChecker::completePropertyBehaviorAccessors (VarDecl *VD,
0 commit comments