@@ -1542,6 +1542,29 @@ synthesizeUnwrappingGetterOrAddressGetterBody(AbstractFunctionDecl *afd,
1542
1542
pointeePropertyRefExpr->setType (elementTy);
1543
1543
propertyExpr = pointeePropertyRefExpr;
1544
1544
}
1545
+ // Cast an 'address' result from a mutable pointer if needed.
1546
+ if (isAddress &&
1547
+ getterImpl->getResultInterfaceType ()->isUnsafeMutablePointer ()) {
1548
+ auto reinterpretCast = cast<FuncDecl>(
1549
+ getBuiltinValueDecl (ctx, ctx.getIdentifier (" reinterpretCast" )));
1550
+ auto rawTy = getterImpl->getResultInterfaceType ();
1551
+ auto enumTy = elementTy;
1552
+ SubstitutionMap subMap = SubstitutionMap::get (
1553
+ reinterpretCast->getGenericSignature (), {rawTy, enumTy}, {});
1554
+ ConcreteDeclRef concreteDeclRef (reinterpretCast, subMap);
1555
+ auto reinterpretCastRef = new (ctx)
1556
+ DeclRefExpr (concreteDeclRef, DeclNameLoc (), /* implicit*/ true );
1557
+ FunctionType::ExtInfo info;
1558
+ reinterpretCastRef->setType (
1559
+ FunctionType::get ({FunctionType::Param (rawTy)}, enumTy, info));
1560
+
1561
+ auto *argList = ArgumentList::forImplicitUnlabeled (ctx, {propertyExpr});
1562
+ auto reinterpreted =
1563
+ CallExpr::createImplicit (ctx, reinterpretCastRef, argList);
1564
+ reinterpreted->setType (enumTy);
1565
+ reinterpreted->setThrows (nullptr );
1566
+ propertyExpr = reinterpreted;
1567
+ }
1545
1568
1546
1569
auto returnStmt = new (ctx) ReturnStmt (SourceLoc (), propertyExpr,
1547
1570
/* implicit*/ true );
@@ -1611,6 +1634,26 @@ synthesizeUnwrappingSetterBody(AbstractFunctionDecl *afd, void *context) {
1611
1634
return {body, /* isTypeChecked*/ true };
1612
1635
}
1613
1636
1637
+ static std::pair<BraceStmt *, bool >
1638
+ synthesizeUnwrappingAddressSetterBody (AbstractFunctionDecl *afd,
1639
+ void *context) {
1640
+ auto setterDecl = cast<AccessorDecl>(afd);
1641
+ auto setterImpl = static_cast <FuncDecl *>(context);
1642
+
1643
+ ASTContext &ctx = setterDecl->getASTContext ();
1644
+
1645
+ auto selfArg = createSelfArg (setterDecl);
1646
+ auto *setterImplCallExpr =
1647
+ createAccessorImplCallExpr (setterImpl, selfArg, nullptr );
1648
+
1649
+ auto returnStmt = new (ctx) ReturnStmt (SourceLoc (), setterImplCallExpr,
1650
+ /* implicit*/ true );
1651
+
1652
+ auto body = BraceStmt::create (ctx, SourceLoc (), {returnStmt}, SourceLoc (),
1653
+ /* implicit*/ true );
1654
+ return {body, /* isTypeChecked*/ true };
1655
+ }
1656
+
1614
1657
SubscriptDecl *SwiftDeclSynthesizer::makeSubscript (FuncDecl *getter,
1615
1658
FuncDecl *setter) {
1616
1659
assert ((getter || setter) &&
@@ -1755,8 +1798,9 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
1755
1798
paramVarDecl->setSpecifier (ParamSpecifier::Default);
1756
1799
paramVarDecl->setInterfaceType (elementTy);
1757
1800
1758
- auto setterParamList =
1759
- ParameterList::create (ctx, {paramVarDecl});
1801
+ auto setterParamList = useAddress
1802
+ ? ParameterList::create (ctx, {})
1803
+ : ParameterList::create (ctx, {paramVarDecl});
1760
1804
1761
1805
setterDecl = AccessorDecl::create (
1762
1806
ctx, setterImpl->getLoc (), setterImpl->getLoc (),
@@ -1773,7 +1817,10 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
1773
1817
setterDecl->setImplicit ();
1774
1818
setterDecl->setIsDynamic (false );
1775
1819
setterDecl->setIsTransparent (true );
1776
- setterDecl->setBodySynthesizer (synthesizeUnwrappingSetterBody, setterImpl);
1820
+ setterDecl->setBodySynthesizer (useAddress
1821
+ ? synthesizeUnwrappingAddressSetterBody
1822
+ : synthesizeUnwrappingSetterBody,
1823
+ setterImpl);
1777
1824
1778
1825
if (setterImpl->isMutating ()) {
1779
1826
setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
0 commit comments