@@ -1293,75 +1293,159 @@ void TypeChecker::completePropertyBehaviorStorage(VarDecl *VD,
1293
1293
ConcreteDeclRef (Context, Storage->getSetter (), MemberSubs));
1294
1294
}
1295
1295
1296
- void TypeChecker::completePropertyBehaviorInitialValue (VarDecl *VD,
1297
- VarDecl *BehaviorInitialValue ,
1296
+ void TypeChecker::completePropertyBehaviorParameter (VarDecl *VD,
1297
+ FuncDecl *BehaviorParameter ,
1298
1298
NormalProtocolConformance *BehaviorConformance,
1299
1299
ArrayRef<Substitution> SelfInterfaceSubs,
1300
1300
ArrayRef<Substitution> SelfContextSubs) {
1301
- // Create a property to witness the requirement.
1301
+ // Create a method to witness the requirement.
1302
1302
auto DC = VD->getDeclContext ();
1303
1303
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);
1323
1306
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 ();
1325
1312
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?!" );
1340
1317
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 ();
1344
1325
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);
1351
1414
1352
1415
// 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 );
1355
1437
1356
1438
// 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 );
1359
1441
auto Body = BraceStmt::create (Context, SourceLoc (), ASTNode (Ret),
1360
1442
SourceLoc (), /* implicit*/ true );
1361
- Get ->setBody (Body);
1443
+ Parameter ->setBody (Body);
1362
1444
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);
1365
1449
1366
1450
// Add the witnesses to the conformance.
1367
1451
ArrayRef<Substitution> MemberSubs;
@@ -1370,10 +1454,8 @@ void TypeChecker::completePropertyBehaviorInitialValue(VarDecl *VD,
1370
1454
->getForwardingSubstitutions (Context);
1371
1455
}
1372
1456
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));
1377
1459
}
1378
1460
1379
1461
void TypeChecker::completePropertyBehaviorAccessors (VarDecl *VD,
0 commit comments