@@ -1501,7 +1501,8 @@ AccessorDecl *SwiftDeclSynthesizer::buildSubscriptSetterDecl(
1501
1501
// / an UnsafePointer or UnsafeMutablePointer, it unwraps the pointer and returns
1502
1502
// / the underlying value.
1503
1503
static std::pair<BraceStmt *, bool >
1504
- synthesizeUnwrappingGetterBody (AbstractFunctionDecl *afd, void *context) {
1504
+ synthesizeUnwrappingGetterOrAddressGetterBody (AbstractFunctionDecl *afd,
1505
+ void *context, bool isAddress) {
1505
1506
auto getterDecl = cast<AccessorDecl>(afd);
1506
1507
auto getterImpl = static_cast <FuncDecl *>(context);
1507
1508
@@ -1525,7 +1526,8 @@ synthesizeUnwrappingGetterBody(AbstractFunctionDecl *afd, void *context) {
1525
1526
// reference type. This check actually checks to see if the type is a pointer
1526
1527
// type, but this does not apply to C pointers because they are Optional types
1527
1528
// when imported. TODO: Use a more obvious check here.
1528
- if (getterImpl->getResultInterfaceType ()->getAnyPointerElementType (ptrKind)) {
1529
+ if (!isAddress &&
1530
+ getterImpl->getResultInterfaceType ()->getAnyPointerElementType (ptrKind)) {
1529
1531
// `getterImpl` can return either UnsafePointer or UnsafeMutablePointer.
1530
1532
// Retrieve the corresponding `.pointee` declaration.
1531
1533
VarDecl *pointeePropertyDecl = ctx.getPointerPointeePropertyDecl (ptrKind);
@@ -1549,6 +1551,19 @@ synthesizeUnwrappingGetterBody(AbstractFunctionDecl *afd, void *context) {
1549
1551
return {body, /* isTypeChecked*/ true };
1550
1552
}
1551
1553
1554
+ static std::pair<BraceStmt *, bool >
1555
+ synthesizeUnwrappingGetterBody (AbstractFunctionDecl *afd, void *context) {
1556
+ return synthesizeUnwrappingGetterOrAddressGetterBody (afd, context,
1557
+ /* isAddress=*/ false );
1558
+ }
1559
+
1560
+ static std::pair<BraceStmt *, bool >
1561
+ synthesizeUnwrappingAddressGetterBody (AbstractFunctionDecl *afd,
1562
+ void *context) {
1563
+ return synthesizeUnwrappingGetterOrAddressGetterBody (afd, context,
1564
+ /* isAddress=*/ true );
1565
+ }
1566
+
1552
1567
// / Synthesizer callback for a subscript setter or a setter for a dereference
1553
1568
// / property (`var pointee`).
1554
1569
static std::pair<BraceStmt *, bool >
@@ -1685,7 +1700,6 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
1685
1700
FuncDecl *setter) {
1686
1701
assert ((getter || setter) &&
1687
1702
" getter or setter required to generate a pointee property" );
1688
-
1689
1703
auto &ctx = ImporterImpl.SwiftContext ;
1690
1704
FuncDecl *getterImpl = getter ? getter : setter;
1691
1705
FuncDecl *setterImpl = setter;
@@ -1697,6 +1711,9 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
1697
1711
const auto elementTy = rawElementTy->getAnyPointerElementType ()
1698
1712
? rawElementTy->getAnyPointerElementType ()
1699
1713
: rawElementTy;
1714
+ // Use 'address' or 'mutableAddress' accessors for non-copyable
1715
+ // types.
1716
+ bool useAddress = elementTy->isNoncopyable (dc);
1700
1717
1701
1718
auto result = new (ctx)
1702
1719
VarDecl (/* isStatic*/ false , VarDecl::Introducer::Var,
@@ -1705,16 +1722,21 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
1705
1722
result->setAccess (AccessLevel::Public);
1706
1723
1707
1724
AccessorDecl *getterDecl = AccessorDecl::create (
1708
- ctx, getterImpl->getLoc (), getterImpl->getLoc (), AccessorKind::Get,
1709
- result, SourceLoc (), StaticSpellingKind::None,
1725
+ ctx, getterImpl->getLoc (), getterImpl->getLoc (),
1726
+ useAddress ? AccessorKind::Address : AccessorKind::Get, result,
1727
+ SourceLoc (), StaticSpellingKind::None,
1710
1728
/* async*/ false , SourceLoc (),
1711
1729
/* throws*/ false , SourceLoc (), /* ThrownType=*/ TypeLoc (),
1712
- ParameterList::createEmpty (ctx), elementTy, dc);
1730
+ ParameterList::createEmpty (ctx),
1731
+ useAddress ? elementTy->wrapInPointer (PTK_UnsafePointer) : elementTy, dc);
1713
1732
getterDecl->setAccess (AccessLevel::Public);
1714
- getterDecl->setImplicit ();
1733
+ if (!useAddress)
1734
+ getterDecl->setImplicit ();
1715
1735
getterDecl->setIsDynamic (false );
1716
1736
getterDecl->setIsTransparent (true );
1717
- getterDecl->setBodySynthesizer (synthesizeUnwrappingGetterBody,
1737
+ getterDecl->setBodySynthesizer (useAddress
1738
+ ? synthesizeUnwrappingAddressGetterBody
1739
+ : synthesizeUnwrappingGetterBody,
1718
1740
getterImpl);
1719
1741
1720
1742
if (getterImpl->isMutating ()) {
@@ -1737,13 +1759,18 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
1737
1759
ParameterList::create (ctx, {paramVarDecl});
1738
1760
1739
1761
setterDecl = AccessorDecl::create (
1740
- ctx, setterImpl->getLoc (), setterImpl->getLoc (), AccessorKind::Set,
1741
- result, SourceLoc (), StaticSpellingKind::None,
1762
+ ctx, setterImpl->getLoc (), setterImpl->getLoc (),
1763
+ useAddress ? AccessorKind::MutableAddress : AccessorKind::Set, result,
1764
+ SourceLoc (), StaticSpellingKind::None,
1742
1765
/* async*/ false , SourceLoc (),
1743
1766
/* throws*/ false , SourceLoc (), /* ThrownType=*/ TypeLoc (),
1744
- setterParamList, TupleType::getEmpty (ctx), dc);
1767
+ setterParamList,
1768
+ useAddress ? elementTy->wrapInPointer (PTK_UnsafeMutablePointer)
1769
+ : TupleType::getEmpty (ctx),
1770
+ dc);
1745
1771
setterDecl->setAccess (AccessLevel::Public);
1746
- setterDecl->setImplicit ();
1772
+ if (!useAddress)
1773
+ setterDecl->setImplicit ();
1747
1774
setterDecl->setIsDynamic (false );
1748
1775
setterDecl->setIsTransparent (true );
1749
1776
setterDecl->setBodySynthesizer (synthesizeUnwrappingSetterBody, setterImpl);
0 commit comments