Skip to content

Commit 5e32563

Browse files
authored
Merge pull request #84746 from meg-gupta/mutateaccessorspr
Add support for mutate accessors
2 parents 0959bce + 73bc2ac commit 5e32563

17 files changed

+1167
-546
lines changed

include/swift/AST/ExtInfo.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@ class ASTExtInfoBuilder {
537537
DifferentiabilityMaskOffset = 11,
538538
DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset,
539539
SendingResultMask = 1 << 14,
540-
NumMaskBits = 15
540+
InOutResultMask = 1 << 15,
541+
NumMaskBits = 16
541542
};
542543

543544
static_assert(FunctionTypeIsolation::Mask == 0x7, "update mask manually");
@@ -660,6 +661,8 @@ class ASTExtInfoBuilder {
660661
globalActor);
661662
}
662663

664+
constexpr bool hasInOutResult() const { return bits & InOutResultMask; }
665+
663666
constexpr bool hasSelfParam() const {
664667
switch (getSILRepresentation()) {
665668
case SILFunctionTypeRepresentation::Thick:
@@ -782,6 +785,11 @@ class ASTExtInfoBuilder {
782785
lifetimeDependencies);
783786
}
784787

788+
[[nodiscard]] ASTExtInfoBuilder withHasInOutResult() const {
789+
return ASTExtInfoBuilder((bits | InOutResultMask), clangTypeInfo,
790+
globalActor, thrownError, lifetimeDependencies);
791+
}
792+
785793
void Profile(llvm::FoldingSetNodeID &ID) const {
786794
ID.AddInteger(bits);
787795
ID.AddPointer(clangTypeInfo.getType());
@@ -877,6 +885,8 @@ class ASTExtInfo {
877885

878886
FunctionTypeIsolation getIsolation() const { return builder.getIsolation(); }
879887

888+
constexpr bool hasInOutResult() const { return builder.hasInOutResult(); }
889+
880890
/// Helper method for changing the representation.
881891
///
882892
/// Prefer using \c ASTExtInfoBuilder::withRepresentation for chaining.

include/swift/AST/Types.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
407407
}
408408

409409
protected:
410-
enum { NumAFTExtInfoBits = 15 };
410+
enum { NumAFTExtInfoBits = 16 };
411411
enum { NumSILExtInfoBits = 14 };
412412

413413
// clang-format off
@@ -444,8 +444,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
444444
HasExtInfo : 1,
445445
HasClangTypeInfo : 1,
446446
HasThrownError : 1,
447-
HasLifetimeDependencies : 1,
448-
NumParams : 15
447+
HasLifetimeDependencies : 1
449448
);
450449

451450
SWIFT_INLINE_BITFIELD_FULL(ArchetypeType, TypeBase, 1+1+16,
@@ -3353,7 +3352,8 @@ END_CAN_TYPE_WRAPPER(DynamicSelfType, Type)
33533352
/// represented at the binary level as a single function pointer.
33543353
class AnyFunctionType : public TypeBase {
33553354
const Type Output;
3356-
3355+
uint16_t NumParams;
3356+
33573357
public:
33583358
using Representation = FunctionTypeRepresentation;
33593359

@@ -3614,8 +3614,8 @@ class AnyFunctionType : public TypeBase {
36143614
Bits.AnyFunctionType.HasThrownError = false;
36153615
Bits.AnyFunctionType.HasLifetimeDependencies = false;
36163616
}
3617-
Bits.AnyFunctionType.NumParams = NumParams;
3618-
assert(Bits.AnyFunctionType.NumParams == NumParams && "Params dropped!");
3617+
this->NumParams = NumParams;
3618+
assert(this->NumParams == NumParams && "Params dropped!");
36193619

36203620
if (Info && CONDITIONAL_ASSERT_enabled()) {
36213621
unsigned maxLifetimeTarget = NumParams + 1;
@@ -3653,7 +3653,7 @@ class AnyFunctionType : public TypeBase {
36533653

36543654
Type getResult() const { return Output; }
36553655
ArrayRef<Param> getParams() const;
3656-
unsigned getNumParams() const { return Bits.AnyFunctionType.NumParams; }
3656+
unsigned getNumParams() const { return NumParams; }
36573657

36583658
GenericSignature getOptGenericSignature() const;
36593659

include/swift/Sema/SyntacticElementTarget.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,9 @@ class SyntacticElementTarget {
263263
unsigned patternBindingIndex, bool bindPatternVarsOneWay);
264264

265265
/// Form an expression target for a ReturnStmt.
266-
static SyntacticElementTarget
267-
forReturn(ReturnStmt *returnStmt, Type contextTy, DeclContext *dc);
266+
static SyntacticElementTarget forReturn(ReturnStmt *returnStmt,
267+
Expr *returnExpr, Type contextTy,
268+
DeclContext *dc);
268269

269270
/// Form a target for the preamble of a for-in loop, excluding its where
270271
/// clause and body.

lib/AST/ASTVerifier.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,9 +1097,15 @@ class Verifier : public ASTWalker {
10971097
void verifyChecked(ReturnStmt *S) {
10981098
auto func = Functions.back();
10991099
Type resultType;
1100+
bool hasInOutResult = false;
1101+
11001102
if (auto *FD = dyn_cast<FuncDecl>(func)) {
11011103
resultType = FD->getResultInterfaceType();
11021104
resultType = FD->mapTypeIntoContext(resultType);
1105+
hasInOutResult = FD->getInterfaceType()
1106+
->castTo<AnyFunctionType>()
1107+
->getExtInfo()
1108+
.hasInOutResult();
11031109
} else if (auto closure = dyn_cast<AbstractClosureExpr>(func)) {
11041110
resultType = closure->getResultType();
11051111
} else if (isa<ConstructorDecl>(func)) {
@@ -1112,6 +1118,9 @@ class Verifier : public ASTWalker {
11121118
auto result = S->getResult();
11131119
auto returnType = result->getType();
11141120
// Make sure that the return has the same type as the function.
1121+
if (hasInOutResult) {
1122+
resultType = InOutType::get(resultType);
1123+
}
11151124
checkSameType(resultType, returnType, "return type");
11161125
} else {
11171126
// Make sure that the function has a Void result type.

lib/ASTGen/Sources/ASTGen/SourceFile.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ extension Parser.ExperimentalFeatures {
8686
mapFeature(.OldOwnershipOperatorSpellings, to: .oldOwnershipOperatorSpellings)
8787
mapFeature(.KeyPathWithMethodMembers, to: .keypathWithMethodMembers)
8888
mapFeature(.DefaultIsolationPerFile, to: .defaultIsolationPerFile)
89+
mapFeature(.BorrowAndMutateAccessors, to: .borrowAndMutateAccessors)
8990
}
9091
}
9192

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,22 @@ class Conventions {
13771377
}
13781378
};
13791379

1380+
static bool isBorrowAccessor(std::optional<SILDeclRef> constant) {
1381+
if (!constant || !constant->hasDecl())
1382+
return false;
1383+
1384+
auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
1385+
return accessor && accessor->isBorrowAccessor();
1386+
}
1387+
1388+
static bool isMutateAccessor(std::optional<SILDeclRef> constant) {
1389+
if (!constant || !constant->hasDecl())
1390+
return false;
1391+
1392+
auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
1393+
return accessor && accessor->isMutateAccessor();
1394+
}
1395+
13801396
/// A visitor for breaking down formal result types into a SILResultInfo
13811397
/// and possibly some number of indirect-out SILParameterInfos,
13821398
/// matching the abstraction patterns of the original type.
@@ -1386,22 +1402,21 @@ class DestructureResults {
13861402
SmallVectorImpl<SILResultInfo> &Results;
13871403
TypeExpansionContext context;
13881404
bool hasSendingResult;
1389-
bool isBorrowOrMutateAccessor;
1405+
std::optional<SILDeclRef> constant;
13901406

13911407
public:
13921408
DestructureResults(TypeExpansionContext context, TypeConverter &TC,
13931409
const Conventions &conventions,
13941410
SmallVectorImpl<SILResultInfo> &results,
1395-
bool hasSendingResult, bool isBorrowOrMutateAccessor)
1411+
bool hasSendingResult, std::optional<SILDeclRef> constant)
13961412
: TC(TC), Convs(conventions), Results(results), context(context),
1397-
hasSendingResult(hasSendingResult),
1398-
isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
1413+
hasSendingResult(hasSendingResult), constant(constant) {}
13991414

14001415
void destructure(AbstractionPattern origType, CanType substType) {
14011416
// Recur into tuples.
14021417
// Do not explode tuples for borrow and mutate accessors since we cannot
14031418
// explode and reconstruct addresses.
1404-
if (origType.isTuple() && !isBorrowOrMutateAccessor) {
1419+
if (origType.isTuple() && !isBorrowAccessor(constant)) {
14051420
origType.forEachTupleElement(substType,
14061421
[&](TupleElementGenerator &elt) {
14071422
// If the original element type is not a pack expansion, just
@@ -1411,7 +1426,7 @@ class DestructureResults {
14111426
return;
14121427
}
14131428

1414-
if (isBorrowOrMutateAccessor) {
1429+
if (isBorrowAccessor(constant)) {
14151430
llvm_unreachable(
14161431
"Returning packs from borrow/mutate accessor is not implemented");
14171432
}
@@ -1448,17 +1463,17 @@ class DestructureResults {
14481463
// Determine the result convention.
14491464
ResultConvention convention;
14501465

1451-
if (isBorrowOrMutateAccessor) {
1466+
if (isBorrowAccessor(constant)) {
14521467
if (substResultTL.isTrivial()) {
14531468
convention = ResultConvention::Unowned;
14541469
} else if (isFormallyReturnedIndirectly(origType, substType,
14551470
substResultTLForConvention)) {
1456-
assert(Convs.getResult(substResultTLForConvention) ==
1457-
ResultConvention::Guaranteed);
14581471
convention = ResultConvention::GuaranteedAddress;
14591472
} else {
14601473
convention = ResultConvention::Guaranteed;
14611474
}
1475+
} else if (isMutateAccessor(constant)) {
1476+
convention = ResultConvention::GuaranteedAddress;
14621477
} else if (isFormallyReturnedIndirectly(origType, substType,
14631478
substResultTLForConvention)) {
14641479
convention = ResultConvention::Indirect;
@@ -2368,17 +2383,6 @@ getAsCoroutineAccessor(std::optional<SILDeclRef> constant) {
23682383
return accessor;
23692384
}
23702385

2371-
static bool isBorrowOrMutateAccessor(std::optional<SILDeclRef> constant) {
2372-
if (!constant || !constant->hasDecl())
2373-
return false;
2374-
2375-
auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
2376-
if (!accessor)
2377-
return false;
2378-
2379-
return accessor->isBorrowAccessor() || accessor->isMutateAccessor();
2380-
}
2381-
23822386
static void destructureYieldsForReadAccessor(TypeConverter &TC,
23832387
TypeExpansionContext expansion,
23842388
AbstractionPattern origType,
@@ -2728,8 +2732,7 @@ static CanSILFunctionType getSILFunctionType(
27282732
SmallVector<SILResultInfo, 8> results;
27292733
{
27302734
DestructureResults destructurer(expansionContext, TC, conventions, results,
2731-
hasSendingResult,
2732-
isBorrowOrMutateAccessor(constant));
2735+
hasSendingResult, constant);
27332736
destructurer.destructure(origResultType, substFormalResultType);
27342737
}
27352738

@@ -3277,11 +3280,6 @@ static CanSILFunctionType getNativeSILFunctionType(
32773280
TC, context, origType, substInterfaceType, extInfoBuilder,
32783281
DefaultSetterConventions(), *constant);
32793282
}
3280-
if (constant->isBorrowAccessor()) {
3281-
return getSILFunctionTypeForConventions(
3282-
DefaultConventions(NormalParameterConvention::Guaranteed,
3283-
ResultConvention::Guaranteed));
3284-
}
32853283
}
32863284
return getSILFunctionTypeForConventions(
32873285
DefaultConventions(NormalParameterConvention::Guaranteed));

lib/SILGen/SILGenApply.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5225,7 +5225,7 @@ class CallEmission {
52255225

52265226
CleanupHandle applyCoroutine(SmallVectorImpl<ManagedValue> &yields);
52275227

5228-
ManagedValue applyBorrowAccessor();
5228+
ManagedValue applyBorrowMutateAccessor();
52295229

52305230
RValue apply(SGFContext C = SGFContext()) {
52315231
initialWritebackScope.verify();
@@ -5426,7 +5426,7 @@ CleanupHandle SILGenFunction::emitBeginApply(
54265426
return endApplyHandle;
54275427
}
54285428

5429-
ManagedValue CallEmission::applyBorrowAccessor() {
5429+
ManagedValue CallEmission::applyBorrowMutateAccessor() {
54305430
auto origFormalType = callee.getOrigFormalType();
54315431
// Get the callee type information.
54325432
auto calleeTypeInfo = callee.getTypeInfo(SGF);
@@ -5453,14 +5453,14 @@ ManagedValue CallEmission::applyBorrowAccessor() {
54535453
lookThroughMoveOnlyCheckerPattern(selfArgMV.getValue()));
54545454
}
54555455

5456-
auto value = SGF.applyBorrowAccessor(uncurriedLoc.value(), fnValue, canUnwind,
5457-
callee.getSubstitutions(), uncurriedArgs,
5458-
calleeTypeInfo.substFnType, options);
5456+
auto value = SGF.applyBorrowMutateAccessor(
5457+
uncurriedLoc.value(), fnValue, canUnwind, callee.getSubstitutions(),
5458+
uncurriedArgs, calleeTypeInfo.substFnType, options);
54595459

54605460
return value;
54615461
}
54625462

5463-
ManagedValue SILGenFunction::applyBorrowAccessor(
5463+
ManagedValue SILGenFunction::applyBorrowMutateAccessor(
54645464
SILLocation loc, ManagedValue fn, bool canUnwind, SubstitutionMap subs,
54655465
ArrayRef<ManagedValue> args, CanSILFunctionType substFnType,
54665466
ApplyOptions options) {
@@ -7887,7 +7887,7 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
78877887
return endApplyHandle;
78887888
}
78897889

7890-
ManagedValue SILGenFunction::emitBorrowAccessor(
7890+
ManagedValue SILGenFunction::emitBorrowMutateAccessor(
78917891
SILLocation loc, SILDeclRef accessor, SubstitutionMap substitutions,
78927892
ArgumentSource &&selfValue, bool isSuper, bool isDirectUse,
78937893
PreparedArguments &&subscriptIndices, bool isOnSelfParameter) {
@@ -7912,7 +7912,7 @@ ManagedValue SILGenFunction::emitBorrowAccessor(
79127912

79137913
emission.setCanUnwind(false);
79147914

7915-
return emission.applyBorrowAccessor();
7915+
return emission.applyBorrowMutateAccessor();
79167916
}
79177917

79187918
ManagedValue SILGenFunction::emitAsyncLetStart(

lib/SILGen/SILGenFunction.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,18 +2079,18 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
20792079
SmallVectorImpl<ManagedValue> &yields,
20802080
bool isOnSelfParameter);
20812081

2082-
ManagedValue emitBorrowAccessor(SILLocation loc, SILDeclRef accessor,
2083-
SubstitutionMap substitutions,
2084-
ArgumentSource &&selfValue, bool isSuper,
2085-
bool isDirectUse,
2086-
PreparedArguments &&subscriptIndices,
2087-
bool isOnSelfParameter);
2088-
2089-
ManagedValue applyBorrowAccessor(SILLocation loc, ManagedValue fn,
2090-
bool canUnwind, SubstitutionMap subs,
2091-
ArrayRef<ManagedValue> args,
2092-
CanSILFunctionType substFnType,
2093-
ApplyOptions options);
2082+
ManagedValue emitBorrowMutateAccessor(SILLocation loc, SILDeclRef accessor,
2083+
SubstitutionMap substitutions,
2084+
ArgumentSource &&selfValue,
2085+
bool isSuper, bool isDirectUse,
2086+
PreparedArguments &&subscriptIndices,
2087+
bool isOnSelfParameter);
2088+
2089+
ManagedValue applyBorrowMutateAccessor(SILLocation loc, ManagedValue fn,
2090+
bool canUnwind, SubstitutionMap subs,
2091+
ArrayRef<ManagedValue> args,
2092+
CanSILFunctionType substFnType,
2093+
ApplyOptions options);
20942094

20952095
RValue emitApplyConversionFunction(SILLocation loc,
20962096
Expr *funcExpr,

0 commit comments

Comments
 (0)