diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index ed9a0f8d1125b..7a8a0975cfe71 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -173,6 +173,15 @@ enum class SILFunctionTypeRepresentation : uint8_t { /// constructor). Except for /// handling the "this" argument, has the same behavior as "CFunctionPointer". CXXMethod, + + /// A KeyPath accessor function, which is thin and also uses the variadic + /// length generic components serialization in trailing buffer. + /// Each representation has a different convention for which parameters + /// have serialized generic type info. + KeyPathAccessorGetter, + KeyPathAccessorSetter, + KeyPathAccessorEquals, + KeyPathAccessorHash, }; /// Returns true if the function with this convention doesn't carry a context. @@ -203,6 +212,10 @@ isThinRepresentation(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); @@ -215,6 +228,31 @@ isThickRepresentation(Repr repr) { return !isThinRepresentation(repr); } +/// Returns true if the function with this convention receives generic arguments +/// from KeyPath argument buffer. +constexpr bool +isKeyPathAccessorRepresentation(SILFunctionTypeRepresentation rep) { + switch (rep) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + return true; + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: + return false; + } + llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); +} + + constexpr SILFunctionTypeRepresentation convertRepresentation(FunctionTypeRepresentation rep) { switch (rep) { @@ -246,6 +284,10 @@ convertRepresentation(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return llvm::None; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation!"); @@ -265,6 +307,10 @@ constexpr bool canBeCalledIndirectly(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; } @@ -286,6 +332,10 @@ template constexpr bool shouldStoreClangType(Repr repr) { case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return false; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation."); @@ -396,6 +446,10 @@ class ASTExtInfoBuilder { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return false; case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Method: @@ -634,6 +688,10 @@ SILFunctionLanguage getSILFunctionLanguage(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return SILFunctionLanguage::Swift; } @@ -652,20 +710,20 @@ class SILExtInfoBuilder { // and NumMaskBits must be updated, and they must match. // |representation|pseudogeneric| noescape | concurrent | async - // | 0 .. 3 | 4 | 5 | 6 | 7 + // | 0 .. 4 | 5 | 6 | 7 | 8 // |differentiability|unimplementable| - // | 8 .. 10 | 11 | + // | 9 .. 11 | 12 | // enum : unsigned { - RepresentationMask = 0xF << 0, - PseudogenericMask = 1 << 4, - NoEscapeMask = 1 << 5, - SendableMask = 1 << 6, - AsyncMask = 1 << 7, - DifferentiabilityMaskOffset = 8, + RepresentationMask = 0x1F << 0, + PseudogenericMask = 1 << 5, + NoEscapeMask = 1 << 6, + SendableMask = 1 << 7, + AsyncMask = 1 << 8, + DifferentiabilityMaskOffset = 9, DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset, - UnimplementableMask = 1 << 11, - NumMaskBits = 12 + UnimplementableMask = 1 << 12, + NumMaskBits = 13 }; unsigned bits; // Naturally sized for speed. @@ -765,6 +823,10 @@ class SILExtInfoBuilder { case Representation::Thin: case Representation::CFunctionPointer: case Representation::Closure: + case Representation::KeyPathAccessorGetter: + case Representation::KeyPathAccessorSetter: + case Representation::KeyPathAccessorEquals: + case Representation::KeyPathAccessorHash: return false; case Representation::ObjCMethod: case Representation::Method: @@ -788,6 +850,10 @@ class SILExtInfoBuilder { case Representation::WitnessMethod: case Representation::Closure: case SILFunctionTypeRepresentation::CXXMethod: + case Representation::KeyPathAccessorGetter: + case Representation::KeyPathAccessorSetter: + case Representation::KeyPathAccessorEquals: + case Representation::KeyPathAccessorHash: return false; } llvm_unreachable("Unhandled Representation in switch."); diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index f8ff0bbafa643..784c7e08c4005 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -380,7 +380,7 @@ class alignas(1 << TypeAlignInBits) TypeBase protected: enum { NumAFTExtInfoBits = 11 }; - enum { NumSILExtInfoBits = 12 }; + enum { NumSILExtInfoBits = 13 }; // clang-format off union { uint64_t OpaqueBits; diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index 59ff025996d38..f05f6c17ed01e 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -21,6 +21,7 @@ #ifndef SWIFT_SIL_APPLYSITE_H #define SWIFT_SIL_APPLYSITE_H +#include "swift/AST/ExtInfo.h" #include "swift/Basic/STLExtras.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" @@ -259,6 +260,10 @@ class ApplySite { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::Thick: diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 86c4d7479b8fb..a7d9771df7c55 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -202,6 +202,14 @@ static StringRef getDumpString(SILFunctionType::Representation value) { case SILFunctionType::Representation::ObjCMethod: return "objc_method"; case SILFunctionType::Representation::WitnessMethod: return "witness_method"; case SILFunctionType::Representation::Closure: return "closure"; + case SILFunctionType::Representation::KeyPathAccessorGetter: + return "keypath_accessor_getter"; + case SILFunctionType::Representation::KeyPathAccessorSetter: + return "keypath_accessor_setter"; + case SILFunctionType::Representation::KeyPathAccessorEquals: + return "keypath_accessor_equals"; + case SILFunctionType::Representation::KeyPathAccessorHash: + return "keypath_accessor_hash"; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 6bea7ffacdda5..2a72558bf1a6c 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -2038,6 +2038,13 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn, case SILFunctionTypeRepresentation::WitnessMethod: OpArgs.push_back('W'); break; + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + // KeyPath accessors are mangled separately based on their index types + // by mangleKeyPathGetterThunkHelper, and so on. + llvm_unreachable("key path accessors should not mangle its function type"); } // Coroutine kind. This is mangled in all pointer auth modes. diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 4f3f149cb5ecb..32f03ca7ded7b 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -6507,6 +6507,18 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::Closure: Printer << "closure"; break; + case SILFunctionType::Representation::KeyPathAccessorGetter: + Printer << "keypath_accessor_getter"; + break; + case SILFunctionType::Representation::KeyPathAccessorSetter: + Printer << "keypath_accessor_setter"; + break; + case SILFunctionType::Representation::KeyPathAccessorEquals: + Printer << "keypath_accessor_equals"; + break; + case SILFunctionType::Representation::KeyPathAccessorHash: + Printer << "keypath_accessor_hash"; + break; } Printer << ")"; Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); @@ -6591,6 +6603,18 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::Closure: Printer << "closure"; break; + case SILFunctionType::Representation::KeyPathAccessorGetter: + Printer << "keypath_accessor_getter"; + break; + case SILFunctionType::Representation::KeyPathAccessorSetter: + Printer << "keypath_accessor_setter"; + break; + case SILFunctionType::Representation::KeyPathAccessorEquals: + Printer << "keypath_accessor_equals"; + break; + case SILFunctionType::Representation::KeyPathAccessorHash: + Printer << "keypath_accessor_hash"; + break; } Printer << ")"; Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index f593e17a04b53..bf07ef9780b81 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -201,6 +201,10 @@ ClangTypeConverter::getFunctionType(ArrayRef params, case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: llvm_unreachable("Expected a C-compatible representation."); } llvm_unreachable("unhandled representation!"); diff --git a/lib/IRGen/CallEmission.h b/lib/IRGen/CallEmission.h index 678890a7cf0a9..872195de63faa 100644 --- a/lib/IRGen/CallEmission.h +++ b/lib/IRGen/CallEmission.h @@ -17,8 +17,9 @@ #ifndef SWIFT_IRGEN_CALLEMISSION_H #define SWIFT_IRGEN_CALLEMISSION_H -#include "Temporary.h" +#include "Address.h" #include "Callee.h" +#include "Temporary.h" namespace llvm { class CallSite; @@ -49,6 +50,10 @@ class CallEmission { /// Temporaries required by the call. TemporarySet Temporaries; + /// Temporaries required by the call that are not mapped to any + /// SIL value. + SmallVector RawTempraries; + /// The function we're going to call. Callee CurCallee; @@ -78,6 +83,8 @@ class CallEmission { virtual void emitCallToUnmappedExplosion(llvm::CallBase *call, Explosion &out) = 0; void emitYieldsToExplosion(Explosion &out); + void setKeyPathAccessorArguments(Explosion &in, bool isOutlined, + Explosion &out); virtual FunctionPointer getCalleeFunctionPointer() = 0; llvm::CallBase *emitCallSite(); diff --git a/lib/IRGen/Callee.h b/lib/IRGen/Callee.h index b3875a1c584a6..207235ac222e2 100644 --- a/lib/IRGen/Callee.h +++ b/lib/IRGen/Callee.h @@ -186,6 +186,7 @@ namespace irgen { TaskGroupWaitNext, TaskGroupWaitAll, DistributedExecuteTarget, + KeyPathAccessor, }; private: @@ -260,6 +261,7 @@ namespace irgen { case SpecialKind::TaskGroupWaitAll: return true; case SpecialKind::DistributedExecuteTarget: + case SpecialKind::KeyPathAccessor: return false; } llvm_unreachable("covered switch"); @@ -289,6 +291,9 @@ namespace irgen { case SpecialKind::AsyncLetFinish: case SpecialKind::TaskGroupWaitNext: case SpecialKind::TaskGroupWaitAll: + // KeyPath accessor functions receive their generic arguments + // as part of indices buffer. + case SpecialKind::KeyPathAccessor: return true; case SpecialKind::DistributedExecuteTarget: return false; diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index c92ac7e86887c..56d7572737209 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -40,6 +40,7 @@ #include "GenCall.h" #include "GenFunc.h" #include "GenHeap.h" +#include "GenKeyPath.h" #include "GenObjC.h" #include "GenPointerAuth.h" #include "GenPoly.h" @@ -174,6 +175,8 @@ FunctionPointerKind::getStaticAsyncContextSize(IRGenModule &IGM) const { // that you make calls to it allocate a little more memory than this! // These frames being this small is very arguably a mistake. return headerSize + 3 * IGM.getPointerSize(); + case SpecialKind::KeyPathAccessor: + return llvm::None; } llvm_unreachable("covered switch"); } @@ -331,6 +334,10 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM, case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: if (isAsync) return IGM.SwiftAsyncCC; return getFreestandingConvention(IGM); @@ -494,6 +501,7 @@ namespace { std::pair expandDirectResult(); void expandIndirectResults(); void expandParameters(SignatureExpansionABIDetails *recordedABIDetails); + void expandKeyPathAccessorParameters(); void expandExternalSignatureTypes(); void expandCoroutineResult(bool forContinuation); @@ -1389,6 +1397,10 @@ void SignatureExpansion::expandExternalSignatureTypes() { case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: llvm_unreachable("not a C representation"); } @@ -1665,6 +1677,60 @@ static void addParamInfo(SignatureExpansionABIDetails *details, SignatureExpansionABIDetails::Parameter(ti, convention)); } +void SignatureExpansion::expandKeyPathAccessorParameters() { + auto params = FnType->getParameters(); + unsigned numArgsToExpand; + SmallVector tailParams; + + switch (FnType->getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + // from: (base: CurValue, indices: (X, Y, ...)) + // to: (base: CurValue, argument: UnsafeRawPointer, size: Int) + numArgsToExpand = 1; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + // from: (value: NewValue, base: CurValue, indices: (X, Y, ...)) + // to: (value: NewValue, base: CurValue, argument: UnsafeRawPointer, size: Int) + numArgsToExpand = 2; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + // from: (lhsIndices: (X, Y, ...), rhsIndices: (X, Y, ...)) + // to: (lhsArguments: UnsafeRawPointer, rhsArguments: UnsafeRawPointer, size: Int) + numArgsToExpand = 0; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + // from: (indices: (X, Y, ...)) + // to: (instanceArguments: UnsafeRawPointer, size: Int) + numArgsToExpand = 0; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: + llvm_unreachable("non keypath accessor convention"); + } + for (unsigned i = 0; i < numArgsToExpand; i++) { + expand(params[i]); + } + for (auto tailParam : tailParams) { + ParamIRTypes.push_back(tailParam); + } +} + /// Expand the abstract parameters of a SIL function type into the physical /// parameters of an LLVM function type (results have already been expanded). void SignatureExpansion::expandParameters( @@ -1746,6 +1812,12 @@ void SignatureExpansion::expandParameters( case SILFunctionType::Representation::Closure: return FnType->hasErrorResult(); + // KeyPath accessor always has no context. + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: + return false; case SILFunctionType::Representation::Thick: return true; } @@ -1793,7 +1865,18 @@ void SignatureExpansion::expandFunctionType( return; } expandResult(recordedABIDetails); - expandParameters(recordedABIDetails); + + switch (FnType->getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + expandKeyPathAccessorParameters(); + break; + default: + expandParameters(recordedABIDetails); + break; + } return; } case SILFunctionLanguage::C: @@ -1916,6 +1999,10 @@ void SignatureExpansion::expandAsyncEntryType() { case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Closure: case SILFunctionType::Representation::CXXMethod: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return false; case SILFunctionType::Representation::Thick: @@ -2377,6 +2464,12 @@ class SyncCallEmission final : public CallEmission { isOutlined); break; + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + setKeyPathAccessorArguments(original, isOutlined, adjusted); + break; case SILFunctionTypeRepresentation::WitnessMethod: assert(witnessMetadata); assert(witnessMetadata->SelfMetadata->getType() == @@ -2639,6 +2732,10 @@ class AsyncCallEmission final : public CallEmission { case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: assert(false && "Should not reach this"); break; @@ -2956,7 +3053,7 @@ llvm::CallBase *CallEmission::emitCallSite() { // Make the call and clear the arguments array. FunctionPointer fn = getCalleeFunctionPointer(); - assert(fn.getKind() == FunctionPointer::Kind::Function); + assert(fn.getKind().getBasicKind() == FunctionPointer::Kind::Function); auto fnTy = fn.getFunctionType(); // Coerce argument types for those cases where the IR type required @@ -3011,9 +3108,14 @@ llvm::CallBase *CallEmission::emitCallSite() { if (!IsCoroutine) { Temporaries.destroyAll(IGF); + for (auto &stackAddr : RawTempraries) { + IGF.emitDeallocateDynamicAlloca(stackAddr); + } + // Clear the temporary set so that we can assert that there are no // temporaries later. Temporaries.clear(); + RawTempraries.clear(); } // Return. @@ -3043,7 +3145,7 @@ assertTypesInByValAndStructRetAttributes(llvm::FunctionType *fnType, llvm::CallBase *IRBuilder::CreateCallOrInvoke( const FunctionPointer &fn, ArrayRef args, llvm::BasicBlock *invokeNormalDest, llvm::BasicBlock *invokeUnwindDest) { - assert(fn.getKind() == FunctionPointer::Kind::Function); + assert(fn.getKind().getBasicKind() == FunctionPointer::Kind::Function); SmallVector bundles; // Add a pointer-auth bundle if necessary. @@ -3360,6 +3462,7 @@ CallEmission::~CallEmission() { assert(LastArgWritten == 0); assert(EmittedCall); assert(Temporaries.hasBeenCleared()); + assert(RawTempraries.empty()); assert(state == State::Finished); } @@ -3398,6 +3501,10 @@ Callee::Callee(CalleeInfo &&info, const FunctionPointer &fn, case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: assert(!FirstData && !SecondData); break; case SILFunctionTypeRepresentation::CXXMethod: @@ -3416,6 +3523,10 @@ llvm::Value *Callee::getSwiftContext() const { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return nullptr; case SILFunctionTypeRepresentation::WitnessMethod: @@ -3896,6 +4007,49 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee, } } +void CallEmission::setKeyPathAccessorArguments(Explosion &in, bool isOutlined, + Explosion &out) { + auto origCalleeType = CurCallee.getOrigFunctionType(); + auto params = origCalleeType->getParameters(); + + switch (getCallee().getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: { + // add base value + addNativeArgument(IGF, in, origCalleeType, params[0], out, isOutlined); + params = params.drop_back(); + break; + } + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: { + // add base value + addNativeArgument(IGF, in, origCalleeType, params[0], out, isOutlined); + // add new value + addNativeArgument(IGF, in, origCalleeType, params[1], out, isOutlined); + params = params.drop_back(2); + break; + } + default: + llvm_unreachable("unexpected representation"); + } + + llvm::Optional dynamicArgsBuf; + SmallVector indiceTypes; + for (auto i : indices(params)) { + auto ty = getParameterType(i); + indiceTypes.push_back(ty); + } + auto sig = origCalleeType->getInvocationGenericSignature(); + auto args = emitKeyPathArgument(IGF, getCallee().getSubstitutions(), sig, + indiceTypes, in, dynamicArgsBuf); + if (dynamicArgsBuf) { + RawTempraries.push_back(*dynamicArgsBuf); + } + + // add arg buffer + out.add(args.first); + // add arg buffer size + out.add(args.second); +} + /// Returns whether allocas are needed. bool irgen::addNativeArgument(IRGenFunction &IGF, Explosion &in, diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 0d2cd436ca16d..706ce5e9021f3 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -629,6 +629,10 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) { case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return ThinFuncTypeInfo::create(CanSILFunctionType(T), IGM.FunctionPtrTy, IGM.getPointerSize(), @@ -702,6 +706,10 @@ getFuncSignatureInfoForLowered(IRGenModule &IGM, CanSILFunctionType type) { case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return ti.as(); case SILFunctionType::Representation::ObjCMethod: return static_cast(ti.as()); diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp index d23a53e822c34..c3f1e5da70807 100644 --- a/lib/IRGen/GenKeyPath.cpp +++ b/lib/IRGen/GenKeyPath.cpp @@ -15,6 +15,7 @@ // //===----------------------------------------------------------------------===// +#include "GenKeyPath.h" #include "Callee.h" #include "ClassLayout.h" #include "ConstantBuilder.h" @@ -32,6 +33,7 @@ #include "IRGenFunction.h" #include "IRGenMangler.h" #include "IRGenModule.h" +#include "LoadableTypeInfo.h" #include "MetadataLayout.h" #include "ProtocolInfo.h" #include "StructLayout.h" @@ -68,8 +70,8 @@ enum KeyPathAccessor { Hash, }; -static void -bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, +void +irgen::bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, GenericEnvironment *genericEnv, ArrayRef requirements, llvm::Value *args, @@ -99,10 +101,7 @@ bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, static llvm::Function * getAccessorForComputedComponent(IRGenModule &IGM, const KeyPathPatternComponent &component, - KeyPathAccessor whichAccessor, - GenericEnvironment *genericEnv, - ArrayRef requirements, - bool hasSubscriptIndices) { + KeyPathAccessor whichAccessor) { SILFunction *accessor; switch (whichAccessor) { case Getter: @@ -118,144 +117,46 @@ getAccessorForComputedComponent(IRGenModule &IGM, accessor = component.getSubscriptIndexHash(); break; } - - // If the accessor is not generic, and locally available, we can use it as is. + // If the accessor is locally available, we can use it as is. // If it's only externally available, we need a local thunk to relative- // reference. - if (requirements.empty() && - !isAvailableExternally(accessor->getLinkage()) && + if (!isAvailableExternally(accessor->getLinkage()) && &IGM == IGM.IRGen.getGenModule(accessor)) { return IGM.getAddrOfSILFunction(accessor, NotForDefinition); } - auto accessorFn = IGM.getAddrOfSILFunction(accessor, NotForDefinition); - auto accessorFnTy = accessorFn->getFunctionType(); - - // Otherwise, we need a thunk to unmarshal the generic environment from the - // argument area. It'd be nice to have a good way to represent this - // directly in SIL, of course... const char *thunkName; - unsigned numArgsToForward; - switch (whichAccessor) { case Getter: thunkName = "keypath_get"; - numArgsToForward = 2; break; case Setter: thunkName = "keypath_set"; - numArgsToForward = 2; break; case Equals: thunkName = "keypath_equals"; - numArgsToForward = 2; break; case Hash: thunkName = "keypath_hash"; - numArgsToForward = 1; break; } - SmallVector thunkParams; - for (unsigned i = 0; i < numArgsToForward; ++i) - thunkParams.push_back(accessorFnTy->getParamType(i)); - - switch (whichAccessor) { - case Getter: - case Setter: - thunkParams.push_back(IGM.Int8PtrTy); - break; - case Equals: - case Hash: - break; - } - thunkParams.push_back(IGM.SizeTy); - - auto thunkType = llvm::FunctionType::get(accessorFnTy->getReturnType(), - thunkParams, - /*vararg*/ false); - - auto accessorThunk = llvm::Function::Create(thunkType, - llvm::GlobalValue::PrivateLinkage, thunkName, IGM.getModule()); + auto accessorFn = IGM.getAddrOfSILFunction(accessor, NotForDefinition); + auto accessorThunk = llvm::Function::Create(accessorFn->getFunctionType(), + llvm::GlobalValue::PrivateLinkage, + thunkName, IGM.getModule()); accessorThunk->setAttributes(IGM.constructInitialAttributes()); accessorThunk->setCallingConv(IGM.SwiftCC); - - switch (whichAccessor) { - case Getter: { - // Original accessor's args should be @in or @out, meaning they won't be - // captured or aliased. - accessorThunk->addParamAttr(0, llvm::Attribute::NoCapture); - accessorThunk->addParamAttr(0, llvm::Attribute::NoAlias); - accessorThunk->addParamAttr(1, llvm::Attribute::NoCapture); - accessorThunk->addParamAttr(1, llvm::Attribute::NoAlias); - // Output is sret. - auto structRetTy = accessorFn->getParamStructRetType(0); - accessorThunk->addParamAttr(0, llvm::Attribute::getWithStructRetType( - IGM.getLLVMContext(), structRetTy)); - break; - } - case Setter: - // Original accessor's args should be @in or @out, meaning they won't be - // captured or aliased. - accessorThunk->addParamAttr(0, llvm::Attribute::NoCapture); - accessorThunk->addParamAttr(0, llvm::Attribute::NoAlias); - accessorThunk->addParamAttr(1, llvm::Attribute::NoCapture); - accessorThunk->addParamAttr(1, llvm::Attribute::NoAlias); - break; - case Equals: - case Hash: - break; - } - + accessorThunk->setAttributes(accessorFn->getAttributes()); { IRGenFunction IGF(IGM, accessorThunk); if (IGM.DebugInfo) IGM.DebugInfo->emitArtificialFunction(IGF, accessorThunk); - - auto params = IGF.collectParameters(); - Explosion forwardedArgs; - forwardedArgs.add(params.claim(numArgsToForward)); - - llvm::Value *componentArgsBuf; - switch (whichAccessor) { - case Getter: - case Setter: - // The component arguments are passed alongside the base being projected. - componentArgsBuf = params.claimNext(); - // Pass the argument pointer down to the underlying function, if it - // wants it. - if (hasSubscriptIndices) { - forwardedArgs.add(componentArgsBuf); - } - break; - case Equals: - case Hash: - // We're operating directly on the component argument buffer. - componentArgsBuf = forwardedArgs.getAll()[0]; - break; - } - auto componentArgsBufSize = params.claimNext(); - bindPolymorphicArgumentsFromComponentIndices(IGF, - genericEnv, requirements, - componentArgsBuf, - componentArgsBufSize, - hasSubscriptIndices); - - // Use the bound generic metadata to form a call to the original generic - // accessor. - if (genericEnv) { - WitnessMetadata ignoreWitnessMetadata; - auto forwardingSubs = genericEnv->getForwardingSubstitutionMap(); - emitPolymorphicArguments(IGF, accessor->getLoweredFunctionType(), - forwardingSubs, - &ignoreWitnessMetadata, - forwardedArgs); - } + Explosion forwardedArgs = IGF.collectParameters(); auto fnPtr = FunctionPointer::forDirect(IGM, accessorFn, /*secondaryValue*/ nullptr, accessor->getLoweredFunctionType()); auto call = IGF.Builder.CreateCall(fnPtr, forwardedArgs.claimAll()); - if (call->getType()->isVoidTy()) IGF.Builder.CreateRetVoid(); else @@ -503,14 +404,10 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, IGF.Builder.CreateRetVoid(); } } - - auto equals = getAccessorForComputedComponent(IGM, component, Equals, - genericEnv, requirements, - !component.getSubscriptIndices().empty()); - auto hash = getAccessorForComputedComponent(IGM, component, Hash, - genericEnv, requirements, - !component.getSubscriptIndices().empty()); - + + auto equals = getAccessorForComputedComponent(IGM, component, Equals); + auto hash = getAccessorForComputedComponent(IGM, component, Hash); + ConstantInitBuilder builder(IGM); ConstantStructBuilder fields = builder.beginStruct(); auto schemaKeyPath = IGM.getOptions().PointerAuth.KeyPaths; @@ -1108,14 +1005,10 @@ emitKeyPathComponent(IRGenModule &IGM, // Push the accessors, possibly thunked to marshal generic environment. fields.addCompactFunctionReference( - getAccessorForComputedComponent(IGM, component, Getter, - genericEnv, requirements, - hasSubscriptIndices)); + getAccessorForComputedComponent(IGM, component, Getter)); if (settable) fields.addCompactFunctionReference( - getAccessorForComputedComponent(IGM, component, Setter, - genericEnv, requirements, - hasSubscriptIndices)); + getAccessorForComputedComponent(IGM, component, Setter)); if (!isInstantiableOnce) { // If there's generic context or subscript indexes, embed as @@ -1412,3 +1305,75 @@ void IRGenModule::emitSILProperty(SILProperty *prop) { var->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); var->setAlignment(llvm::MaybeAlign(4)); } + +std::pair irgen::emitKeyPathArgument( + IRGenFunction &IGF, SubstitutionMap subs, const CanGenericSignature &sig, + ArrayRef indiceTypes, Explosion &indiceValues, + llvm::Optional &dynamicArgsBuf) { + auto &IGM = IGF.IGM; + + if (subs.empty() && indiceTypes.empty()) { + // No arguments necessary, so the argument ought to be ignored by any + // callbacks in the pattern. + assert(indiceTypes.empty() && "indices not implemented"); + return std::make_pair(llvm::UndefValue::get(IGM.Int8PtrTy), + llvm::ConstantInt::get(IGM.SizeTy, 0)); + } + + SmallVector requirements; + enumerateGenericSignatureRequirements( + sig, [&](GenericRequirement reqt) { requirements.push_back(reqt); }); + + llvm::Value *argsBufSize = llvm::ConstantInt::get(IGM.SizeTy, 0); + SmallVector operandOffsets; + + for (unsigned i : indices(indiceTypes)) { + auto &indiceTy = indiceTypes[i]; + auto &ti = IGF.getTypeInfo(indiceTy); + + if (i != 0) { + auto alignMask = ti.getAlignmentMask(IGF, indiceTy); + auto notAlignMask = IGF.Builder.CreateNot(alignMask); + argsBufSize = IGF.Builder.CreateAdd(argsBufSize, alignMask); + argsBufSize = IGF.Builder.CreateAnd(argsBufSize, notAlignMask); + } + operandOffsets.push_back(argsBufSize); + + auto size = ti.getSize(IGF, indiceTy); + argsBufSize = IGF.Builder.CreateAdd(argsBufSize, size); + } + + if (!subs.empty()) { + argsBufSize = llvm::ConstantInt::get( + IGM.SizeTy, IGM.getPointerSize().getValue() * requirements.size()); + } + + dynamicArgsBuf = + IGF.emitDynamicAlloca(IGM.Int8Ty, argsBufSize, Alignment(16)); + + Address argsBuf = dynamicArgsBuf->getAddress(); + + // Copy indices into the buffer. + for (unsigned i : indices(indiceTypes)) { + + auto operandTy = indiceTypes[i]; + auto &ti = IGF.getTypeInfo(operandTy); + auto ptr = IGF.Builder.CreateInBoundsGEP(IGM.Int8Ty, argsBuf.getAddress(), + operandOffsets[i]); + auto addr = ti.getAddressForPointer( + IGF.Builder.CreateBitCast(ptr, ti.getStorageType()->getPointerTo())); + if (operandTy.isAddress()) { + ti.initializeWithTake(IGF, addr, ti.getAddressForPointer(indiceValues.claimNext()), + operandTy, false); + } else { + cast(ti).initialize(IGF, indiceValues, addr, false); + } + } + + if (!subs.empty()) { + emitInitOfGenericRequirementsBuffer(IGF, requirements, argsBuf, + MetadataState::Complete, subs); + } + + return std::make_pair(argsBuf.getAddress(), argsBufSize); +} diff --git a/lib/IRGen/GenKeyPath.h b/lib/IRGen/GenKeyPath.h new file mode 100644 index 0000000000000..345ee953e5828 --- /dev/null +++ b/lib/IRGen/GenKeyPath.h @@ -0,0 +1,39 @@ +//===--- GenKeyPath.h - IR generation for KeyPath ---------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file provides the private interface to the emission of KeyPath +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_GENKEYPATH_H +#define SWIFT_IRGEN_GENKEYPATH_H + +#include "GenericRequirement.h" +#include "swift/AST/SubstitutionMap.h" +#include "swift/Basic/LLVM.h" +#include "swift/SIL/SILValue.h" +#include "llvm/IR/Value.h" + +namespace swift { +namespace irgen { +class Explosion; +class IRGenFunction; +class StackAddress; + +std::pair emitKeyPathArgument( + IRGenFunction &IGF, SubstitutionMap subs, const CanGenericSignature &sig, + ArrayRef indiceTypes, Explosion &indiceValues, + llvm::Optional &dynamicArgsBuf); +} // end namespace irgen +} // end namespace swift + +#endif diff --git a/lib/IRGen/GenPointerAuth.cpp b/lib/IRGen/GenPointerAuth.cpp index f57fd89237684..693f5549c4d0b 100644 --- a/lib/IRGen/GenPointerAuth.cpp +++ b/lib/IRGen/GenPointerAuth.cpp @@ -183,6 +183,10 @@ static const PointerAuthSchema &getFunctionPointerSchema(IRGenModule &IGM, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: if (fnType->isAsync()) { return options.AsyncSwiftFunctionPointers; } @@ -626,7 +630,11 @@ PointerAuthEntity::getTypeDiscriminator(IRGenModule &IGM) const { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: - case SILFunctionTypeRepresentation::Closure: { + case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: { llvm::ConstantInt *&cache = IGM.getPointerAuthCaches().Types[fnType]; if (cache) return cache; diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index a688220e3d86d..829992dc115ed 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2497,6 +2497,10 @@ bool irgen::hasPolymorphicParameters(CanSILFunctionType ty) { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return ty->isPolymorphic(); case SILFunctionTypeRepresentation::CFunctionPointer: diff --git a/lib/IRGen/GenericRequirement.h b/lib/IRGen/GenericRequirement.h index 5109219cb24e1..4fb61a8b50542 100644 --- a/lib/IRGen/GenericRequirement.h +++ b/lib/IRGen/GenericRequirement.h @@ -80,6 +80,13 @@ void bindFromGenericRequirementsBuffer(IRGenFunction &IGF, MetadataState metadataState, SubstitutionMap subs); +void bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, + GenericEnvironment *genericEnv, + ArrayRef requirements, + llvm::Value *args, + llvm::Value *size, + bool hasSubscriptIndices); + /// A class describing the layout of the generic requirements of a /// nominal type metadata. diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 5d232932fdb77..d4a80a28683c9 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -15,6 +15,8 @@ // //===----------------------------------------------------------------------===// +#include "GenKeyPath.h" +#include "swift/AST/ExtInfo.h" #include "swift/AST/ASTContext.h" #include "swift/AST/DiagnosticsIRGen.h" #include "swift/AST/GenericEnvironment.h" @@ -2189,6 +2191,75 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, llvm::Value *contextPtr = emission->getContext(); (void)contextPtr; assert(contextPtr->getType() == IGF.IGM.RefCountedPtrTy); + } else if (isKeyPathAccessorRepresentation(funcTy->getRepresentation())) { + auto genericEnv = IGF.CurSILFn->getGenericEnvironment(); + SmallVector requirements; + CanGenericSignature genericSig; + if (genericEnv) { + genericSig = IGF.CurSILFn->getGenericSignature().getCanonicalSignature(); + enumerateGenericSignatureRequirements(genericSig, + [&](GenericRequirement reqt) { requirements.push_back(reqt); }); + } + + unsigned baseIndexOfIndicesArguments; + unsigned numberOfIndicesArguments; + switch (funcTy->getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + baseIndexOfIndicesArguments = 1; + numberOfIndicesArguments = 1; + break; + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + baseIndexOfIndicesArguments = 2; + numberOfIndicesArguments = 1; + break; + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + baseIndexOfIndicesArguments = 0; + numberOfIndicesArguments = 2; + break; + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + baseIndexOfIndicesArguments = 0; + numberOfIndicesArguments = 1; + break; + default: + llvm_unreachable("unhandled keypath accessor representation"); + } + + llvm::Value *componentArgsBufSize = allParamValues.takeLast(); + llvm::Value *componentArgsBuf; + bool hasSubscriptIndices = params.size() > baseIndexOfIndicesArguments; + + // Bind the indices arguments if present. + if (hasSubscriptIndices) { + assert(baseIndexOfIndicesArguments + numberOfIndicesArguments == params.size()); + + for (unsigned i = 0; i < numberOfIndicesArguments; ++i) { + SILArgument *indicesArg = params[baseIndexOfIndicesArguments + i]; + componentArgsBuf = allParamValues.takeLast(); + bindParameter( + IGF, *emission, baseIndexOfIndicesArguments + i, indicesArg, + conv.getSILArgumentType(baseIndexOfIndicesArguments + i, + IGF.IGM.getMaximalTypeExpansionContext()), + [&](unsigned startIndex, unsigned size) { + assert(size == 1); + Explosion indicesTemp; + auto castedIndices = IGF.Builder.CreateBitCast( + componentArgsBuf, IGF.getTypeInfo(indicesArg->getType()) + .getStorageType() + ->getPointerTo()); + indicesTemp.add(castedIndices); + return indicesTemp; + }); + } + params = params.drop_back(numberOfIndicesArguments); + } else { + // Discard the trailing unbound LLVM IR arguments. + for (unsigned i = 0; i < numberOfIndicesArguments; ++i) { + componentArgsBuf = allParamValues.takeLast(); + } + } + bindPolymorphicArgumentsFromComponentIndices( + IGF, genericEnv, requirements, componentArgsBuf, componentArgsBufSize, + hasSubscriptIndices); } // Map the remaining SIL parameters to LLVM parameters. @@ -2206,7 +2277,9 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, // Bind polymorphic arguments. This can only be done after binding // all the value parameters. - if (hasPolymorphicParameters(funcTy)) { + // Polymorphic parameters in KeyPath accessors are already bound above + if (hasPolymorphicParameters(funcTy) && + !isKeyPathAccessorRepresentation(funcTy->getRepresentation())) { emitPolymorphicParameters( IGF, *IGF.CurSILFn, *emission, &witnessMetadata, [&](unsigned paramIndex) -> llvm::Value * { @@ -2877,6 +2950,10 @@ FunctionPointer::Kind irgen::classifyFunctionPointerKind(SILFunction *fn) { return SpecialKind::DistributedExecuteTarget; } + if (isKeyPathAccessorRepresentation(fn->getRepresentation())) { + return SpecialKind::KeyPathAccessor; + } + return fn->getLoweredFunctionType(); } // Async functions that end up with weak_odr or linkonce_odr linkage may not be @@ -3274,6 +3351,10 @@ Callee LoweredValue::getCallee(IRGenFunction &IGF, case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Method: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return getSwiftFunctionPointerCallee(IGF, functionValue, selfValue, std::move(calleeInfo), false, false); case SILFunctionType::Representation::Closure: @@ -3338,6 +3419,10 @@ static std::unique_ptr getCallEmissionForLoweredValue( case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Method: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: break; } @@ -3717,6 +3802,10 @@ getPartialApplicationFunction(IRGenSILFunction &IGF, SILValue v, case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: break; } diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 033c826783263..21cdc7995166d 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -3451,6 +3451,10 @@ class GetFormalTypeWithSameLayout case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: // A thin function looks like a plain pointer. // FIXME: Except for extra inhabitants? return C.TheRawPointerType; @@ -3655,6 +3659,10 @@ namespace { case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: // A thin function looks like a plain pointer. // FIXME: Except for extra inhabitants? return emitFromValueWitnessTable(C.TheRawPointerType); diff --git a/lib/SIL/IR/Bridging.cpp b/lib/SIL/IR/Bridging.cpp index 43d59f73f7f6a..3c13c805085a5 100644 --- a/lib/SIL/IR/Bridging.cpp +++ b/lib/SIL/IR/Bridging.cpp @@ -101,6 +101,10 @@ Type TypeConverter::getLoweredBridgedType(AbstractionPattern pattern, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: // No bridging needed for native CCs. return t; case SILFunctionTypeRepresentation::CFunctionPointer: @@ -187,6 +191,10 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern, case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return t; case SILFunctionType::Representation::Thick: { // Thick functions (TODO: conditionally) get bridged to blocks. diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 93bfce34c19b9..a5a6faf6d3b3b 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2710,6 +2710,10 @@ static CanSILFunctionType getNativeSILFunctionType( case SILFunctionType::Representation::Thick: case SILFunctionType::Representation::Method: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: case SILFunctionType::Representation::WitnessMethod: { switch (origConstant ? origConstant->kind : SILDeclRef::Kind::Func) { case SILDeclRef::Kind::Initializer: @@ -4571,6 +4575,10 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: // Native functions don't need bridging. bridgedParams.append(methodParams.begin(), methodParams.end()); bridgedResultType = resultType; diff --git a/lib/SIL/Utils/InstructionUtils.cpp b/lib/SIL/Utils/InstructionUtils.cpp index b5e39b8bacb48..157a222ddb9ef 100644 --- a/lib/SIL/Utils/InstructionUtils.cpp +++ b/lib/SIL/Utils/InstructionUtils.cpp @@ -918,6 +918,10 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: break; } diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 1433a35da4c83..af8a62b90d748 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -188,15 +188,17 @@ void verifyKeyPathComponent(SILModule &M, auto substEqualsType = equals->getLoweredFunctionType() ->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal()); + require(substEqualsType->getRepresentation() == + SILFunctionTypeRepresentation::KeyPathAccessorEquals, + "equals should be a keypath equals convention"); + require(substEqualsType->getParameters().size() == 2, "must have two arguments"); for (unsigned i = 0; i < 2; ++i) { auto param = substEqualsType->getParameters()[i]; require(param.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require(param.getInterfaceType()->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); + == ParameterConvention::Indirect_In_Guaranteed, + "indices pointer should be in_guaranteed"); } require(substEqualsType->getResults().size() == 1, @@ -218,15 +220,16 @@ void verifyKeyPathComponent(SILModule &M, auto substHashType = hash->getLoweredFunctionType() ->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal()); + require(substHashType->getRepresentation() == + SILFunctionTypeRepresentation::KeyPathAccessorHash, + "hash should be a keypath hash convention"); require(substHashType->getParameters().size() == 1, "must have two arguments"); auto param = substHashType->getParameters()[0]; require(param.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require(param.getInterfaceType()->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); - + == ParameterConvention::Indirect_In_Guaranteed, + "indices pointer should be in_guaranteed"); + require(substHashType->getResults().size() == 1, "must have one result"); @@ -301,8 +304,8 @@ void verifyKeyPathComponent(SILModule &M, auto substGetterType = getter->getLoweredFunctionType()->substGenericArgs( M, patternSubs, TypeExpansionContext::minimal()); require(substGetterType->getRepresentation() == - SILFunctionTypeRepresentation::Thin, - "getter should be a thin function"); + SILFunctionTypeRepresentation::KeyPathAccessorGetter, + "getter should be a keypath getter convention"); require(substGetterType->getNumParameters() == 1 + hasIndices, "getter should have one parameter"); @@ -317,13 +320,8 @@ void verifyKeyPathComponent(SILModule &M, if (hasIndices) { auto indicesParam = substGetterType->getParameters()[1]; require(indicesParam.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require( - indicesParam - .getArgumentType(M, substGetterType, typeExpansionContext) - ->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); + == ParameterConvention::Indirect_In_Guaranteed, + "indices should be in_guaranteed"); } require(substGetterType->getNumResults() == 1, @@ -353,8 +351,8 @@ void verifyKeyPathComponent(SILModule &M, ->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal()); require(substSetterType->getRepresentation() == - SILFunctionTypeRepresentation::Thin, - "setter should be a thin function"); + SILFunctionTypeRepresentation::KeyPathAccessorSetter, + "setter should be keypath setter convention"); require(substSetterType->getNumParameters() == 2 + hasIndices, "setter should have two parameters"); @@ -375,13 +373,8 @@ void verifyKeyPathComponent(SILModule &M, if (hasIndices) { auto indicesParam = substSetterType->getParameters()[2]; require(indicesParam.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require( - indicesParam - .getArgumentType(M, substSetterType, typeExpansionContext) - ->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); + == ParameterConvention::Indirect_In_Guaranteed, + "indices pointer should be in_guaranteed"); } require(getTypeInExpansionContext(newValueParam.getArgumentType( diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index a9f8b2d248d36..96df23508ad91 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -38,6 +38,7 @@ #include "swift/AST/ParameterList.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/SubstitutionMap.h" +#include "swift/AST/Type.h" #include "swift/AST/Types.h" #include "swift/Basic/Defer.h" #include "swift/Basic/SourceManager.h" @@ -1785,6 +1786,10 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::CXXMethod: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: llvm_unreachable("should not do function conversion from method rep"); } llvm_unreachable("bad representation"); @@ -1815,6 +1820,10 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::CXXMethod: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: llvm_unreachable("should not do function conversion from method rep"); } llvm_unreachable("bad representation"); @@ -2971,15 +2980,8 @@ loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc, return indexValues; } - auto indexLoweredTy = SGF.getLoweredType(AnyFunctionType::composeTuple( - SGF.getASTContext(), indexParams, ParameterFlagHandling::AssertEmpty)); - - auto addr = SGF.B.createPointerToAddress(loc, pointer, - indexLoweredTy.getAddressType(), - /*isStrict*/ false); - for (unsigned i : indices(indexes)) { - SILValue eltAddr = addr; + SILValue eltAddr = pointer; if (indexes.size() > 1) { eltAddr = SGF.B.createTupleElementAddr(loc, eltAddr, i); } @@ -3004,6 +3006,20 @@ getRepresentativeAccessorForKeyPath(AbstractStorageDecl *storage) { return storage->getOpaqueAccessor(AccessorKind::Read); } +static CanType buildKeyPathIndicesTuple(ASTContext &C, + ArrayRef indexes) { + + if (indexes.size() == 1) { + return indexes[0].FormalType; + } + + SmallVector indicesElements; + for (auto &elt : indexes) { + indicesElements.emplace_back(elt.FormalType); + } + return TupleType::get(indicesElements, C)->getCanonicalType(); +} + static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, AbstractStorageDecl *property, SubstitutionMap subs, @@ -3052,14 +3068,26 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, SmallVector params; params.push_back({loweredBaseTy, paramConvention}); auto &C = SGM.getASTContext(); - if (!indexes.empty()) - params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(), - ParameterConvention::Direct_Unowned}); - + + if (!indexes.empty()) { + if (indexes.size() > 1) { + SmallVector indicesElements; + for (auto &elt : indexes) { + indicesElements.emplace_back(elt.first); + } + auto indicesTupleTy = TupleType::get(indicesElements, C)->getCanonicalType(); + params.push_back({indicesTupleTy, paramConvention}); + } else { + params.push_back({indexes[0].first, paramConvention}); + } + } + SILResultInfo result(loweredPropTy, ResultConvention::Indirect); return SILFunctionType::get( - genericSig, SILFunctionType::ExtInfo::getThin(), SILCoroutineKind::None, + genericSig, SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorGetter), + SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, {}, result, llvm::None, SubstitutionMap(), SubstitutionMap(), SGM.getASTContext()); }(); @@ -3116,6 +3144,8 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, auto indexArgTy = subSGF.silConv.getSILType(signature->getParameters()[1], signature, subSGF.F.getTypeExpansionContext()); + if (genericEnv) + indexArgTy = genericEnv->mapTypeIntoContext(SGM.M, indexArgTy); indexPtrArg = entry->createFunctionArgument(indexArgTy); } @@ -3235,12 +3265,23 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, ? ParameterConvention::Indirect_Inout : paramConvention}); // indexes - if (!indexes.empty()) - params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(), - ParameterConvention::Direct_Unowned}); + if (!indexes.empty()) { + if (indexes.size() > 1) { + SmallVector indicesElements; + for (auto &elt : indexes) { + indicesElements.emplace_back(elt.first); + } + auto indicesTupleTy = TupleType::get(indicesElements, C)->getCanonicalType(); + params.push_back({indicesTupleTy, paramConvention}); + } else { + params.push_back({indexes[0].first, paramConvention}); + } + } return SILFunctionType::get( - genericSig, SILFunctionType::ExtInfo::getThin(), SILCoroutineKind::None, + genericSig, SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorSetter), + SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, {}, {}, llvm::None, SubstitutionMap(), SubstitutionMap(), SGM.getASTContext()); }(); @@ -3289,20 +3330,22 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, } auto valueArg = entry->createFunctionArgument(valueArgTy); auto baseArg = entry->createFunctionArgument(baseArgTy); - SILValue indexPtrArg; + SILValue indicesTupleArg; if (!indexes.empty()) { auto indexArgTy = subSGF.silConv.getSILType(signature->getParameters()[2], signature, subSGF.getTypeExpansionContext()); - indexPtrArg = entry->createFunctionArgument(indexArgTy); + if (genericEnv) + indexArgTy = genericEnv->mapTypeIntoContext(SGM.M, indexArgTy); + indicesTupleArg = entry->createFunctionArgument(indexArgTy); } Scope scope(subSGF, loc); auto subscriptIndices = loadIndexValuesForKeyPathComponent(subSGF, loc, property, - indexes, indexPtrArg); + indexes, indicesTupleArg); auto valueOrig = valueArgTy.isTrivial(subSGF.F) ? ManagedValue::forRValueWithoutOwnership(valueArg) @@ -3394,9 +3437,9 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, } auto &C = SGM.getASTContext(); - auto unsafeRawPointerTy = C.getUnsafeRawPointerType()->getCanonicalType(); auto boolTy = C.getBoolType()->getCanonicalType(); auto intTy = C.getIntType()->getCanonicalType(); + auto indicesTupleTy = buildKeyPathIndicesTuple(C, indexes); auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable); @@ -3422,25 +3465,23 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, RValue indexValue(indexTupleTy); - auto indexLoweredTy = - SILType::getPrimitiveAddressType(SGM.Types.getLoweredRValueType( - TypeExpansionContext::minimal(), indexTupleTy)); - // Get or create the equals witness - [unsafeRawPointerTy, boolTy, genericSig, &C, &indexTypes, &equals, loc, - &SGM, genericEnv, expansion, indexLoweredTy, indexes]{ - // (RawPointer, RawPointer) -> Bool + [boolTy, indicesTupleTy, genericSig, &C, &indexTypes, &equals, loc, &SGM, + genericEnv, expansion, indexes] { + // (lhs: (X, Y, ...), rhs: (X, Y, ...)) -> Bool SmallVector params; - params.push_back({unsafeRawPointerTy, - ParameterConvention::Direct_Unowned}); - params.push_back({unsafeRawPointerTy, - ParameterConvention::Direct_Unowned}); - + params.push_back( + {indicesTupleTy, ParameterConvention::Indirect_In_Guaranteed}); + params.push_back( + {indicesTupleTy, ParameterConvention::Indirect_In_Guaranteed}); + SmallVector results; results.push_back({boolTy, ResultConvention::Unowned}); auto signature = SILFunctionType::get( - genericSig, SILFunctionType::ExtInfo::getThin(), SILCoroutineKind::None, + genericSig, SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorEquals), + SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, results, llvm::None, SubstitutionMap(), SubstitutionMap(), C); @@ -3462,20 +3503,19 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILGenFunction subSGF(SGM, *equals, SGM.SwiftModule); equals->setGenericEnvironment(genericEnv); auto entry = equals->begin(); - auto lhsPtr = entry->createFunctionArgument(subSGF.silConv.getSILType( - params[0], signature, subSGF.getTypeExpansionContext())); - auto rhsPtr = entry->createFunctionArgument(subSGF.silConv.getSILType( - params[1], signature, subSGF.getTypeExpansionContext())); + auto lhsArgTy = subSGF.silConv.getSILType( + params[0], signature, subSGF.getTypeExpansionContext()); + auto rhsArgTy = subSGF.silConv.getSILType( + params[1], signature, subSGF.getTypeExpansionContext()); + if (genericEnv) { + lhsArgTy = genericEnv->mapTypeIntoContext(SGM.M, lhsArgTy); + rhsArgTy = genericEnv->mapTypeIntoContext(SGM.M, rhsArgTy); + } + auto lhsAddr = entry->createFunctionArgument(lhsArgTy); + auto rhsAddr = entry->createFunctionArgument(rhsArgTy); Scope scope(subSGF, loc); - auto lhsAddr = subSGF.B.createPointerToAddress(loc, lhsPtr, - indexLoweredTy, - /*isStrict*/ false); - auto rhsAddr = subSGF.B.createPointerToAddress(loc, rhsPtr, - indexLoweredTy, - /*isStrict*/ false); - // Compare each pair of index values using the == witness from the // conformance. auto equatableProtocol = C.getProtocol(KnownProtocolKind::Equatable); @@ -3525,12 +3565,12 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, llvm::None, llvm::None, ImportAsMemberStatus()); Scope branchScope(subSGF, loc); - + SILValue lhsEltAddr = lhsAddr; SILValue rhsEltAddr = rhsAddr; if (indexes.size() > 1) { - lhsEltAddr = subSGF.B.createTupleElementAddr(loc, lhsEltAddr, i); - rhsEltAddr = subSGF.B.createTupleElementAddr(loc, rhsEltAddr, i); + lhsEltAddr = subSGF.B.createTupleElementAddr(loc, lhsAddr, i); + rhsEltAddr = subSGF.B.createTupleElementAddr(loc, rhsAddr, i); } auto lhsArg = subSGF.emitLoad(loc, lhsEltAddr, subSGF.getTypeLowering(AbstractionPattern::getOpaque(), formalTy), @@ -3603,18 +3643,20 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, }(); // Get or create the hash witness - [unsafeRawPointerTy, intTy, genericSig, &C, indexTypes, &hash, &loc, - &SGM, genericEnv, expansion, indexLoweredTy, hashableProto, indexes]{ - // (RawPointer) -> Int + [intTy, indicesTupleTy, genericSig, &C, indexTypes, &hash, &loc, &SGM, + genericEnv, expansion, hashableProto, indexes] { + // (indices: (X, Y, ...)) -> Int SmallVector params; - params.push_back({unsafeRawPointerTy, - ParameterConvention::Direct_Unowned}); - + params.push_back({indicesTupleTy, + ParameterConvention::Indirect_In_Guaranteed}); + SmallVector results; results.push_back({intTy, ResultConvention::Unowned}); auto signature = SILFunctionType::get( - genericSig, SILFunctionType::ExtInfo::getThin(), SILCoroutineKind::None, + genericSig, SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorHash), + SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, results, llvm::None, SubstitutionMap(), SubstitutionMap(), C); @@ -3638,8 +3680,11 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILGenFunction subSGF(SGM, *hash, SGM.SwiftModule); hash->setGenericEnvironment(genericEnv); auto entry = hash->begin(); - auto indexPtr = entry->createFunctionArgument(subSGF.silConv.getSILType( - params[0], signature, subSGF.getTypeExpansionContext())); + auto indexArgTy = subSGF.silConv.getSILType( + params[0], signature, subSGF.getTypeExpansionContext()); + if (genericEnv) + indexArgTy = genericEnv->mapTypeIntoContext(SGM.M, indexArgTy); + auto indexPtr = entry->createFunctionArgument(indexArgTy); SILValue hashCode; @@ -3651,11 +3696,9 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, auto &index = indexes[0]; // Extract the index value. - SILValue indexAddr = subSGF.B.createPointerToAddress(loc, indexPtr, - indexLoweredTy, - /*isStrict*/ false); + SILValue indexAddr = indexPtr; if (indexes.size() > 1) { - indexAddr = subSGF.B.createTupleElementAddr(loc, indexAddr, 0); + indexAddr = subSGF.B.createTupleElementAddr(loc, indexPtr, 0); } VarDecl *hashValueVar = diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index 96ccf7362f3e4..a8989ac47cbf3 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -85,6 +85,10 @@ static bool isSpecializableRepresentation(SILFunctionTypeRepresentation Rep, case SILFunctionTypeRepresentation::Thick: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; case SILFunctionTypeRepresentation::WitnessMethod: return OptForPartialApply; diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index fa864bf13026d..d9b797604ded7 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -732,6 +732,10 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: break; case SILFunctionTypeRepresentation::CFunctionPointer: diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index e9641484533f0..4d97fdd711472 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -3049,6 +3049,14 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr, SILFunctionType::Representation::ObjCMethod) .Case("witness_method", SILFunctionType::Representation::WitnessMethod) + .Case("keypath_accessor_getter", + SILFunctionType::Representation::KeyPathAccessorGetter) + .Case("keypath_accessor_setter", + SILFunctionType::Representation::KeyPathAccessorSetter) + .Case("keypath_accessor_equals", + SILFunctionType::Representation::KeyPathAccessorEquals) + .Case("keypath_accessor_hash", + SILFunctionType::Representation::KeyPathAccessorHash) .Default(llvm::None); if (!parsedRep) { diagnoseInvalid(repr, attrs.getLoc(TAK_convention), diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 128930a2d6c4e..31a506e638305 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -6123,6 +6123,10 @@ getActualSILFunctionTypeRepresentation(uint8_t rep) { CASE(ObjCMethod) CASE(WitnessMethod) CASE(CXXMethod) + CASE(KeyPathAccessorGetter) + CASE(KeyPathAccessorSetter) + CASE(KeyPathAccessorEquals) + CASE(KeyPathAccessorHash) #undef CASE default: return llvm::None; diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 522d9ca5d70ef..f287c70434293 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 806; // end_init_let_ref instructions +const uint16_t SWIFTMODULE_VERSION_MINOR = 807; // keypath accessor /// A standard hash seed used for all string hashes in a serialized module. /// @@ -296,8 +296,12 @@ enum class SILFunctionTypeRepresentation : uint8_t { WitnessMethod, Closure, CXXMethod, + KeyPathAccessorGetter, + KeyPathAccessorSetter, + KeyPathAccessorEquals, + KeyPathAccessorHash, }; -using SILFunctionTypeRepresentationField = BCFixed<4>; +using SILFunctionTypeRepresentationField = BCFixed<5>; // These IDs must \em not be renumbered or reordered without incrementing // the module version. diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 0b7c4eb029545..f2d82d59c2d50 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -4914,6 +4914,10 @@ static uint8_t getRawStableSILFunctionTypeRepresentation( SIMPLE_CASE(SILFunctionTypeRepresentation, WitnessMethod) SIMPLE_CASE(SILFunctionTypeRepresentation, Closure) SIMPLE_CASE(SILFunctionTypeRepresentation, CXXMethod) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorGetter) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorSetter) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorEquals) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorHash) } llvm_unreachable("bad calling convention"); } diff --git a/test/Constraints/keypath_dynamic_member_lookup.swift b/test/Constraints/keypath_dynamic_member_lookup.swift index d28d9767e5cdc..b5ef78d45cb19 100644 --- a/test/Constraints/keypath_dynamic_member_lookup.swift +++ b/test/Constraints/keypath_dynamic_member_lookup.swift @@ -417,34 +417,34 @@ func testIUOUnwrap(_ x: S_54310, _ y: S_57571) { // CHECK: keypath $KeyPath, (root $S_54310_Base; stored_property #S_54310_Base.i : $Optional; optional_force : $Int) x.i - // CHECK: keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed S_54310_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) x[5] // CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; stored_property #S_54310_Base.i : $Optional; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $S_54310; gettable_property $(), id @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54310) -> (), getter @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_54310, UnsafeRawPointer) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP]]) + // CHECK: $KeyPath, (root $S_54310; gettable_property $(), id @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54310) -> (), getter @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310, @in_guaranteed KeyPath) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP]]) _ = \S_54310.i - // CHECK: [[INNER_SUB_KP:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed S_54310_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $S_54310; gettable_property $(), id @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54310) -> (), getter @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_54310, UnsafeRawPointer) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_SUB_KP]]) + // CHECK: [[INNER_SUB_KP:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath, (root $S_54310; gettable_property $(), id @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54310) -> (), getter @$s29keypath_dynamic_member_lookup7S_54310V0B6Memberys7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310, @in_guaranteed KeyPath) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_SUB_KP]]) _ = \S_54310.[5] // https://github.com/apple/swift/issues/57571: Make sure we can handle IUO // unwraps in both the inner and outer key paths. // CHECK: [[INNER_KP2:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; stored_property #S_54310_Base.i : $Optional; optional_force : $Int) - // CHECK: keypath $KeyPath>, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_57571, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP2]]) + // CHECK: keypath $KeyPath>, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_57571, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP2]]) _ = \S_57571.i // CHECK: [[INNER_KP3:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; stored_property #S_54310_Base.i : $Optional; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_57571, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) ([[INNER_KP3]]) + // CHECK: keypath $KeyPath, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_57571, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int; optional_force : $Int) ([[INNER_KP3]]) let _: KeyPath = \S_57571.i - // CHECK: [[INNER_KP4:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed S_54310_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) - // CHECK: keypath $KeyPath>, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_57571, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP4]]) + // CHECK: [[INNER_KP4:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath>, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_57571, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP4]]) _ = \S_57571.[0] - // CHECK: [[INNER_KP5:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed S_54310_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_57571, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) ([[INNER_KP5]]) + // CHECK: [[INNER_KP5:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath, (root $S_57571; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional, getter @$s29keypath_dynamic_member_lookup7S_57571V0B6MemberSiSgs7KeyPathCyAA12S_54310_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_57571, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup12S_54310_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int; optional_force : $Int) ([[INNER_KP5]]) let _: KeyPath = \S_57571.[0] // CHECK: [[INNER_KP6:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; stored_property #S_54310_Base.i : $Optional; optional_force : $Int) @@ -454,7 +454,7 @@ func testIUOUnwrap(_ x: S_54310, _ y: S_57571) { // CHECK: bb{{[0-9]+}}(%{{[0-9]+}} : $Int) let _: Int = y.i - // CHECK: [[INNER_KP7:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed S_54310_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) + // CHECK: [[INNER_KP7:%[0-9]+]] = keypath $KeyPath, (root $S_54310_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicig : $@convention(method) (Int, S_54310_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup12S_54310_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54310_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) // CHECK: [[Y0_OPT:%[0-9]+]] = apply {{%[0-9]+}}([[INNER_KP7]], {{%[0-9]+}}) : $@convention(method) (@guaranteed KeyPath, S_57571) -> Optional // CHECK: switch_enum [[Y0_OPT]] // CHECK: unreachable @@ -520,15 +520,15 @@ struct S_54352 { func testDynamicMemberWithDefault(_ x: S_54352) { // CHECK: [[DEF_FN:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipfA_ : $@convention(thin) () -> Int // CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_FN]]() - // CHECK: [[KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(thin) (@in_guaranteed HasDefaultedSubscript, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[DEF_ARG]]) + // CHECK: [[KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed HasDefaultedSubscript, @in_guaranteed Int) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int) ([[DEF_ARG]]) // CHECK: [[SUB_GET:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup7S_54352V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54352) -> Int // CHECK: apply [[SUB_GET]]([[KP]], {{%[0-9]+}}) _ = x[] // CHECK: [[DEF_FN:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipfA_ : $@convention(thin) () -> Int // CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_FN]]() - // CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(thin) (@in_guaranteed HasDefaultedSubscript, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[DEF_ARG]]) - // CHECK: [[OUTER_KP:%[0-9]+]] = keypath $KeyPath, (root $S_54352; gettable_property $Int, id @$s29keypath_dynamic_member_lookup7S_54352V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54352) -> Int, getter @$s29keypath_dynamic_member_lookup7S_54352V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcipACTK : $@convention(thin) (@in_guaranteed S_54352, UnsafeRawPointer) -> @out Int, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP]]) + // CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed HasDefaultedSubscript, @in_guaranteed Int) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int) ([[DEF_ARG]]) + // CHECK: [[OUTER_KP:%[0-9]+]] = keypath $KeyPath, (root $S_54352; gettable_property $Int, id @$s29keypath_dynamic_member_lookup7S_54352V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath, S_54352) -> Int, getter @$s29keypath_dynamic_member_lookup7S_54352V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed S_54352, @in_guaranteed KeyPath) -> @out Int, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP]]) _ = \S_54352.[] } diff --git a/test/DebugInfo/keypath.swift b/test/DebugInfo/keypath.swift index 96df16bbe08e9..95452beff33fb 100644 --- a/test/DebugInfo/keypath.swift +++ b/test/DebugInfo/keypath.swift @@ -8,7 +8,7 @@ public struct Gen { // This used to assert. -// CHECK: distinct !DISubprogram(linkageName: "keypath_set", {{.*}} flags: DIFlagArtificial +// CHECK: distinct !DISubprogram(linkageName: "$sSly7ElementQz5IndexQzcipSMRzSHADRQlxxTK", {{.*}} flags: DIFlagArtificial extension Gen where Value : MutableCollection, Value.Index : Hashable { public var dontAssert: Int { var i = value.startIndex diff --git a/test/IRGen/default_function_ir_attributes.swift b/test/IRGen/default_function_ir_attributes.swift index b0041410a1b08..db53a36e37335 100644 --- a/test/IRGen/default_function_ir_attributes.swift +++ b/test/IRGen/default_function_ir_attributes.swift @@ -118,14 +118,6 @@ func test_computed_key_path_sil_thunks() -> KeyPath { \S.computed } -// helper function: IR-generated key path getter -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_get( -// CHECK-SAME: [[ATTRS_SIMPLE]] - -// helper function: IR-generated key path setter -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_set( -// CHECK-SAME: [[ATTRS_SIMPLE]] - // helper function: IR-generated key path arg layout accessor // CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_get_arg_layout( // CHECK-SAME: [[ATTRS_SIMPLE]] @@ -138,14 +130,6 @@ func test_computed_key_path_sil_thunks() -> KeyPath { // CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_copy( // CHECK-SAME: [[ATTRS_SIMPLE]] -// helper function: IR-generated key path equals function -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_equals( -// CHECK-SAME: [[ATTRS_SIMPLE]] - -// helper function: IR-generated key path hash function -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_hash( -// CHECK-SAME: [[ATTRS_SIMPLE]] - // helper function: IR-generated key path argument initializer // CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_arg_init( // CHECK-SAME: [[ATTRS_SIMPLE]] diff --git a/test/IRGen/keypath_accessor.sil b/test/IRGen/keypath_accessor.sil new file mode 100644 index 0000000000000..c0483963befa0 --- /dev/null +++ b/test/IRGen/keypath_accessor.sil @@ -0,0 +1,59 @@ +// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s -DINT=i%target-ptrsize + +sil_stage canonical +import Swift + +public struct Blah { + public subscript(x: T) -> Int { get set } + public subscript(x: T, y: T) -> Int { get set } + public subscript(x: T, y: U) -> Int { get set } +} + +// CHECK: define{{.*}} swiftcc void @"$simple_getter"( +// CHECK-SAME: ptr{{.*}} sret(%TSi) %0, +// CHECK-SAME: ptr{{.*}} %1, +// CHECK-SAME: ptr{{.*}} %2, [[INT]] %3) +sil @$simple_getter : $@convention(keypath_accessor_getter) (@in_guaranteed Blah) -> @out Int { +bb0(%0 : $*Int, %1 : $*Blah): + unreachable +} + +// CHECK: define{{.*}} swiftcc void @"$generic_indices_getter"( +// CHECK-SAME: ptr{{.*}} {{.*}} %0, +// CHECK-SAME: ptr{{.*}} %1, +// %2 = the key path component buffer pointer and %3 is the size +// CHECK-SAME: ptr{{.*}} %2, [[INT]] %3) +sil @$generic_indices_getter : $@convention(keypath_accessor_getter) (@in_guaranteed Blah, @in_guaranteed (_: T)) -> @out Int { +bb0(%0 : $*Int, %1 : $*Blah, %2 : $*(_: T)): + unreachable +} + + + +// CHECK: define{{.*}} swiftcc void @"$generic_indices_setter"( +// CHECK-SAME: ptr{{.*}} %0, +// CHECK-SAME: ptr{{.*}} %1, +// %2 = the key path component buffer pointer and %3 is the size +// CHECK-SAME: ptr{{.*}} %2, [[INT]] %3) +sil @$generic_indices_setter : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout Blah, @in_guaranteed (_: T)) -> () { +bb0(%0 : $*Int, %1 : $*Blah, %2 : $*(_: T)): + unreachable +} + +// CHECK: define{{.*}} swiftcc [[INT]] @"$generic_indices_hash"( +// %0 = the key path component buffer pointer and %1 is the size +// CHECK-SAME: ptr{{.*}} %0, [[INT]] %1) +sil @$generic_indices_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (_: T)) -> Int { +bb0(%0 : $*(_: T)): + unreachable +} + +// CHECK: define{{.*}} swiftcc i1 @"$generic_indices_equals"( +// %0 = LHS of key path component buffer pointer +// %1 = RHS of key path component buffer pointer +// %2 = the size of the key path component buffers +// CHECK-SAME: ptr{{.*}} %0, ptr{{.*}} %1, [[INT]] %2) +sil @$generic_indices_equals : $@convention(keypath_accessor_equals) (@in_guaranteed (_: T), @in_guaranteed (_: T)) -> Bool { +bb0(%0 : $*(_: T), %1 : $*(_: T)): + unreachable +} diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil index eeb590d6f078b..e669b8888c8eb 100644 --- a/test/IRGen/keypaths.sil +++ b/test/IRGen/keypaths.sil @@ -336,10 +336,10 @@ entry: // CHECK: call ptr @swift_getKeyPath(ptr [[KP_H]], ptr undef) %h = keypath $KeyPath, (root $C; stored_property #C.z : $S; stored_property #S.x : $Int) - %k = keypath $KeyPath, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int) - %l = keypath $KeyPath, (root $C; settable_property $Int, id #C.w!getter, getter @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> ()) - %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> ()) + %k = keypath $KeyPath, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + %l = keypath $KeyPath, (root $C; settable_property $Int, id #C.w!getter, getter @l_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) + %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> ()) + %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(keypath_accessor_getter) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m2_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> ()) // CHECK: call ptr @swift_getKeyPath(ptr [[KP_T0]], ptr undef) %t0 = keypath $KeyPath, (root $T; stored_property #T.a : $(Int, String); tuple_element #0 : $Int) @@ -351,33 +351,33 @@ entry: } sil @k_id : $@convention(thin) () -> () -sil @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int { +sil @k_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int { bb0(%0 : $*Int, %1 : $*S): unreachable } -sil @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int { +sil @l_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int { bb0(%0 : $*Int, %1 : $*C): unreachable } -sil @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () { +sil @l_set : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () { bb0(%0 : $*Int, %1 : $*C): unreachable } -sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()> { +sil @m_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()> { bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } -sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> () { +sil @m_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> () { bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } -sil @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()> -sil @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> () +sil @m2_get : $@convention(keypath_accessor_getter) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()> +sil @m2_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> () struct Gen { var x: T @@ -443,103 +443,103 @@ entry: // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @computed_property_generics sil @computed_property_generics : $@convention(thin) () -> () { entry: - %n = keypath $WritableKeyPath, (root $TTT; settable_property $UUU, id @n_get : $@convention(thin) (@in_guaranteed TT) -> @out UU, getter @n_get : $@convention(thin) (@in_guaranteed TT) -> @out UU, setter @n_set : $@convention(thin) (@in_guaranteed UU, @in_guaranteed TT) -> ()) + %n = keypath $WritableKeyPath, (root $TTT; settable_property $UUU, id @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU, getter @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU, setter @n_set : $@convention(keypath_accessor_setter) (@in_guaranteed UU, @in_guaranteed TT) -> ()) return undef : $() } -sil @n_get : $@convention(thin) (@in_guaranteed TT) -> @out UU -sil @n_set : $@convention(thin) (@in_guaranteed UU, @in_guaranteed TT) -> () +sil @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU +sil @n_set : $@convention(keypath_accessor_setter) (@in_guaranteed UU, @in_guaranteed TT) -> () sil @computed_property_indices : $@convention(thin) (C, S, C, S, C, S) -> () { entry(%0 : $C, %1 : $S, %2 : $C, %3 : $S, %4 : $C, %5 : $S): %o = keypath $WritableKeyPath, ( root $S; settable_property $C, - id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), + id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $C : $C], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%0) %p = keypath $WritableKeyPath, ( root $S; settable_property $C, - id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), + id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%1, %2) %r = keypath $WritableKeyPath, ( root $S; settable_property $C, - id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), + id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int; + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; settable_property $S, - id @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S, - getter @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S, - setter @r_set : $@convention(thin) (@in_guaranteed S, @in_guaranteed C, UnsafeRawPointer) -> (), + id @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S, + getter @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S, + setter @r_set : $@convention(keypath_accessor_setter) (@in_guaranteed S, @in_guaranteed C, @in_guaranteed Int) -> (), indices [%$2 : $S : $S], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%3, %4, %5) return undef : $() } -sil @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C -sil @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> () -sil @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C +sil @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> () +sil @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool +sil @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int -sil @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S -sil @r_set : $@convention(thin) (@in_guaranteed S, @in_guaranteed C, UnsafeRawPointer) -> () +sil @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S +sil @r_set : $@convention(keypath_accessor_setter) (@in_guaranteed S, @in_guaranteed C, @in_guaranteed Int) -> () sil @generic_computed_property_indices : $@convention(thin) (@in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B) -> () { entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B): %s = keypath $WritableKeyPath, ( root $X; settable_property $Y, - id @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - getter @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - setter @s_set : $@convention(thin) (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), + id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%0) %t = keypath $WritableKeyPath, ( root $X; settable_property $Y, - id @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - getter @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - setter @s_set : $@convention(thin) (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), + id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $Y : $*Y, %$1 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%1, %2) %v = keypath $WritableKeyPath, ( root $X; settable_property $Y, - id @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - getter @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - setter @s_set : $@convention(thin) (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), + id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $Y : $*Y, %$1 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int; + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; settable_property $X, - id @v_get : $@convention(thin) (@in_guaranteed U, UnsafeRawPointer) -> @out T, - getter @v_get : $@convention(thin) (@in_guaranteed U, UnsafeRawPointer) -> @out T, - setter @v_set : $@convention(thin) (@in_guaranteed T, @in_guaranteed U, UnsafeRawPointer) -> (), + id @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed U, @in_guaranteed Int) -> @out T, + getter @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed U, @in_guaranteed Int) -> @out T, + setter @v_set : $@convention(keypath_accessor_setter) (@in_guaranteed T, @in_guaranteed U, @in_guaranteed Int) -> (), indices [%$2 : $Y : $*Y], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%3, %4, %5) return undef : $() @@ -572,10 +572,10 @@ bb0: return %t : $() } -sil @s_get : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out B -sil @s_set : $@convention(thin) (@in_guaranteed B, @in_guaranteed A, UnsafeRawPointer) -> () -sil @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed Int) -> @out B +sil @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed B, @in_guaranteed A, @in_guaranteed Int) -> () +sil @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool +sil @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int -sil @v_get : $@convention(thin) (@in_guaranteed B, UnsafeRawPointer) -> @out A -sil @v_set : $@convention(thin) (@in_guaranteed A, @in_guaranteed B, UnsafeRawPointer) -> () +sil @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed B, @in_guaranteed Int) -> @out A +sil @v_set : $@convention(keypath_accessor_setter) (@in_guaranteed A, @in_guaranteed B, @in_guaranteed Int) -> () diff --git a/test/IRGen/keypaths_external.sil b/test/IRGen/keypaths_external.sil index 333edc8d458dd..582efefd0699f 100644 --- a/test/IRGen/keypaths_external.sil +++ b/test/IRGen/keypaths_external.sil @@ -14,31 +14,31 @@ entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B): %t = keypath $KeyPath, B>, ( root $G; gettable_property $Z, - id @g_x_get : $@convention(thin) (@in_guaranteed G) -> @out Z, - getter @g_x_get : $@convention(thin) (@in_guaranteed G) -> @out Z, + id @g_x_get : $@convention(keypath_accessor_getter) (@in_guaranteed G) -> @out Z, + getter @g_x_get : $@convention(keypath_accessor_getter) (@in_guaranteed G) -> @out Z, external #G.x ) %u = keypath $KeyPath, A>, ( root $G; gettable_property $Y, - id @g_subscript_get : $@convention(thin) (@in_guaranteed G, UnsafeRawPointer) -> @out B, - getter @g_subscript_get : $@convention(thin) (@in_guaranteed G, UnsafeRawPointer) -> @out B, + id @g_subscript_get : $@convention(keypath_accessor_getter) (@in_guaranteed G, @in_guaranteed Int) -> @out B, + getter @g_subscript_get : $@convention(keypath_accessor_getter) (@in_guaranteed G, @in_guaranteed Int) -> @out B, indices [%$0 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int, + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int, external #G.subscript ) (%1) return undef : $() } -sil @g_x_get : $@convention(thin) (@in_guaranteed G) -> @out Z -sil @g_subscript_get : $@convention(thin) (@in_guaranteed G, UnsafeRawPointer) -> +sil @g_x_get : $@convention(keypath_accessor_getter) (@in_guaranteed G) -> @out Z +sil @g_subscript_get : $@convention(keypath_accessor_getter) (@in_guaranteed G, @in_guaranteed Int) -> @out B -sil @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool +sil @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int // -- %t // CHECK: [[KP_T:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ {{.*}} i32 1, {{.*}} @"{{got.|\\01__imp__?}}$s23keypaths_external_other1GV1xxvpMV" diff --git a/test/IRGen/keypaths_objc.sil b/test/IRGen/keypaths_objc.sil index 2945cd877f63c..9d1b0fed0d608 100644 --- a/test/IRGen/keypaths_objc.sil +++ b/test/IRGen/keypaths_objc.sil @@ -15,7 +15,7 @@ class C: NSObject { sil_vtable C {} -sil @x_get : $@convention(thin) (@in_guaranteed C) -> @out NSString +sil @x_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out NSString // CHECK: [[KEYPATH_A:@keypath(\..*)?]] = private global // -- computed, get-only, function-instantiated identifier @@ -31,7 +31,7 @@ sil @x_get : $@convention(thin) (@in_guaranteed C) -> @out NSString sil @objc_only_property : $@convention(thin) () -> () { entry: // CHECK: call ptr @swift_getKeyPath({{.*}} [[KEYPATH_A]] - %a = keypath $KeyPath, (objc "x"; root $C; gettable_property $NSString, id #C.x!getter.foreign, getter @x_get : $@convention(thin) (@in_guaranteed C) -> @out NSString) + %a = keypath $KeyPath, (objc "x"; root $C; gettable_property $NSString, id #C.x!getter.foreign, getter @x_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out NSString) unreachable } diff --git a/test/IRGen/property_descriptor.sil b/test/IRGen/property_descriptor.sil index 7da3ce2abacba..350c1eca9de3c 100644 --- a/test/IRGen/property_descriptor.sil +++ b/test/IRGen/property_descriptor.sil @@ -63,7 +63,7 @@ sil_property #ExternalGeneric.rw ( sil_property #ExternalGeneric.computedRO ( gettable_property $T, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_generic : $@convention(thin) (@in_guaranteed ExternalGeneric) -> @out T) + getter @get_computed_generic : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric) -> @out T) // CHECK: @"$s19property_descriptor15ExternalGenericV10computedRWxvpMV" = // -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id @@ -77,8 +77,8 @@ sil_property #ExternalGeneric.computedRO ( sil_property #ExternalGeneric.computedRW ( settable_property $T, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_generic : $@convention(thin) (@in_guaranteed ExternalGeneric) -> @out T, - setter @set_computed_generic : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric) -> ()) + getter @get_computed_generic : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric) -> @out T, + setter @set_computed_generic : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric) -> ()) // CHECK: @"$s19property_descriptor15ExternalGenericVyxqd__cSHRd__luipMV" = // -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id @@ -92,8 +92,8 @@ sil_property #ExternalGeneric.computedRW ( sil_property #ExternalGeneric.subscript ( settable_property $T, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_generic_subscript : $@convention(thin) (@in_guaranteed ExternalGeneric, UnsafeRawPointer) -> @out T, - setter @set_computed_generic_subscript : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric, UnsafeRawPointer) -> ()) + getter @get_computed_generic_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric, @in_guaranteed U) -> @out T, + setter @set_computed_generic_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric, @in_guaranteed U) -> ()) // CHECK: @"$s19property_descriptor8ExternalV2roSivpMV" = // CHECK-64: @"$s19property_descriptor8ExternalV2rwSivpMV" = @@ -103,17 +103,17 @@ sil_property #External.rw (stored_property #External.rw : $Int) sil_property #External.computedRO ( gettable_property $Int, id @id_computed : $@convention(thin) () -> (), - getter @get_computed : $@convention(thin) (@in_guaranteed External) -> @out Int) + getter @get_computed : $@convention(keypath_accessor_getter) (@in_guaranteed External) -> @out Int) sil_property #External.computedRW ( settable_property $Int, id @id_computed : $@convention(thin) () -> (), - getter @get_computed : $@convention(thin) (@in_guaranteed External) -> @out Int, - setter @set_computed : $@convention(thin) (@in_guaranteed Int, @inout External) -> ()) + getter @get_computed : $@convention(keypath_accessor_getter) (@in_guaranteed External) -> @out Int, + setter @set_computed : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External) -> ()) sil_property #External.subscript ( settable_property $Int, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out Int, - setter @set_computed_subscript : $@convention(thin) (@in_guaranteed Int, @inout External, UnsafeRawPointer) -> ()) + getter @get_computed_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed String) -> @out Int, + setter @set_computed_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External, @in_guaranteed String) -> ()) sil_property #ExternalReabstractions.ro ( stored_property #ExternalReabstractions.ro : $T) @@ -121,8 +121,8 @@ sil_property #ExternalReabstractions.ro ( sil_property #ExternalReabstractions.reabstracted ( settable_property $() -> (), id ##ExternalReabstractions.reabstracted, - getter @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()>, - setter @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> ()) + getter @get_reabstracted : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()>, + setter @set_reabstracted : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> ()) // All trivial descriptors should share a definition by aliasing to the common // definition @@ -136,17 +136,17 @@ sil_property #ExternalGeneric.computedWithTrivialDescriptor () sil_property #External.computedWithTrivialDescriptor () sil @id_computed : $@convention(thin) () -> () -sil @get_computed : $@convention(thin) (@in_guaranteed External) -> @out Int -sil @set_computed : $@convention(thin) (@in_guaranteed Int, @inout External) -> () +sil @get_computed : $@convention(keypath_accessor_getter) (@in_guaranteed External) -> @out Int +sil @set_computed : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External) -> () -sil @get_computed_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out Int -sil @set_computed_subscript : $@convention(thin) (@in_guaranteed Int, @inout External, UnsafeRawPointer) -> () +sil @get_computed_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed String) -> @out Int +sil @set_computed_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External, @in_guaranteed String) -> () -sil @get_computed_generic : $@convention(thin) (@in_guaranteed ExternalGeneric) -> @out T -sil @set_computed_generic : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric) -> () +sil @get_computed_generic : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric) -> @out T +sil @set_computed_generic : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric) -> () -sil @get_computed_generic_subscript : $@convention(thin) (@in_guaranteed ExternalGeneric, UnsafeRawPointer) -> @out T -sil @set_computed_generic_subscript : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric, UnsafeRawPointer) -> () +sil @get_computed_generic_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric, @in_guaranteed U) -> @out T +sil @set_computed_generic_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric, @in_guaranteed U) -> () -sil @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()> -sil @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> () +sil @get_reabstracted : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()> +sil @set_reabstracted : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> () diff --git a/test/SIL/Parser/keypath.sil b/test/SIL/Parser/keypath.sil index 651815a23eb25..33e840eb3717e 100644 --- a/test/SIL/Parser/keypath.sil +++ b/test/SIL/Parser/keypath.sil @@ -92,50 +92,50 @@ entry: } sil @id_a : $@convention(thin) () -> () -sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int -sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> () -sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int -sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () -sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for -sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> () -sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int -sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () -sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int -sil @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C -sil @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> () -sil @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int +sil @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> () +sil @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int +sil @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () +sil @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for +sil @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> () +sil @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int +sil @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> () +sil @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int +sil @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C +sil @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> () +sil @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int // CHECK-LABEL: sil shared @computed_properties sil shared @computed_properties : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, ( root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), - getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , - setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> ()) - // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) + getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , + setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> ()) + // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) + %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) return undef : $() } -sil @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X1 -sil @set_gen_a : $@convention(thin) (@in_guaranteed X2, @in_guaranteed Gen) -> () +sil @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X1 +sil @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X2, @in_guaranteed Gen) -> () // CHECK-LABEL: sil shared @computed_properties_generic sil shared @computed_properties_generic : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) return undef : $() } @@ -166,14 +166,14 @@ entry: sil @indexes : $@convention(thin) (S, C) -> () { // CHECK: bb0([[S:%.*]] : $S, [[C:%.*]] : $C): entry(%s : $S, %c : $C): - // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) ([[S]], [[C]]) - %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%s, %c) + // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) ([[S]], [[C]]) + %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%s, %c) // CHECK: [[T:%.*]] = alloc_stack %t = alloc_stack $S // CHECK: [[D:%.*]] = alloc_stack %d = alloc_stack $C - // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, UnsafeRawPointer) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer) -> Int) ([[T]], [[D]]) - %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C, setter @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%t, %d) + // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2), @in_guaranteed (S, τ_0_2)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2)) -> Int) ([[T]], [[D]]) + %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%t, %d) dealloc_stack %d : $*C dealloc_stack %t : $*S @@ -184,22 +184,22 @@ entry(%s : $S, %c : $C): // CHECK-LABEL: sil @external sil @external : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) return undef : $() } -sil @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T -sil @equals_external_subscript : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @hash_external_subscript : $@convention(thin) (UnsafeRawPointer) -> Int +sil @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T +sil @equals_external_subscript : $@convention(keypath_accessor_equals) (@in_guaranteed U, @in_guaranteed U) -> Bool +sil @hash_external_subscript : $@convention(keypath_accessor_hash) (@in_guaranteed U) -> Int // CHECK-LABEL: sil_property #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0) sil_property #External.ro (stored_property #External.ro : $T) // CHECK-LABEL: sil_property #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0, // CHECK-SAME: id @id_a : $@convention(thin) () -> (), -// CHECK-SAME: getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0) +// CHECK-SAME: getter @get_external_subscript : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, @in_guaranteed τ_0_1) -> @out τ_0_0 sil_property #External.subscript (gettable_property $T, id @id_a : $@convention(thin) () -> (), - getter @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T) + getter @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T) diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil index dbf0242f94e53..810c507a71cc2 100644 --- a/test/SIL/Serialization/keypath.sil +++ b/test/SIL/Serialization/keypath.sil @@ -131,44 +131,44 @@ entry: } sil @id_a : $@convention(thin) () -> () -sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int -sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> () -sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int -sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () -sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for -sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () -sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int -sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () -sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int -sil @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C -sil @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> () -sil @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int +sil @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> () +sil @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int +sil @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () +sil @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for +sil @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +sil @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int +sil @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> () +sil @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int +sil @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C +sil @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> () +sil @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int // CHECK-LABEL: sil shared [serialized] @EE_computed_properties sil shared [serialized] @EE_computed_properties : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) - %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) - // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) + // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) + %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) return undef : $() } -sil @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X1 -sil @set_gen_a : $@convention(thin) (@in_guaranteed X2, @in_guaranteed Gen) -> () +sil @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X1 +sil @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X2, @in_guaranteed Gen) -> () // CHECK-LABEL: sil shared [serialized] @FF_computed_properties_generic sil shared [serialized] @FF_computed_properties_generic : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) return undef : $() } @@ -188,14 +188,14 @@ entry: sil shared [serialized] @HH_indexes : $@convention(thin) (S, C) -> () { // CHECK: bb0([[S:%.*]] : $S, [[C:%.*]] : $C): entry(%s : $S, %c : $C): - // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) ([[S]], [[C]]) - %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%s, %c) + // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) ([[S]], [[C]]) + %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%s, %c) // CHECK: [[T:%.*]] = alloc_stack %t = alloc_stack $S // CHECK: [[D:%.*]] = alloc_stack %d = alloc_stack $C - // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, UnsafeRawPointer) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer) -> Int) ([[T]], [[D]]) - %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C, setter @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%t, %d) + // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2), @in_guaranteed (S, τ_0_2)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2)) -> Int) ([[T]], [[D]]) + %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%t, %d) dealloc_stack %d : $*C dealloc_stack %t : $*S @@ -206,8 +206,8 @@ entry(%s : $S, %c : $C): // CHECK-LABEL: sil shared [serialized] @II_external sil shared [serialized] @II_external : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) return undef : $() } @@ -227,16 +227,16 @@ entry: unreachable } -sil [serialized] @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T -sil [serialized] @equals_external_subscript : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil [serialized] @hash_external_subscript : $@convention(thin) (UnsafeRawPointer) -> Int +sil [serialized] @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T +sil [serialized] @equals_external_subscript : $@convention(keypath_accessor_equals) (@in_guaranteed U, @in_guaranteed U) -> Bool +sil [serialized] @hash_external_subscript : $@convention(keypath_accessor_hash) (@in_guaranteed U) -> Int // CHECK-LABEL: sil_property [serialized] #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0) sil_property [serialized] #External.ro (stored_property #External.ro : $T) // CHECK-LABEL: sil_property [serialized] #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0, // CHECK-SAME: id @id_a : $@convention(thin) () -> (), -// CHECK-SAME: getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0) +// CHECK-SAME: getter @get_external_subscript : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, @in_guaranteed τ_0_1) -> @out τ_0_0) sil_property [serialized] #External.subscript (gettable_property $T, id @id_a : $@convention(thin) () -> (), - getter @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T) + getter @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T) diff --git a/test/SILGen/back_deployed_attr_accessor.swift b/test/SILGen/back_deployed_attr_accessor.swift index b3ed063e941cf..2262117d25efe 100644 --- a/test/SILGen/back_deployed_attr_accessor.swift +++ b/test/SILGen/back_deployed_attr_accessor.swift @@ -47,9 +47,9 @@ func caller(_ s: TopLevelStruct) { _ = s.property // -- Verify key path - // CHECK: {{%.*}} = keypath $KeyPath, (root $TopLevelStruct; gettable_property $TopLevelStruct, id @$s11back_deploy14TopLevelStructV8propertyACvg : $@convention(method) (TopLevelStruct) -> TopLevelStruct, getter @$s11back_deploy14TopLevelStructV8propertyACvpACTK : $@convention(thin) (@in_guaranteed TopLevelStruct) -> @out TopLevelStruct) + // CHECK: {{%.*}} = keypath $KeyPath, (root $TopLevelStruct; gettable_property $TopLevelStruct, id @$s11back_deploy14TopLevelStructV8propertyACvg : $@convention(method) (TopLevelStruct) -> TopLevelStruct, getter @$s11back_deploy14TopLevelStructV8propertyACvpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed TopLevelStruct) -> @out TopLevelStruct) _ = \TopLevelStruct.property } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s11back_deploy14TopLevelStructV8propertyACvpACTK : $@convention(thin) (@in_guaranteed TopLevelStruct) -> @out TopLevelStruct +// CHECK-LABEL: sil shared [thunk] [ossa] @$s11back_deploy14TopLevelStructV8propertyACvpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed TopLevelStruct) -> @out TopLevelStruct // CHECK: function_ref @$s11back_deploy14TopLevelStructV8propertyACvgTwb diff --git a/test/SILGen/default_arg_multiple_modules.swift b/test/SILGen/default_arg_multiple_modules.swift index 7a13494c6ef15..2897faf833edd 100644 --- a/test/SILGen/default_arg_multiple_modules.swift +++ b/test/SILGen/default_arg_multiple_modules.swift @@ -39,7 +39,7 @@ func test3() -> String { func test4() { // CHECK: [[DEF_ARG_FN:%[0-9]+]] = function_ref @$s17default_arg_other10Subscript1VyS2icipfA_ : $@convention(thin) () -> Int // CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_ARG_FN]]() {{.*}} - // CHECK: keypath $KeyPath, (root $Subscript1; gettable_property $Int, id @$s17default_arg_other10Subscript1VyS2icig : $@convention(method) (Int, Subscript1) -> Int, getter @$s17default_arg_other10Subscript1VyS2icipACTK : $@convention(thin) (@in_guaranteed Subscript1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int, external #Subscript1.subscript) ([[DEF_ARG]]) + // CHECK: keypath $KeyPath, (root $Subscript1; gettable_property $Int, id @$s17default_arg_other10Subscript1VyS2icig : $@convention(method) (Int, Subscript1) -> Int, getter @$s17default_arg_other10Subscript1VyS2icipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed Subscript1, @in_guaranteed Int) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int, external #Subscript1.subscript) ([[DEF_ARG]]) _ = \Subscript1.[] } @@ -48,6 +48,6 @@ func test5() { // This should not call default arg constructor // CHECK: [[STR_LIT:%[0-9]+]] = string_literal utf8 "test5()" // CHECK: [[DEF_ARG:%[0-9]+]] = apply %{{[0-9]+}}([[STR_LIT]], {{.*}} - // CHECK: keypath $KeyPath, (root $Subscript2; gettable_property $String, id @$s17default_arg_other10Subscript2VyS2Scig : $@convention(method) (@guaranteed String, Subscript2) -> @owned String, getter @$s17default_arg_other10Subscript2VyS2ScipACTK : $@convention(thin) (@in_guaranteed Subscript2, UnsafeRawPointer) -> @out String, indices [%$0 : $String : $String], indices_equals @$sSSTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSSTh : $@convention(thin) (UnsafeRawPointer) -> Int, external #Subscript2.subscript) ([[DEF_ARG]]) + // CHECK: keypath $KeyPath, (root $Subscript2; gettable_property $String, id @$s17default_arg_other10Subscript2VyS2Scig : $@convention(method) (@guaranteed String, Subscript2) -> @owned String, getter @$s17default_arg_other10Subscript2VyS2ScipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed Subscript2, @in_guaranteed String) -> @out String, indices [%$0 : $String : $String], indices_equals @$sSSTH : $@convention(keypath_accessor_equals) (@in_guaranteed String, @in_guaranteed String) -> Bool, indices_hash @$sSSTh : $@convention(keypath_accessor_hash) (@in_guaranteed String) -> Int, external #Subscript2.subscript) ([[DEF_ARG]]) _ = \Subscript2.[] } diff --git a/test/SILGen/keypath_accessors_reabstraction.swift b/test/SILGen/keypath_accessors_reabstraction.swift index 90edf0bbd61f5..517566017108d 100644 --- a/test/SILGen/keypath_accessors_reabstraction.swift +++ b/test/SILGen/keypath_accessors_reabstraction.swift @@ -14,13 +14,13 @@ func physicalFunctionValue() { let _ = \Foo.closure } // CHECK: // end sil function '{{.+}}physicalFunctionValue -// CHECK: sil shared [thunk] [ossa] @$[[GETTER]] : $@convention(thin) (@in_guaranteed Foo) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for > { +// CHECK: sil shared [thunk] [ossa] @$[[GETTER]] : $@convention(keypath_accessor_getter) (@in_guaranteed Foo) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for > { // CHECK: bb0([[OUT_FN:%[0-9]+]] {{.+}}): // CHECK: [[SRC_REABSTR:%[0-9]+]] = convert_function %{{[0-9]+}} : $@callee_guaranteed () -> @out Optional to $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for > // CHECK-NEXT: store [[SRC_REABSTR]] to [init] [[OUT_FN]] : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for > // CHECK: } // end sil function '$[[GETTER]]' -// CHECK: sil shared [thunk] [ossa] @$[[SETTER]] : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for >, @inout Foo) -> () { +// CHECK: sil shared [thunk] [ossa] @$[[SETTER]] : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for >, @inout Foo) -> () { // CHECK: bb0({{.+}}, [[FOO:%[0-9]+]] : $*Foo): // CHECK: [[SRC_REABSTR:%[0-9]+]] = convert_function %{{[0-9]+}} : $@callee_guaranteed () -> @out Optional to $@callee_guaranteed @substituted <τ_0_0> () -> @out Optional<τ_0_0> for // CHECK-NEXT: [[DEST:%[0-9]+]] = struct_element_addr [[FOO]] : $*Foo, #Foo.closure diff --git a/test/SILGen/keypaths.swift b/test/SILGen/keypaths.swift index 7ae5e8c2d3c54..99e6c43ed48f4 100644 --- a/test/SILGen/keypaths.swift +++ b/test/SILGen/keypaths.swift @@ -78,8 +78,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $S<τ_0_0>, // CHECK-SAME: id #C.nonfinal!getter : (C) -> () -> S, - // CHECK-SAME: getter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, - // CHECK-SAME: setter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, + // CHECK-SAME: setter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.nonfinal @@ -87,7 +87,7 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: gettable_property $S<τ_0_0>, // CHECK-SAME: id #C.computed!getter : (C) -> () -> S, - // CHECK-SAME: getter @$s8keypaths1CC8computedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0> + // CHECK-SAME: getter @$s8keypaths1CC8computedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0> // CHECK-SAME: ) _ = \C.computed @@ -95,8 +95,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $S<τ_0_0>, // CHECK-SAME: id #C.observed!getter : (C) -> () -> S, - // CHECK-SAME: getter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, - // CHECK-SAME: setter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, + // CHECK-SAME: setter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.observed @@ -111,15 +111,15 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $() -> (), // CHECK-SAME: id ##C.reabstracted, - // CHECK-SAME: getter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, - // CHECK-SAME: setter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, + // CHECK-SAME: setter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.reabstracted // CHECK: keypath $KeyPath, C>, <τ_0_0 where τ_0_0 : P> ( // CHECK-SAME: root $S<τ_0_0>; gettable_property $C<τ_0_0>, // CHECK-SAME: id @$s8keypaths1SV8computedAA1CCyxGvg : $@convention(method) <τ_0_0> (@in_guaranteed S<τ_0_0>) -> @owned C<τ_0_0>, - // CHECK-SAME: getter @$s8keypaths1SV8computedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0> + // CHECK-SAME: getter @$s8keypaths1SV8computedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0> // CHECK-SAME: ) _ = \S.computed @@ -127,8 +127,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $S<τ_0_0>; // CHECK-SAME: settable_property $C<τ_0_0>, // CHECK-SAME: id @$s8keypaths1SV8observedAA1CCyxGvg : $@convention(method) <τ_0_0> (@in_guaranteed S<τ_0_0>) -> @owned C<τ_0_0>, - // CHECK-SAME: getter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0>, - // CHECK-SAME: setter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>, @inout S<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0>, + // CHECK-SAME: setter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>, @inout S<τ_0_0>) -> () // CHECK-SAME: ) _ = \S.observed _ = \S.z.nonfinal @@ -140,8 +140,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $S<τ_0_0>; // CHECK-SAME: settable_property $() -> (), // CHECK-SAME: id ##S.reabstracted, - // CHECK-SAME: getter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, - // CHECK-SAME: setter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @inout S<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, + // CHECK-SAME: setter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @inout S<τ_0_0>) -> () // CHECK-SAME: ) _ = \S.reabstracted @@ -149,15 +149,15 @@ func computedProperties(_: T) { // CHECK-SAME: root $τ_0_0; // CHECK-SAME: gettable_property $Int, // CHECK-SAME: id #P.x!getter : (Self) -> () -> Int, - // CHECK-SAME: getter @$s8keypaths1PP1xSivpAaBRzlxTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out Int + // CHECK-SAME: getter @$s8keypaths1PP1xSivpAaBRzlxTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out Int // CHECK-SAME: ) _ = \T.x // CHECK: keypath $WritableKeyPath, <τ_0_0 where τ_0_0 : P> ( // CHECK-SAME: root $τ_0_0; // CHECK-SAME: settable_property $String, // CHECK-SAME: id #P.y!getter : (Self) -> () -> String, - // CHECK-SAME: getter @$s8keypaths1PP1ySSvpAaBRzlxTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out String, - // CHECK-SAME: setter @$s8keypaths1PP1ySSvpAaBRzlxTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed String, @inout τ_0_0) -> () + // CHECK-SAME: getter @$s8keypaths1PP1ySSvpAaBRzlxTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out String, + // CHECK-SAME: setter @$s8keypaths1PP1ySSvpAaBRzlxTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed String, @inout τ_0_0) -> () // CHECK-SAME: ) _ = \T.y @@ -178,7 +178,7 @@ func keyPathsWithSpecificGenericInstance() { // CHECK: keypath $KeyPath, ( // CHECK-SAME: gettable_property $String, // CHECK-SAME: id @$s8keypaths1PPAAE1zSSvg - // CHECK-SAME: getter @$s8keypaths1PPAAE1zSSvpAA8ConcreteVTK : $@convention(thin) (@in_guaranteed Concrete) -> @out String + // CHECK-SAME: getter @$s8keypaths1PPAAE1zSSvpAA8ConcreteVTK : $@convention(keypath_accessor_getter) (@in_guaranteed Concrete) -> @out String _ = \Concrete.z _ = \S.computed } @@ -425,7 +425,7 @@ func check_default_subscripts() { // CHECK: [[IX:%[0-9]+]] = apply %{{[0-9]+}}([[INTX]], {{.*}} // CHECK: [[INTY:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 0 // CHECK: [[IY:%[0-9]+]] = apply %{{[0-9]+}}([[INTY]], {{.*}} - // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(thin) (@in_guaranteed SubscriptDefaults4, UnsafeRawPointer) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(thin) (@in_guaranteed Int, @inout SubscriptDefaults4, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2iTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[IX]], [[IY]]) + // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults4, @in_guaranteed (Int, Int)) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout SubscriptDefaults4, @in_guaranteed (Int, Int)) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, Int), @in_guaranteed (Int, Int)) -> Bool, indices_hash @$sS2iTh : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, Int)) -> Int) ([[IX]], [[IY]]) _ = \SubscriptDefaults4.[x: 0, y: 0] // CHECK: [[INTINIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 0 @@ -434,21 +434,21 @@ func check_default_subscripts() { // CHECK: [[ALLOC:%[0-9]+]] = alloc_stack $Int // CHECK: apply [[DFN]]([[ALLOC]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Numeric> () -> @out τ_0_0 // CHECK: [[LOAD:%[0-9]+]] = load [trivial] [[ALLOC]] : $*Int - // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(thin) (@in_guaranteed SubscriptDefaults4, UnsafeRawPointer) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(thin) (@in_guaranteed Int, @inout SubscriptDefaults4, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2iTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[I]], [[LOAD]]) + // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults4, @in_guaranteed (Int, Int)) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout SubscriptDefaults4, @in_guaranteed (Int, Int)) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, Int), @in_guaranteed (Int, Int)) -> Bool, indices_hash @$sS2iTh : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, Int)) -> Int) ([[I]], [[LOAD]]) _ = \SubscriptDefaults4.[x: 0] // CHECK: [[STRX_LIT:%[0-9]+]] = string_literal utf8 "" // CHECK: [[STRX:%[0-9]+]] = apply %{{[0-9]+}}([[STRX_LIT]], {{.*}} // CHECK: [[STRY_LIT:%[0-9]+]] = string_literal utf8 "check_default_subscripts()" // CHECK: [[DEF_ARG:%[0-9]+]] = apply %{{[0-9]+}}([[STRY_LIT]], {{.*}} - // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(thin) (@in_guaranteed SubscriptDefaults5, UnsafeRawPointer) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(thin) (@in_guaranteed String, @inout SubscriptDefaults5, UnsafeRawPointer) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2STh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[STRX]], [[DEF_ARG]]) + // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults5, @in_guaranteed (String, String)) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout SubscriptDefaults5, @in_guaranteed (String, String)) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(keypath_accessor_equals) (@in_guaranteed (String, String), @in_guaranteed (String, String)) -> Bool, indices_hash @$sS2STh : $@convention(keypath_accessor_hash) (@in_guaranteed (String, String)) -> Int) ([[STRX]], [[DEF_ARG]]) _ = \SubscriptDefaults5.[x: ""] // CHECK: [[STRX_LIT:%[0-9]+]] = string_literal utf8 "" // CHECK: [[STRX:%[0-9]+]] = apply %{{[0-9]+}}([[STRX_LIT]], {{.*}} // CHECK: [[STRY_LIT:%[0-9]+]] = string_literal utf8 "" // CHECK: [[STRY:%[0-9]+]] = apply %{{[0-9]+}}([[STRY_LIT]], {{.*}} - // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(thin) (@in_guaranteed SubscriptDefaults5, UnsafeRawPointer) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(thin) (@in_guaranteed String, @inout SubscriptDefaults5, UnsafeRawPointer) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2STh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[STRX]], [[STRY]]) + // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults5, @in_guaranteed (String, String)) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout SubscriptDefaults5, @in_guaranteed (String, String)) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(keypath_accessor_equals) (@in_guaranteed (String, String), @in_guaranteed (String, String)) -> Bool, indices_hash @$sS2STh : $@convention(keypath_accessor_hash) (@in_guaranteed (String, String)) -> Int) ([[STRX]], [[STRY]]) _ = \SubscriptDefaults5.[x: "", y: ""] } @@ -472,7 +472,7 @@ func test_variadics() { // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) // CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF // CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]([[ARR]]) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic1, @in_guaranteed Array) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[FIN_ARR]]) _ = \SubscriptVariadic1.[1, 2, 3] // CHECK: [[ARR_COUNT:%[0-9]+]] = integer_literal $Builtin.Word, 1 // CHECK: [[FN_REF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF @@ -480,13 +480,13 @@ func test_variadics() { // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) // CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF // CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]([[ARR]]) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic1, @in_guaranteed Array) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[FIN_ARR]]) _ = \SubscriptVariadic1.[1] // CHECK: [[ARR_COUNT:%[0-9]+]] = integer_literal $Builtin.Word, 0 // CHECK: [[FN_REF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF // CHECK: [[MAKE_ARR:%[0-9]+]] = apply [[FN_REF]]([[ARR_COUNT]]) // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic1, @in_guaranteed Array) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[ARR]]) _ = \SubscriptVariadic1.[] _ = \SubscriptVariadic2.["", "1"] @@ -497,7 +497,7 @@ func test_variadics() { // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) // CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF // CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]([[ARR]]) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic2; gettable_property $String, id @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@guaranteed Array<τ_0_0>, SubscriptVariadic2) -> @out τ_0_0, getter @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(thin) (@in_guaranteed SubscriptVariadic2, UnsafeRawPointer) -> @out String, indices [%$0 : $Array : $Array], indices_equals @$sSaySSGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySSGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic2; gettable_property $String, id @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@guaranteed Array<τ_0_0>, SubscriptVariadic2) -> @out τ_0_0, getter @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic2, @in_guaranteed Array) -> @out String, indices [%$0 : $Array : $Array], indices_equals @$sSaySSGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySSGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[FIN_ARR]]) _ = \SubscriptVariadic2.["", #function] _ = \SubscriptVariadic3.[""] diff --git a/test/SILGen/keypaths_inlinable.swift b/test/SILGen/keypaths_inlinable.swift index f72f0fe7985a4..0373070cb0a9b 100644 --- a/test/SILGen/keypaths_inlinable.swift +++ b/test/SILGen/keypaths_inlinable.swift @@ -14,33 +14,33 @@ public struct KeypathStruct { // CHECK-LABEL: sil [serialized] [ossa] @$s18keypaths_inlinable11usesKeypathyyF : $@convention(thin) () -> () @inlinable public func usesKeypath() { // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; stored_property #KeypathStruct.stored : $Int) - // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Int, id @$s18keypaths_inlinable13KeypathStructV6storedSivg : $@convention(method) (@in_guaranteed KeypathStruct) -> Int, getter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out Int, setter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(thin) (@in_guaranteed Int, @inout KeypathStruct) -> (), external #KeypathStruct.stored) + // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Int, id @$s18keypaths_inlinable13KeypathStructV6storedSivg : $@convention(method) (@in_guaranteed KeypathStruct) -> Int, getter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out Int, setter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout KeypathStruct) -> (), external #KeypathStruct.stored) _ = \KeypathStruct.stored - // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> () - // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (@in_guaranteed KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> (), external #KeypathStruct.computed + // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout KeypathStruct) -> () + // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (@in_guaranteed KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout KeypathStruct) -> (), external #KeypathStruct.computed _ = \KeypathStruct.computed - // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int) ({{.*}}) - // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, @in_guaranteed KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int, external #KeypathStruct.subscript) ({{.*}}) + // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct, @in_guaranteed (Int, String)) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Bool, @inout KeypathStruct, @in_guaranteed (Int, String)) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, String), @in_guaranteed (Int, String)) -> Bool, indices_hash @$sSiSSThq : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, String)) -> Int) ({{.*}}) + // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, @in_guaranteed KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct, @in_guaranteed (Int, String)) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Bool, @inout KeypathStruct, @in_guaranteed (Int, String)) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, String), @in_guaranteed (Int, String)) -> Bool, indices_hash @$sSiSSThq : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, String)) -> Int, external #KeypathStruct.subscript) ({{.*}}) _ = \KeypathStruct[0, ""] } -// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out Int +// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out Int // RESILIENT: function_ref @$s18keypaths_inlinable13KeypathStructV6storedSivg -// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(thin) (@in_guaranteed Int, @inout KeypathStruct) -> () +// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout KeypathStruct) -> () // RESILIENT: function_ref @$s18keypaths_inlinable13KeypathStructV6storedSivs -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out String -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> () +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout KeypathStruct) -> () -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSTHq : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, String), @in_guaranteed (Int, String)) -> Bool -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSThq : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, String)) -> Int -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct, @in_guaranteed (Int, String)) -> @out Bool -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> () +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Bool, @inout KeypathStruct, @in_guaranteed (Int, String)) -> () diff --git a/test/SILGen/keypaths_objc_optional.swift b/test/SILGen/keypaths_objc_optional.swift index cdbb0a281365f..016d49f9571ae 100644 --- a/test/SILGen/keypaths_objc_optional.swift +++ b/test/SILGen/keypaths_objc_optional.swift @@ -25,22 +25,22 @@ import Foundation // CHECK: keypath $KeyPath>, (objc "flag"; root $any ObjCProtocol; gettable_property $Optional, id #ObjCProtocol.flag!getter.foreign : (Self) -> () -> Bool, getter @$[[OBJC_PROP_GETTER:[_a-zA-Z0-9]+]] // CHECK: } // end sil function '${{.*}}testKeyPathAccessorsForOptionalStorageComponentsyyF' // -// CHECK: sil shared [thunk] [ossa] @$[[SWIFT_PROP_GETTER]] : $@convention(thin) (@in_guaranteed any SwiftProtocol) -> @out Optional { +// CHECK: sil shared [thunk] [ossa] @$[[SWIFT_PROP_GETTER]] : $@convention(keypath_accessor_getter) (@in_guaranteed any SwiftProtocol) -> @out Optional { // CHECK: [[BASE:%[0-9]+]] = open_existential_ref {{%[0-9]+}} : $any SwiftProtocol to $[[OPENED_TY:@opened\("[-A-F0-9]+", any SwiftProtocol\) Self]] // CHECK: dynamic_method_br [[BASE]] : $[[OPENED_TY]], #SwiftProtocol.object!getter.foreign, bb1 // CHECK: bb1({{%[0-9]+}} : $@convention(objc_method) ([[OPENED_TY]]) -> @autoreleased Object) // CHECK: } // end sil function '$[[SWIFT_PROP_GETTER]]' // -// CHECK: sil shared [thunk] [ossa] @$[[SWIFT_SUBSCR_GETTER]] : $@convention(thin) (@in_guaranteed any SwiftProtocol, UnsafeRawPointer) -> @out Optional { +// CHECK: sil shared [thunk] [ossa] @$[[SWIFT_SUBSCR_GETTER]] : $@convention(keypath_accessor_getter) (@in_guaranteed any SwiftProtocol, @in_guaranteed Bool) -> @out Optional { // CHECK: [[BASE:%[0-9]+]] = open_existential_ref {{%[0-9]+}} : $any SwiftProtocol to $[[OPENED_TY:@opened\("[-A-F0-9]+", any SwiftProtocol\) Self]] // CHECK: [[INDEX:%[0-9]+]] = load [trivial] {{%[0-9]+}} : $*Bool // CHECK: dynamic_method_br [[BASE]] : $[[OPENED_TY]], #SwiftProtocol.subscript!getter.foreign, bb1, bb2 // CHECK: bb1({{%[0-9]+}} : $@convention(objc_method) (ObjCBool, [[OPENED_TY]]) -> @autoreleased Object): -// CHECK: %17 = apply {{%[0-9]+}}([[INDEX]]) : $@callee_guaranteed (Bool) -> @owned Object +// CHECK: apply {{%[0-9]+}}([[INDEX]]) : $@callee_guaranteed (Bool) -> @owned Object // CHECK: bb2: // CHECK: } // end sil function '$[[SWIFT_SUBSCR_GETTER]]' // -// CHECK: sil shared [thunk] [ossa] @$[[OBJC_PROP_GETTER]] : $@convention(thin) (@in_guaranteed any ObjCProtocol) -> @out Optional { +// CHECK: sil shared [thunk] [ossa] @$[[OBJC_PROP_GETTER]] : $@convention(keypath_accessor_getter) (@in_guaranteed any ObjCProtocol) -> @out Optional { // CHECK: bb0([[OUT:%[0-9]+]] : $*Optional, // CHECK: [[BASE:%[0-9]+]] = open_existential_ref {{%[0-9]+}} : $any ObjCProtocol to $[[OPENED_TY:@opened\("[-A-F0-9]+", any ObjCProtocol\) Self]] // CHECK: [[DEST:%[0-9]+]] = alloc_stack $Optional diff --git a/test/SILGen/keypaths_resilient_generic.swift b/test/SILGen/keypaths_resilient_generic.swift index 2a398ea6bd213..de883054da853 100644 --- a/test/SILGen/keypaths_resilient_generic.swift +++ b/test/SILGen/keypaths_resilient_generic.swift @@ -14,15 +14,15 @@ open class ConcreteSubclass : MySubclass { public final var anotherStoredProperty: Int? = nil } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(thin) (@in_guaranteed MySubclass) -> @out Optional { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(keypath_accessor_getter) (@in_guaranteed MySubclass) -> @out Optional { -// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(thin) (@in_guaranteed Optional, @in_guaranteed MySubclass) -> () { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(keypath_accessor_setter) (@in_guaranteed Optional, @in_guaranteed MySubclass) -> () { // CHECK: sil_property #MySubclass.storedProperty<τ_0_0> ( // CHECK-SAME: settable_property $Optional<τ_0_0>, // CHECK-SAME: id ##MySubclass.storedProperty, -// CHECK-SAME: getter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(thin) <τ_0_0> (@in_guaranteed MySubclass<τ_0_0>) -> @out Optional<τ_0_0>, -// CHECK-SAME: setter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed MySubclass<τ_0_0>) -> () +// CHECK-SAME: getter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0> (@in_guaranteed MySubclass<τ_0_0>) -> @out Optional<τ_0_0>, +// CHECK-SAME: setter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed MySubclass<τ_0_0>) -> () // CHECK-SAME: ) // CHECK: sil_property #ConcreteSubclass.anotherStoredProperty ( diff --git a/test/SILGen/opaque_result_type_class_property.swift b/test/SILGen/opaque_result_type_class_property.swift index 042f1b60c111e..3d54dc818b632 100644 --- a/test/SILGen/opaque_result_type_class_property.swift +++ b/test/SILGen/opaque_result_type_class_property.swift @@ -7,8 +7,8 @@ public class HasProperty { public var foo: some V = E() } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTK : $@convention(thin) (@in_guaranteed HasProperty) -> @out @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __ { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed HasProperty) -> @out @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __ { // CHECK: bb0(%0 : $*E, %1 : $*HasProperty): -// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTk : $@convention(thin) (@in_guaranteed @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __, @in_guaranteed HasProperty) -> () { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __, @in_guaranteed HasProperty) -> () { // CHECK: bb0(%0 : $*E, %1 : $*HasProperty): diff --git a/test/SILGen/property_wrapper_coroutine_public.swift b/test/SILGen/property_wrapper_coroutine_public.swift index 188df59cfb5e4..db0ddbf8caaf7 100644 --- a/test/SILGen/property_wrapper_coroutine_public.swift +++ b/test/SILGen/property_wrapper_coroutine_public.swift @@ -29,5 +29,5 @@ public class Store { } // CHECK-LABEL: sil [ossa] @$s33property_wrapper_coroutine_public5StoreC5stateypvM : $@yield_once @convention(method) (@guaranteed Store) -> @yields @inout Any { -// CHECK: keypath $ReferenceWritableKeyPath, (root $Store; settable_property $Any, id #Store.state!getter : (Store) -> () -> Any, getter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTK : $@convention(thin) (@in_guaranteed Store) -> @out Any, setter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTk : $@convention(thin) (@in_guaranteed Any, @in_guaranteed Store) -> ()) +// CHECK: keypath $ReferenceWritableKeyPath, (root $Store; settable_property $Any, id #Store.state!getter : (Store) -> () -> Any, getter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed Store) -> @out Any, setter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Any, @in_guaranteed Store) -> ()) // CHECK: keypath $ReferenceWritableKeyPath>, (root $Store; stored_property #Store._state : $Published) diff --git a/test/SILOptimizer/access_wmo.sil b/test/SILOptimizer/access_wmo.sil index d6512521af731..a714a6b254705 100644 --- a/test/SILOptimizer/access_wmo.sil +++ b/test/SILOptimizer/access_wmo.sil @@ -176,7 +176,7 @@ bb0(%0 : $C): // CHECK: begin_unpaired_access [modify] [dynamic] [[E3]] : $*Int64, %{{.*}} : $*Builtin.UnsafeValueBuffer // CHECK: [[E4:%.*]] = ref_element_addr %0 : $C, #C.internalProp // CHECK: begin_unpaired_access [modify] [dynamic] [[E4]] : $*Int64, %{{.*}} : $*Builtin.UnsafeValueBuffer -// CHECK: keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> ()) +// CHECK: keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> ()) // CHECK: keypath $ReferenceWritableKeyPath, (root $C; stored_property #C.finalKeyPathProp : $Int64) // CHECK: [[E5:%.*]] = ref_element_addr %0 : $C, #C.publicProp // CHECK: begin_unpaired_access [modify] [dynamic] [[E5]] : $*Int64, %{{.*}} : $*Builtin.UnsafeValueBuffer @@ -207,7 +207,7 @@ bb0(%0 : $C, %1 : $Int64): %22 = apply %8(%21, %1) : $@convention(thin) (@inout Int64, Int64) -> () end_unpaired_access [dynamic] %18 : $*Builtin.UnsafeValueBuffer dealloc_stack %18 : $*Builtin.UnsafeValueBuffer - %25 = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> ()) + %25 = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> ()) // function_ref setKeyPath(_:_:_:) %26 = function_ref @$s10access_wmo10setKeyPathyyAA1CC_s017ReferenceWritabledE0CyADSiGSitF : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int64) -> () %27 = apply %26(%0, %25, %1) : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int64) -> () @@ -228,10 +228,10 @@ bb0(%0 : $C, %1 : $Int64): // key path getter for C.keyPathProp : C // -// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64 { +// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64 { // CHECK: begin_access [read] [static] [no_nested_conflict] %{{.*}} : $*Int64 // CHECK-LABEL: } // end sil function '$s10access_wmo1CC11keyPathPropSivpACTK' -sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64 { +sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64 { bb0(%0 : $*Int64, %1 : $*C): %2 = load %1 : $*C // user: %3 %3 = ref_element_addr %2 : $C, #C.keyPathProp // user: %4 @@ -245,10 +245,10 @@ bb0(%0 : $*Int64, %1 : $*C): // key path setter for C.keyPathProp : C // -// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> () { +// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> () { // CHECK: begin_access [modify] [static] [no_nested_conflict] %{{.*}} : $*Int64 // CHECK-LABEL: } // end sil function '$s10access_wmo1CC11keyPathPropSivpACTk' -sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> () { +sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> () { bb0(%0 : $*Int64, %1 : $*C): %2 = load %0 : $*Int64 // user: %6 %3 = load %1 : $*C // user: %4 diff --git a/test/SILOptimizer/access_wmo.swift b/test/SILOptimizer/access_wmo.swift index 354316d4fb2fb..cdb940b7a5740 100644 --- a/test/SILOptimizer/access_wmo.swift +++ b/test/SILOptimizer/access_wmo.swift @@ -225,7 +225,7 @@ public func testAccessProp(c: C, v: Int) { // WMO: apply [[F1]]([[A4]], %1) : $@convention(thin) (@inout Int, Int) -> () // WMO: end_access [[A4]] // -// WMO: [[KP:%.*]] = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int, id #C.keyPathProp!getter : (C) -> () -> Int, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) +// WMO: [[KP:%.*]] = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int, id #C.keyPathProp!getter : (C) -> () -> Int, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) // function_ref setKeyPath(_:_:_:) // WMO: [[F2:%.*]] = function_ref @$s10access_wmo10setKeyPathyyAA1CC_s017ReferenceWritabledE0CyADSiGSitF : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int) -> () // WMO: apply [[F2]](%0, [[KP]], %1) : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int) -> () diff --git a/test/SILOptimizer/dead_alloc_elim.sil b/test/SILOptimizer/dead_alloc_elim.sil index 09d7fb142fcfa..b7b48e02f7c87 100644 --- a/test/SILOptimizer/dead_alloc_elim.sil +++ b/test/SILOptimizer/dead_alloc_elim.sil @@ -656,9 +656,9 @@ struct I { struct S2 { } sil @getter : $@convention(method) (@guaranteed KeyPath, S2) -> @out II -sil @kpgetter : $@convention(thin) (@in_guaranteed S2, UnsafeRawPointer) -> @out II -sil @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @hsh : $@convention(thin) (UnsafeRawPointer) -> Int +sil @kpgetter : $@convention(keypath_accessor_getter) (@in_guaranteed S2, @in_guaranteed KeyPath) -> @out II +sil @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool +sil @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int // CHECK-LABEL: sil @remove_dead_keypath @@ -667,7 +667,7 @@ sil @hsh : $@convention(thin) (UnsafeRawPointer) -> Int sil @remove_dead_keypath: $@convention(thin) () -> () { bb0: %0 = keypath $KeyPath, (root $I; stored_property #I.x : $II) - %1 = keypath $KeyPath, (root $S2; gettable_property $II, id @getter : $@convention(method) (@guaranteed KeyPath, S2) -> @out II, getter @kpgetter: $@convention(thin) (@in_guaranteed S2, UnsafeRawPointer) -> @out II, indices [%$0 : $KeyPath : $KeyPath], indices_equals @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @hsh : $@convention(thin) (UnsafeRawPointer) -> Int) (%0) + %1 = keypath $KeyPath, (root $S2; gettable_property $II, id @getter : $@convention(method) (@guaranteed KeyPath, S2) -> @out II, getter @kpgetter: $@convention(keypath_accessor_getter) (@in_guaranteed S2, @in_guaranteed KeyPath) -> @out II, indices [%$0 : $KeyPath : $KeyPath], indices_equals @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) (%0) %r = tuple () return %r : $() diff --git a/test/SILOptimizer/dead_alloc_elim_ossa.sil b/test/SILOptimizer/dead_alloc_elim_ossa.sil index aedee7501f335..4a7f6846765fe 100644 --- a/test/SILOptimizer/dead_alloc_elim_ossa.sil +++ b/test/SILOptimizer/dead_alloc_elim_ossa.sil @@ -465,11 +465,11 @@ struct I { struct S2 { } sil @getter1 : $@convention(method) (@guaranteed KeyPath, S2) -> @out II -sil @kpgetter1 : $@convention(thin) (@in_guaranteed S2, UnsafeRawPointer) -> @out II -sil @getter2 : $@convention(method) (@guaranteed String, Foo) -> @owned String -sil @kpgetter2 : $@convention(thin) (@in_guaranteed Foo, UnsafeRawPointer) -> @out String -sil @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @hsh : $@convention(thin) (UnsafeRawPointer) -> Int +sil @kpgetter1 : $@convention(keypath_accessor_getter) (@in_guaranteed S2, @in_guaranteed KeyPath) -> @out II +sil @getter2 : $@convention(keypath_accessor_getter) (@guaranteed String, Foo) -> @owned String +sil @kpgetter2 : $@convention(keypath_accessor_getter) (@in_guaranteed Foo, @in_guaranteed KeyPath) -> @out String +sil @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool +sil @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int // CHECK-LABEL: sil [ossa] @remove_dead_keypath @@ -478,7 +478,7 @@ sil @hsh : $@convention(thin) (UnsafeRawPointer) -> Int sil [ossa] @remove_dead_keypath: $@convention(thin) () -> () { bb0: %0 = keypath $KeyPath, (root $I; stored_property #I.x : $II) - %1 = keypath $KeyPath, (root $S2; gettable_property $II, id @getter1 : $@convention(method) (@guaranteed KeyPath, S2) -> @out II, getter @kpgetter1: $@convention(thin) (@in_guaranteed S2, UnsafeRawPointer) -> @out II, indices [%$0 : $KeyPath : $KeyPath], indices_equals @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @hsh : $@convention(thin) (UnsafeRawPointer) -> Int) (%0) + %1 = keypath $KeyPath, (root $S2; gettable_property $II, id @getter1 : $@convention(method) (@guaranteed KeyPath, S2) -> @out II, getter @kpgetter1: $@convention(keypath_accessor_getter) (@in_guaranteed S2, @in_guaranteed KeyPath) -> @out II, indices [%$0 : $KeyPath : $KeyPath], indices_equals @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) (%0) destroy_value %1 : $KeyPath %r = tuple () return %r : $() @@ -494,7 +494,7 @@ struct Foo { // CHECK: } // end sil function 'remove_nontrivial_dead_keypath' sil [ossa] @remove_nontrivial_dead_keypath : $@convention(thin) (@owned String) -> () { bb0(%0 : @owned $String): - %3 = keypath $KeyPath, (root $Foo; gettable_property $String, id @getter2 : $@convention(method) (@guaranteed String, Foo) -> @owned String, getter @kpgetter2 : $@convention(thin) (@in_guaranteed Foo, UnsafeRawPointer) -> @out String, indices [%$0 : $String : $String], indices_equals @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @hsh : $@convention(thin) (UnsafeRawPointer) -> Int) (%0) // user: %4 + %3 = keypath $KeyPath, (root $Foo; gettable_property $String, id @getter2 : $@convention(keypath_accessor_getter) (@guaranteed String, Foo) -> @owned String, getter @kpgetter2 : $@convention(keypath_accessor_getter) (@in_guaranteed Foo, @in_guaranteed KeyPath) -> @out String, indices [%$0 : $String : $String], indices_equals @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) (%0) // user: %4 destroy_value %3 : $KeyPath %r = tuple () return %r : $() diff --git a/test/SILOptimizer/function_uses.sil b/test/SILOptimizer/function_uses.sil index 48110a6df0d41..2885e7855cde9 100644 --- a/test/SILOptimizer/function_uses.sil +++ b/test/SILOptimizer/function_uses.sil @@ -86,8 +86,8 @@ bb0: // CHECK-NEXT: @test_keypath: %2 = keypath {{.*}} // CHECK-NEXT: ] // CHECK-NEXT: End function get_s_int_subs -sil hidden @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int { -bb0(%0 : $*Int, %1 : $*S, %2 : $UnsafeRawPointer): +sil hidden @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int { +bb0(%0 : $*Int, %1 : $*S, %2 : $*(S, C)): unreachable } @@ -97,8 +97,8 @@ bb0(%0 : $*Int, %1 : $*S, %2 : $UnsafeRawPointer): // CHECK-NEXT: ] // CHECK-NEXT: End function set_s_int_subs -sil hidden @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () { -bb0(%0 : $*Int, %1 : $*S, %2 : $UnsafeRawPointer): +sil hidden @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> () { +bb0(%0 : $*Int, %1 : $*S, %2 : $*(S, C)): unreachable } @@ -107,8 +107,8 @@ bb0(%0 : $*Int, %1 : $*S, %2 : $UnsafeRawPointer): // CHECK-NEXT: @test_keypath: %2 = keypath {{.*}} // CHECK-NEXT: ] // CHECK-NEXT: End function subs_eq -sil hidden @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool { -bb0(%0 : $UnsafeRawPointer, %1 : $UnsafeRawPointer): +sil hidden @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool { +bb0(%0 : $*(S, C), %1 : $*(S, C)): unreachable } @@ -117,8 +117,8 @@ bb0(%0 : $UnsafeRawPointer, %1 : $UnsafeRawPointer): // CHECK-NEXT: @test_keypath: %2 = keypath {{.*}} // CHECK-NEXT: ] // CHECK-NEXT: End function subs_hash -sil hidden @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int { -bb0(%0 : $UnsafeRawPointer): +sil hidden @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int { +bb0(%0 : $*(S, C)): unreachable } @@ -129,7 +129,7 @@ bb0(%0 : $UnsafeRawPointer): // CHECK-NEXT: End function test_keypath sil @test_keypath : $@convention(thin) (S, C) -> () { bb0(%0 : $S, %1 : $C): - %2 = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%0, %1) + %2 = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%0, %1) %7 = tuple () return %7 : $() } diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil index a43bf9d7b821f..b9a4603417f6a 100644 --- a/test/SILOptimizer/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -4275,8 +4275,8 @@ class Kp2 { init() } -sil @kpgetter : $@convention(thin) (@in_guaranteed Kp2) -> @out String -sil @kpsetter : $@convention(thin) (@in_guaranteed String, @in_guaranteed Kp2) -> () +sil @kpgetter : $@convention(keypath_accessor_getter) (@in_guaranteed Kp2) -> @out String +sil @kpsetter : $@convention(keypath_accessor_setter) (@in_guaranteed String, @in_guaranteed Kp2) -> () sil @swift_getAtKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed KeyPath<τ_0_0, τ_0_1>) -> @out τ_0_1 // Test keypath optimization for optional chaining with accesses scopes. @@ -4294,7 +4294,7 @@ sil @swift_getAtKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ // CHECK: } // end sil function 'test_optional_chaining_keypath' sil @test_optional_chaining_keypath : $@convention(thin) (@in_guaranteed Kp1) -> @out Optional { bb0(%0 : $*Optional, %1 : $*Kp1): - %kp = keypath $KeyPath>, (root $Kp1; stored_property #Kp1.b : $Optional; optional_chain : $Kp2; settable_property $String, id #Kp2.s!getter : (Kp2) -> () -> String, getter @kpgetter : $@convention(thin) (@in_guaranteed Kp2) -> @out String, setter @kpsetter : $@convention(thin) (@in_guaranteed String, @in_guaranteed Kp2) -> (); optional_wrap : $Optional) + %kp = keypath $KeyPath>, (root $Kp1; stored_property #Kp1.b : $Optional; optional_chain : $Kp2; settable_property $String, id #Kp2.s!getter : (Kp2) -> () -> String, getter @kpgetter : $@convention(keypath_accessor_getter) (@in_guaranteed Kp2) -> @out String, setter @kpsetter : $@convention(keypath_accessor_setter) (@in_guaranteed String, @in_guaranteed Kp2) -> (); optional_wrap : $Optional) %f = function_ref @swift_getAtKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed KeyPath<τ_0_0, τ_0_1>) -> @out τ_0_1 %a = apply %f>(%0, %1, %kp) : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed KeyPath<τ_0_0, τ_0_1>) -> @out τ_0_1 strong_release %kp : $KeyPath>