Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion include/swift/AST/ExtInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,8 @@ class ASTExtInfoBuilder {
DifferentiabilityMaskOffset = 11,
DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset,
SendingResultMask = 1 << 14,
NumMaskBits = 15
InOutResultMask = 1 << 15,
NumMaskBits = 16
};

static_assert(FunctionTypeIsolation::Mask == 0x7, "update mask manually");
Expand Down Expand Up @@ -660,6 +661,8 @@ class ASTExtInfoBuilder {
globalActor);
}

constexpr bool hasInOutResult() const { return bits & InOutResultMask; }

constexpr bool hasSelfParam() const {
switch (getSILRepresentation()) {
case SILFunctionTypeRepresentation::Thick:
Expand Down Expand Up @@ -782,6 +785,11 @@ class ASTExtInfoBuilder {
lifetimeDependencies);
}

[[nodiscard]] ASTExtInfoBuilder withHasInOutResult() const {
return ASTExtInfoBuilder((bits | InOutResultMask), clangTypeInfo,
globalActor, thrownError, lifetimeDependencies);
}

void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddInteger(bits);
ID.AddPointer(clangTypeInfo.getType());
Expand Down Expand Up @@ -877,6 +885,8 @@ class ASTExtInfo {

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

constexpr bool hasInOutResult() const { return builder.hasInOutResult(); }

/// Helper method for changing the representation.
///
/// Prefer using \c ASTExtInfoBuilder::withRepresentation for chaining.
Expand Down
14 changes: 7 additions & 7 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
}

protected:
enum { NumAFTExtInfoBits = 15 };
enum { NumAFTExtInfoBits = 16 };
enum { NumSILExtInfoBits = 14 };

// clang-format off
Expand Down Expand Up @@ -444,8 +444,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
HasExtInfo : 1,
HasClangTypeInfo : 1,
HasThrownError : 1,
HasLifetimeDependencies : 1,
NumParams : 15
HasLifetimeDependencies : 1
);

SWIFT_INLINE_BITFIELD_FULL(ArchetypeType, TypeBase, 1+1+16,
Expand Down Expand Up @@ -3350,7 +3349,8 @@ END_CAN_TYPE_WRAPPER(DynamicSelfType, Type)
/// represented at the binary level as a single function pointer.
class AnyFunctionType : public TypeBase {
const Type Output;

uint16_t NumParams;

public:
using Representation = FunctionTypeRepresentation;

Expand Down Expand Up @@ -3611,8 +3611,8 @@ class AnyFunctionType : public TypeBase {
Bits.AnyFunctionType.HasThrownError = false;
Bits.AnyFunctionType.HasLifetimeDependencies = false;
}
Bits.AnyFunctionType.NumParams = NumParams;
assert(Bits.AnyFunctionType.NumParams == NumParams && "Params dropped!");
this->NumParams = NumParams;
assert(this->NumParams == NumParams && "Params dropped!");

if (Info && CONDITIONAL_ASSERT_enabled()) {
unsigned maxLifetimeTarget = NumParams + 1;
Expand Down Expand Up @@ -3650,7 +3650,7 @@ class AnyFunctionType : public TypeBase {

Type getResult() const { return Output; }
ArrayRef<Param> getParams() const;
unsigned getNumParams() const { return Bits.AnyFunctionType.NumParams; }
unsigned getNumParams() const { return NumParams; }

GenericSignature getOptGenericSignature() const;

Expand Down
5 changes: 3 additions & 2 deletions include/swift/Sema/SyntacticElementTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,9 @@ class SyntacticElementTarget {
unsigned patternBindingIndex, bool bindPatternVarsOneWay);

/// Form an expression target for a ReturnStmt.
static SyntacticElementTarget
forReturn(ReturnStmt *returnStmt, Type contextTy, DeclContext *dc);
static SyntacticElementTarget forReturn(ReturnStmt *returnStmt,
Expr *returnExpr, Type contextTy,
DeclContext *dc);

/// Form a target for the preamble of a for-in loop, excluding its where
/// clause and body.
Expand Down
9 changes: 9 additions & 0 deletions lib/AST/ASTVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1097,9 +1097,15 @@ class Verifier : public ASTWalker {
void verifyChecked(ReturnStmt *S) {
auto func = Functions.back();
Type resultType;
bool hasInOutResult = false;

if (auto *FD = dyn_cast<FuncDecl>(func)) {
resultType = FD->getResultInterfaceType();
resultType = FD->mapTypeIntoContext(resultType);
hasInOutResult = FD->getInterfaceType()
->castTo<AnyFunctionType>()
->getExtInfo()
.hasInOutResult();
} else if (auto closure = dyn_cast<AbstractClosureExpr>(func)) {
resultType = closure->getResultType();
} else if (isa<ConstructorDecl>(func)) {
Expand All @@ -1112,6 +1118,9 @@ class Verifier : public ASTWalker {
auto result = S->getResult();
auto returnType = result->getType();
// Make sure that the return has the same type as the function.
if (hasInOutResult) {
resultType = InOutType::get(resultType);
}
checkSameType(resultType, returnType, "return type");
} else {
// Make sure that the function has a Void result type.
Expand Down
1 change: 1 addition & 0 deletions lib/ASTGen/Sources/ASTGen/SourceFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ extension Parser.ExperimentalFeatures {
mapFeature(.OldOwnershipOperatorSpellings, to: .oldOwnershipOperatorSpellings)
mapFeature(.KeyPathWithMethodMembers, to: .keypathWithMethodMembers)
mapFeature(.DefaultIsolationPerFile, to: .defaultIsolationPerFile)
mapFeature(.BorrowAndMutateAccessors, to: .borrowAndMutateAccessors)
}
}

Expand Down
52 changes: 25 additions & 27 deletions lib/SIL/IR/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,22 @@ class Conventions {
}
};

static bool isBorrowAccessor(std::optional<SILDeclRef> constant) {
if (!constant || !constant->hasDecl())
return false;

auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
return accessor && accessor->isBorrowAccessor();
}

static bool isMutateAccessor(std::optional<SILDeclRef> constant) {
if (!constant || !constant->hasDecl())
return false;

auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
return accessor && accessor->isMutateAccessor();
}

/// A visitor for breaking down formal result types into a SILResultInfo
/// and possibly some number of indirect-out SILParameterInfos,
/// matching the abstraction patterns of the original type.
Expand All @@ -1386,22 +1402,21 @@ class DestructureResults {
SmallVectorImpl<SILResultInfo> &Results;
TypeExpansionContext context;
bool hasSendingResult;
bool isBorrowOrMutateAccessor;
std::optional<SILDeclRef> constant;

public:
DestructureResults(TypeExpansionContext context, TypeConverter &TC,
const Conventions &conventions,
SmallVectorImpl<SILResultInfo> &results,
bool hasSendingResult, bool isBorrowOrMutateAccessor)
bool hasSendingResult, std::optional<SILDeclRef> constant)
: TC(TC), Convs(conventions), Results(results), context(context),
hasSendingResult(hasSendingResult),
isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
hasSendingResult(hasSendingResult), constant(constant) {}

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

if (isBorrowOrMutateAccessor) {
if (isBorrowAccessor(constant)) {
llvm_unreachable(
"Returning packs from borrow/mutate accessor is not implemented");
}
Expand Down Expand Up @@ -1448,17 +1463,17 @@ class DestructureResults {
// Determine the result convention.
ResultConvention convention;

if (isBorrowOrMutateAccessor) {
if (isBorrowAccessor(constant)) {
if (substResultTL.isTrivial()) {
convention = ResultConvention::Unowned;
} else if (isFormallyReturnedIndirectly(origType, substType,
substResultTLForConvention)) {
assert(Convs.getResult(substResultTLForConvention) ==
ResultConvention::Guaranteed);
convention = ResultConvention::GuaranteedAddress;
} else {
convention = ResultConvention::Guaranteed;
}
} else if (isMutateAccessor(constant)) {
convention = ResultConvention::GuaranteedAddress;
} else if (isFormallyReturnedIndirectly(origType, substType,
substResultTLForConvention)) {
convention = ResultConvention::Indirect;
Expand Down Expand Up @@ -2368,17 +2383,6 @@ getAsCoroutineAccessor(std::optional<SILDeclRef> constant) {
return accessor;
}

static bool isBorrowOrMutateAccessor(std::optional<SILDeclRef> constant) {
if (!constant || !constant->hasDecl())
return false;

auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
if (!accessor)
return false;

return accessor->isBorrowAccessor() || accessor->isMutateAccessor();
}

static void destructureYieldsForReadAccessor(TypeConverter &TC,
TypeExpansionContext expansion,
AbstractionPattern origType,
Expand Down Expand Up @@ -2728,8 +2732,7 @@ static CanSILFunctionType getSILFunctionType(
SmallVector<SILResultInfo, 8> results;
{
DestructureResults destructurer(expansionContext, TC, conventions, results,
hasSendingResult,
isBorrowOrMutateAccessor(constant));
hasSendingResult, constant);
destructurer.destructure(origResultType, substFormalResultType);
}

Expand Down Expand Up @@ -3277,11 +3280,6 @@ static CanSILFunctionType getNativeSILFunctionType(
TC, context, origType, substInterfaceType, extInfoBuilder,
DefaultSetterConventions(), *constant);
}
if (constant->isBorrowAccessor()) {
return getSILFunctionTypeForConventions(
DefaultConventions(NormalParameterConvention::Guaranteed,
ResultConvention::Guaranteed));
}
}
return getSILFunctionTypeForConventions(
DefaultConventions(NormalParameterConvention::Guaranteed));
Expand Down
16 changes: 8 additions & 8 deletions lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5225,7 +5225,7 @@ class CallEmission {

CleanupHandle applyCoroutine(SmallVectorImpl<ManagedValue> &yields);

ManagedValue applyBorrowAccessor();
ManagedValue applyBorrowMutateAccessor();

RValue apply(SGFContext C = SGFContext()) {
initialWritebackScope.verify();
Expand Down Expand Up @@ -5426,7 +5426,7 @@ CleanupHandle SILGenFunction::emitBeginApply(
return endApplyHandle;
}

ManagedValue CallEmission::applyBorrowAccessor() {
ManagedValue CallEmission::applyBorrowMutateAccessor() {
auto origFormalType = callee.getOrigFormalType();
// Get the callee type information.
auto calleeTypeInfo = callee.getTypeInfo(SGF);
Expand All @@ -5453,14 +5453,14 @@ ManagedValue CallEmission::applyBorrowAccessor() {
lookThroughMoveOnlyCheckerPattern(selfArgMV.getValue()));
}

auto value = SGF.applyBorrowAccessor(uncurriedLoc.value(), fnValue, canUnwind,
callee.getSubstitutions(), uncurriedArgs,
calleeTypeInfo.substFnType, options);
auto value = SGF.applyBorrowMutateAccessor(
uncurriedLoc.value(), fnValue, canUnwind, callee.getSubstitutions(),
uncurriedArgs, calleeTypeInfo.substFnType, options);

return value;
}

ManagedValue SILGenFunction::applyBorrowAccessor(
ManagedValue SILGenFunction::applyBorrowMutateAccessor(
SILLocation loc, ManagedValue fn, bool canUnwind, SubstitutionMap subs,
ArrayRef<ManagedValue> args, CanSILFunctionType substFnType,
ApplyOptions options) {
Expand Down Expand Up @@ -7888,7 +7888,7 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
return endApplyHandle;
}

ManagedValue SILGenFunction::emitBorrowAccessor(
ManagedValue SILGenFunction::emitBorrowMutateAccessor(
SILLocation loc, SILDeclRef accessor, SubstitutionMap substitutions,
ArgumentSource &&selfValue, bool isSuper, bool isDirectUse,
PreparedArguments &&subscriptIndices, bool isOnSelfParameter) {
Expand All @@ -7913,7 +7913,7 @@ ManagedValue SILGenFunction::emitBorrowAccessor(

emission.setCanUnwind(false);

return emission.applyBorrowAccessor();
return emission.applyBorrowMutateAccessor();
}

ManagedValue SILGenFunction::emitAsyncLetStart(
Expand Down
24 changes: 12 additions & 12 deletions lib/SILGen/SILGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -2079,18 +2079,18 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
SmallVectorImpl<ManagedValue> &yields,
bool isOnSelfParameter);

ManagedValue emitBorrowAccessor(SILLocation loc, SILDeclRef accessor,
SubstitutionMap substitutions,
ArgumentSource &&selfValue, bool isSuper,
bool isDirectUse,
PreparedArguments &&subscriptIndices,
bool isOnSelfParameter);

ManagedValue applyBorrowAccessor(SILLocation loc, ManagedValue fn,
bool canUnwind, SubstitutionMap subs,
ArrayRef<ManagedValue> args,
CanSILFunctionType substFnType,
ApplyOptions options);
ManagedValue emitBorrowMutateAccessor(SILLocation loc, SILDeclRef accessor,
SubstitutionMap substitutions,
ArgumentSource &&selfValue,
bool isSuper, bool isDirectUse,
PreparedArguments &&subscriptIndices,
bool isOnSelfParameter);

ManagedValue applyBorrowMutateAccessor(SILLocation loc, ManagedValue fn,
bool canUnwind, SubstitutionMap subs,
ArrayRef<ManagedValue> args,
CanSILFunctionType substFnType,
ApplyOptions options);

RValue emitApplyConversionFunction(SILLocation loc,
Expr *funcExpr,
Expand Down
Loading