diff --git a/include/swift/AST/ASTDemangler.h b/include/swift/AST/ASTDemangler.h index 58bcf68281a..ed75a613abb 100644 --- a/include/swift/AST/ASTDemangler.h +++ b/include/swift/AST/ASTDemangler.h @@ -276,6 +276,8 @@ public: Type createBuiltinFixedArrayType(Type size, Type element); + Type createBuiltinBorrowType(Type referent); + BuiltGenericSignature createGenericSignature(ArrayRef params, ArrayRef requirements); diff --git a/include/swift/AST/TypeNodes.def b/include/swift/AST/TypeNodes.def index b49e9958dd8..52100bae686 100644 --- a/include/swift/AST/TypeNodes.def +++ b/include/swift/AST/TypeNodes.def @@ -143,7 +143,8 @@ ABSTRACT_TYPE(Builtin, Type) BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType) ABSTRACT_TYPE(BuiltinGeneric, BuiltinType) BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinGenericType) - TYPE_RANGE(BuiltinGeneric, BuiltinFixedArray, BuiltinFixedArray) + BUILTIN_GENERIC_TYPE(BuiltinBorrow, BuiltinGenericType) + TYPE_RANGE(BuiltinGeneric, BuiltinFixedArray, BuiltinBorrow) BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType) BUILTIN_CONCRETE_TYPE(BuiltinImplicitActor, BuiltinType) TYPE_RANGE(Builtin, BuiltinInteger, BuiltinImplicitActor) diff --git a/include/swift/AST/TypeTransform.h b/include/swift/AST/TypeTransform.h index 74f77278c42..d04aff01a18 100644 --- a/include/swift/AST/TypeTransform.h +++ b/include/swift/AST/TypeTransform.h @@ -120,6 +120,7 @@ case TypeKind::Id: return t; // BuiltinGenericType subclasses + case TypeKind::BuiltinBorrow: case TypeKind::BuiltinFixedArray: { auto bgaTy = cast(base); diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 56456d62ae5..eef66bee7cf 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -1830,7 +1830,7 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinGenericType, BuiltinType) /// value may be copied, moved, or destroyed. class BuiltinFixedArrayType : public BuiltinGenericType, public llvm::FoldingSetNode { - friend class ASTContext; + friend ASTContext; CanType Size; CanType ElementType; @@ -1887,6 +1887,46 @@ public: }; DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinGenericType) +/// BuiltinBorrowType - The builtin type representing a reified borrow of +/// another value. +class BuiltinBorrowType : public BuiltinGenericType, + public llvm::FoldingSetNode +{ + friend ASTContext; + + CanType Referent; + + BuiltinBorrowType(CanType Referent, RecursiveTypeProperties properties) + : BuiltinGenericType(TypeKind::BuiltinBorrow, + Referent->getASTContext(), + properties), + Referent(Referent) + {} + + friend BuiltinGenericType; + /// Get the generic arguments as a substitution map. + SubstitutionMap buildSubstitutions() const; + +public: + static bool classof(const TypeBase *T) { + return T->getKind() == TypeKind::BuiltinBorrow; + } + + static BuiltinBorrowType *get(CanType Referent); + + /// Get the type of the referenced borrow. + CanType getReferentType() const { return Referent; } + + void Profile(llvm::FoldingSetNodeID &ID) const { + Profile(ID, getReferentType()); + } + static void Profile(llvm::FoldingSetNodeID &ID, + CanType Referent) { + ID.AddPointer(Referent.getPointer()); + } +}; +DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinBorrowType, BuiltinGenericType) + /// BuiltinRawPointerType - The builtin raw (and dangling) pointer type. This /// pointer is completely unmanaged and is equivalent to i8* in LLVM IR. class BuiltinRawPointerType : public BuiltinType { diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 6cfa2de348c..0e913b9cdb7 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -47,6 +47,7 @@ NODE(BoundGenericFunction) NODE(BuiltinTypeName) NODE(BuiltinTupleType) NODE(BuiltinFixedArray) +NODE(BuiltinBorrow) NODE(CFunctionPointer) NODE(ClangType) CONTEXT_NODE(Class) diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index e5811d7ff6f..358aa6168ed 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -1614,21 +1614,33 @@ protected: return Builder.createNegativeIntegerType((intptr_t)Node->getIndex()); } + case NodeKind::BuiltinBorrow: { + if (Node->getNumChildren() < 1) { + return MAKE_NODE_TYPE_ERROR(Node, + "fewer children (%zu) than required (1)", + Node->getNumChildren()); + } + auto referent = decodeMangledType(Node->getChild(0), depth + 1); + if (referent.isError()) + return referent; + return Builder.createBuiltinBorrowType(referent.getType()); + } + case NodeKind::BuiltinFixedArray: { - if (Node->getNumChildren() < 2) + if (Node->getNumChildren() < 2) { return MAKE_NODE_TYPE_ERROR(Node, "fewer children (%zu) than required (2)", Node->getNumChildren()); - + } auto size = decodeMangledType(Node->getChild(0), depth + 1); if (size.isError()) return size; - auto element = decodeMangledType(Node->getChild(1), depth + 1); if (element.isError()) return element; - return Builder.createBuiltinFixedArrayType(size.getType(), element.getType()); + return Builder.createBuiltinFixedArrayType(size.getType(), + element.getType()); } // TODO: Handle OpaqueReturnType, when we're in the middle of reconstructing diff --git a/include/swift/RemoteInspection/TypeLowering.h b/include/swift/RemoteInspection/TypeLowering.h index a5ec50f72c0..134f68823bd 100644 --- a/include/swift/RemoteInspection/TypeLowering.h +++ b/include/swift/RemoteInspection/TypeLowering.h @@ -118,6 +118,7 @@ enum class TypeInfoKind : unsigned { Invalid, Enum, Array, + Borrow, }; class TypeInfo { diff --git a/include/swift/RemoteInspection/TypeRef.h b/include/swift/RemoteInspection/TypeRef.h index 354492a497b..e4b304882f2 100644 --- a/include/swift/RemoteInspection/TypeRef.h +++ b/include/swift/RemoteInspection/TypeRef.h @@ -1270,6 +1270,34 @@ public: } }; +class BuiltinBorrowTypeRef final : public TypeRef { + const TypeRef *Referent; + + static TypeRefID Profile(const TypeRef *Referent) { + TypeRefID ID; + ID.addPointer(Referent); + return ID; + } + +public: + BuiltinBorrowTypeRef(const TypeRef *Referent) + : TypeRef(TypeRefKind::BuiltinBorrow), Referent(Referent) {} + + template + static const BuiltinBorrowTypeRef *create(Allocator &A, + const TypeRef *Referent) { + FIND_OR_CREATE_TYPEREF(A, BuiltinBorrowTypeRef, Referent); + } + + const TypeRef *getReferentType() const { + return Referent; + } + + static bool classof(const TypeRef *TR) { + return TR->getKind() == TypeRefKind::BuiltinBorrow; + } +}; + template class TypeRefVisitor { public: diff --git a/include/swift/RemoteInspection/TypeRefBuilder.h b/include/swift/RemoteInspection/TypeRefBuilder.h index 16c42bad0f9..dfbc5ca1a41 100644 --- a/include/swift/RemoteInspection/TypeRefBuilder.h +++ b/include/swift/RemoteInspection/TypeRefBuilder.h @@ -963,6 +963,10 @@ public: return BuiltinFixedArrayTypeRef::create(*this, size, element); } + const TypeRef *createBuiltinBorrowType(const TypeRef *referent) { + return BuiltinBorrowTypeRef::create(*this, referent); + } + // Construct a bound generic type ref along with the parent type info // The parent list contains every parent type with at least 1 generic // type parameter. diff --git a/include/swift/RemoteInspection/TypeRefs.def b/include/swift/RemoteInspection/TypeRefs.def index 0fcd9929997..d3eeac6c646 100644 --- a/include/swift/RemoteInspection/TypeRefs.def +++ b/include/swift/RemoteInspection/TypeRefs.def @@ -40,6 +40,7 @@ TYPEREF(SILBox, TypeRef) TYPEREF(SILBoxTypeWithLayout, TypeRef) TYPEREF(Integer, TypeRef) TYPEREF(BuiltinFixedArray, TypeRef) +TYPEREF(BuiltinBorrow, TypeRef) TYPEREF(Pack, TypeRef) TYPEREF(PackExpansion, TypeRef) diff --git a/include/swift/Strings.h b/include/swift/Strings.h index 20cf33e0130..db239e2f8e1 100644 --- a/include/swift/Strings.h +++ b/include/swift/Strings.h @@ -180,6 +180,8 @@ constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_VEC = { "Builtin.Vec"}; constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_FIXEDARRAY = { "Builtin.FixedArray"}; +constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_BORROW = { + "Builtin.Borrow"}; /// The name of the Builtin type for SILToken constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_SILTOKEN = { "Builtin.SILToken"}; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 85255280b86..4987808d0d1 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -591,6 +591,7 @@ struct ASTContext::Implementation { llvm::FoldingSet UnboundGenericTypes; llvm::FoldingSet BoundGenericTypes; llvm::FoldingSet BuiltinFixedArrayTypes; + llvm::FoldingSet BuiltinBorrowTypes; llvm::FoldingSet ProtocolCompositionTypes; llvm::FoldingSet ParameterizedProtocolTypes; llvm::FoldingSet LayoutConstraints; @@ -3839,6 +3840,29 @@ BuiltinFixedArrayType *BuiltinFixedArrayType::get(CanType Size, return faTy; } +BuiltinBorrowType *BuiltinBorrowType::get(CanType Referent) { + RecursiveTypeProperties properties; + properties |= Referent->getRecursiveProperties(); + + AllocationArena arena = getArena(properties); + + llvm::FoldingSetNodeID id; + BuiltinBorrowType::Profile(id, Referent); + auto &ctx = Referent->getASTContext(); + + void *insertPos; + if (BuiltinBorrowType *faTy + = ctx.getImpl().getArena(arena).BuiltinBorrowTypes + .FindNodeOrInsertPos(id, insertPos)) + return faTy; + + BuiltinBorrowType *faTy + = new (ctx, arena) BuiltinBorrowType(Referent, properties); + ctx.getImpl().getArena(arena).BuiltinBorrowTypes + .InsertNode(faTy, insertPos); + return faTy; +} + BuiltinVectorType *BuiltinVectorType::get(const ASTContext &context, Type elementType, unsigned numElements) { diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 58064b56a15..f15ad2ffb84 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -1233,6 +1233,10 @@ Type ASTBuilder::createBuiltinFixedArrayType(Type size, Type element) { element->getCanonicalType()); } +Type ASTBuilder::createBuiltinBorrowType(Type referent) { + return BuiltinBorrowType::get(referent->getCanonicalType()); +} + GenericSignature ASTBuilder::createGenericSignature(ArrayRef builtParams, ArrayRef requirements) { diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index f82f3393301..9608d760ea9 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -6245,6 +6245,13 @@ namespace { printFoot(); } + void visitBuiltinBorrowType(BuiltinBorrowType *T, + Label label) { + printCommon("builtin_borrow_type", label); + printRec(T->getReferentType(), Label::optional("referent")); + printFoot(); + } + void visitTypeAliasType(TypeAliasType *T, Label label) { printCommon("type_alias_type", label); diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index a5fe6adc203..721b1b53680 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -43,7 +43,6 @@ #include "swift/ClangImporter/ClangImporter.h" #include "swift/ClangImporter/ClangModule.h" #include "swift/Demangling/Demangler.h" -#include "swift/Demangling/ManglingMacros.h" #include "swift/Demangling/ManglingUtils.h" #include "swift/Strings.h" #include "clang/AST/ASTContext.h" @@ -54,11 +53,9 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Mangle.h" #include "clang/Basic/CharInfo.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" @@ -1469,6 +1466,11 @@ void ASTMangler::appendType(Type type, GenericSignature sig, appendType(bfa->getElementType(), sig, forDecl); return appendOperator("BV"); } + case TypeKind::BuiltinBorrow: { + auto bfa = cast(tybase); + appendType(bfa->getReferentType(), sig, forDecl); + return appendOperator("BW"); + } case TypeKind::SILToken: return appendOperator("Bt"); diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 66e117ca73b..6c8cd4cf52c 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -6362,6 +6362,16 @@ public: Printer << ">"; } + void visitBuiltinBorrowType(BuiltinBorrowType *T, + NonRecursivePrintOptions nrOptions) { + SmallString<32> buffer; + T->getTypeName(buffer); + Printer << buffer; + Printer << "<"; + visit(T->getReferentType()); + Printer << ">"; + } + void visitSILTokenType(SILTokenType *T, NonRecursivePrintOptions nrOptions) { Printer << BUILTIN_TYPE_NAME_SILTOKEN; diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index c7eb499aa9f..93a1cf6c69c 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -67,6 +67,7 @@ Type swift::getBuiltinType(ASTContext &Context, StringRef Name) { auto kind = llvm::StringSwitch>(Name) .Case("FixedArray", BuiltinTypeKind::BuiltinFixedArray) + .Case("Borrow", BuiltinTypeKind::BuiltinBorrow) .StartsWith("Vec", BuiltinTypeKind::BuiltinVector) .Case("RawPointer", BuiltinTypeKind::BuiltinRawPointer) .Case("RawUnsafeContinuation", @@ -104,6 +105,9 @@ Type swift::getBuiltinType(ASTContext &Context, StringRef Name) { case BuiltinTypeKind::BuiltinFixedArray: return BuiltinUnboundGenericType::get(TypeKind::BuiltinFixedArray, Context); + case BuiltinTypeKind::BuiltinBorrow: + return BuiltinUnboundGenericType::get(TypeKind::BuiltinBorrow, Context); + case BuiltinTypeKind::BuiltinVector: { // Vectors are VecNxT, where "N" is the number of elements and // T is the element type. @@ -3582,6 +3586,7 @@ bool BuiltinType::isBitwiseCopyable() const { case BuiltinTypeKind::BuiltinExecutor: case BuiltinTypeKind::BuiltinJob: case BuiltinTypeKind::BuiltinRawUnsafeContinuation: + case BuiltinTypeKind::BuiltinBorrow: return true; case BuiltinTypeKind::BuiltinNativeObject: case BuiltinTypeKind::BuiltinBridgeObject: @@ -3713,6 +3718,9 @@ StringRef BuiltinType::getTypeName(SmallVectorImpl &result, case BuiltinTypeKind::BuiltinFixedArray: printer << MAYBE_GET_NAMESPACED_BUILTIN(BUILTIN_TYPE_NAME_FIXEDARRAY); break; + case BuiltinTypeKind::BuiltinBorrow: + printer << MAYBE_GET_NAMESPACED_BUILTIN(BUILTIN_TYPE_NAME_BORROW); + break; case BuiltinTypeKind::BuiltinUnboundGeneric: { auto bug = cast(this); printer << MAYBE_GET_NAMESPACED_BUILTIN(bug->getBuiltinTypeName()); @@ -3729,6 +3737,8 @@ BuiltinUnboundGenericType::getBuiltinTypeName() const { switch (BoundGenericTypeKind) { case TypeKind::BuiltinFixedArray: return BUILTIN_TYPE_NAME_FIXEDARRAY; + case TypeKind::BuiltinBorrow: + return BUILTIN_TYPE_NAME_BORROW; case TypeKind::BuiltinInteger: return BUILTIN_TYPE_NAME_INT; @@ -3756,6 +3766,13 @@ getBuiltinGenericSignature(ASTContext &C, return GenericSignature::get({Count, Element}, {}); } + case TypeKind::BuiltinBorrow: { + auto Referent = GenericTypeParamType::get(C.getIdentifier("Referent"), + GenericTypeParamKind::Type, + 0, 0, Type(), C); + return GenericSignature::get({Referent}, {}); + } + case TypeKind::BuiltinInteger: { auto bits = GenericTypeParamType::get(C.getIdentifier("Bits"), GenericTypeParamKind::Type, @@ -3802,6 +3819,14 @@ getBuiltinBoundGenericType(ASTContext &C, return BuiltinFixedArrayType::get(size, element); } + case TypeKind::BuiltinBorrow: { + auto types = subs.getReplacementTypes(); + + auto referent = types[0]->getCanonicalType(); + + return BuiltinBorrowType::get(referent); + } + case TypeKind::BuiltinInteger: { auto size = subs.getReplacementTypes()[0]; if (validate @@ -3863,6 +3888,7 @@ BuiltinGenericType::getSubstitutions() const { } BUILTIN_GENERIC_SUBCLASS(BuiltinFixedArrayType) + BUILTIN_GENERIC_SUBCLASS(BuiltinBorrowType) llvm_unreachable("unhandled BuiltinGenericType subclass"); }; @@ -3878,6 +3904,13 @@ BuiltinFixedArrayType::buildSubstitutions() const { ArrayRef{}); } +SubstitutionMap +BuiltinBorrowType::buildSubstitutions() const { + return SubstitutionMap::get(getGenericSignature(), + {getReferentType()}, + ArrayRef{}); +} + std::optional BuiltinFixedArrayType::getFixedInhabitedSize() const { if (auto intSize = getSize()->getAs()) { diff --git a/lib/AST/ConformanceLookup.cpp b/lib/AST/ConformanceLookup.cpp index 8124ada2255..2d48e9fe506 100644 --- a/lib/AST/ConformanceLookup.cpp +++ b/lib/AST/ConformanceLookup.cpp @@ -30,6 +30,7 @@ #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/GenericEnvironment.h" +#include "swift/AST/KnownProtocols.h" #include "swift/AST/Module.h" #include "swift/AST/NameLookup.h" #include "swift/AST/NameLookupRequests.h" @@ -37,6 +38,7 @@ #include "swift/AST/PrettyStackTrace.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/TypeCheckRequests.h" +#include "swift/AST/Types.h" #include "swift/Basic/Assertions.h" #include "swift/Basic/Compiler.h" #include "swift/Basic/SourceManager.h" @@ -487,6 +489,8 @@ getBuiltinBuiltinTypeConformance(Type type, const BuiltinType *builtinType, ASTContext &ctx = protocol->getASTContext(); // FixedArray is Sendable, Copyable, or Escapable if its element type is. + // FIXME: If the type arguments contain type variables, this should set + // up a proper conditional conformance. if (auto bfa = dyn_cast(builtinType)) { if (lookupConformance(bfa->getElementType(), protocol)) { return ProtocolConformanceRef( @@ -495,6 +499,28 @@ getBuiltinBuiltinTypeConformance(Type type, const BuiltinType *builtinType, } break; } + + if (auto bba = dyn_cast(builtinType)) { + // Borrow is always Copyable. + if (*kp == KnownProtocolKind::Copyable) { + return ProtocolConformanceRef( + ctx.getBuiltinConformance(type, protocol, + BuiltinConformanceKind::Synthesized)); + } + // Borrow is never Escapable. + if (*kp == KnownProtocolKind::Escapable) { + return ProtocolConformanceRef::forMissingOrInvalid(type, protocol); + } + + // Borrow is Sendable[Metatype] if its element type is. + // FIXME: If the type arguments contain type variables, this should set + // up a proper conditional conformance. + if (lookupConformance(bba->getReferentType(), protocol)) { + return ProtocolConformanceRef( + ctx.getBuiltinConformance(type, protocol, + BuiltinConformanceKind::Synthesized)); + } + } // All other builtin types are Sendable, SendableMetatype, Copyable, and // Escapable. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 6495cd035fa..f88f97516d0 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -272,6 +272,7 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig, case TypeKind::Integer: case TypeKind::BuiltinUnboundGeneric: case TypeKind::BuiltinFixedArray: + case TypeKind::BuiltinBorrow: #define REF_STORAGE(Name, ...) \ case TypeKind::Name##Storage: #include "swift/AST/ReferenceStorage.def" @@ -4670,6 +4671,7 @@ ReferenceCounting TypeBase::getReferenceCounting() { case TypeKind::Integer: case TypeKind::BuiltinUnboundGeneric: case TypeKind::BuiltinFixedArray: + case TypeKind::BuiltinBorrow: #define REF_STORAGE(Name, ...) \ case TypeKind::Name##Storage: #include "swift/AST/ReferenceStorage.def" diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index d4054fa0efe..1840e81a790 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -14,7 +14,6 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/Compiler.h" #include "swift/Demangling/Demangler.h" #include "DemanglerAssert.h" #include "swift/Demangling/ManglingMacros.h" @@ -1510,6 +1509,14 @@ NodePointer Demangler::demangleBuiltinType() { Ty->addChild(element, *this); break; } + case 'W': { + NodePointer referent = popNode(Node::Kind::Type); + if (!referent) + return nullptr; + Ty = createNode(Node::Kind::BuiltinBorrow); + Ty->addChild(referent, *this); + break; + } case 'O': Ty = createNode(Node::Kind::BuiltinTypeName, BUILTIN_TYPE_NAME_UNKNOWNOBJECT); diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 30aeb3eb95b..df0b10921fe 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -252,6 +252,7 @@ bool NodePrinter::isSimpleType(NodePointer Node) { case Node::Kind::BuiltinTypeName: case Node::Kind::BuiltinTupleType: case Node::Kind::BuiltinFixedArray: + case Node::Kind::BuiltinBorrow: case Node::Kind::Class: case Node::Kind::DependentGenericType: case Node::Kind::DependentMemberType: @@ -2021,6 +2022,11 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, print(Node->getChild(1), depth + 1); Printer << ">"; return nullptr; + case Node::Kind::BuiltinBorrow: + Printer << "Builtin.Borrow<"; + print(Node->getChild(0), depth + 1); + Printer << ">"; + return nullptr; case Node::Kind::Number: Printer << Node->getIndex(); return nullptr; diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index 6b98bf81aa5..d87d4028a2a 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -1567,6 +1567,10 @@ ManglingError Remangler::mangleBuiltinFixedArray(Node *node, unsigned depth) { return MANGLING_ERROR(ManglingError::UnexpectedBuiltinType, node); } +ManglingError Remangler::mangleBuiltinBorrow(Node *node, unsigned depth) { + return MANGLING_ERROR(ManglingError::UnexpectedBuiltinType, node); +} + ManglingError Remangler::mangleBuiltinTypeName(Node *node, unsigned depth) { Buffer << 'B'; StringRef text = node->getText(); diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index efd7d02d6e3..d184f00e454 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -22,7 +22,6 @@ #include "swift/Demangling/Demangler.h" #include "swift/Demangling/ManglingMacros.h" #include "swift/Demangling/ManglingUtils.h" -#include "swift/Demangling/Punycode.h" #include "swift/Strings.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" @@ -906,6 +905,12 @@ ManglingError Remangler::mangleBuiltinFixedArray(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError Remangler::mangleBuiltinBorrow(Node *node, unsigned depth) { + RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); + Buffer << "BW"; + return ManglingError::Success; +} + ManglingError Remangler::mangleBuiltinTypeName(Node *node, unsigned depth) { Buffer << 'B'; StringRef text = node->getText(); diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 262b9d370ed..c843b17d29d 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2322,6 +2322,11 @@ const TypeInfo *TypeConverter::convertType(CanType ty) { return convertBuiltinFixedArrayType(cast(ty)); } + case TypeKind::BuiltinBorrow: { + llvm_unreachable("todo"); + //return convertBuiltinBorrowType(cast(ty)); + } + case TypeKind::PrimaryArchetype: case TypeKind::ExistentialArchetype: case TypeKind::OpaqueTypeArchetype: diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 46cec932e02..5a83acf884d 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1923,6 +1923,10 @@ private: case TypeKind::BuiltinUnboundGeneric: llvm_unreachable("not a real type"); + case TypeKind::BuiltinBorrow: { + llvm_unreachable("todo"); + + } case TypeKind::BuiltinFixedArray: { if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) { auto *FixedArray = llvm::cast(BaseTy); diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 7a438ddd5d0..d6c4edb122d 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -1871,6 +1871,12 @@ namespace { llvm_unreachable("not a real type"); } + MetadataResponse + visitBuiltinBorrowType(CanBuiltinBorrowType type, + DynamicMetadataRequest request) { + llvm_unreachable("todo"); + } + MetadataResponse visitBuiltinFixedArrayType(CanBuiltinFixedArrayType type, DynamicMetadataRequest request) { diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 722d0551d83..af09c685288 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -416,6 +416,12 @@ namespace { getBuiltinFixedArrayProperties(type, origType, isSensitive)); } + RetTy visitBuiltinBorrowType(CanBuiltinBorrowType type, + AbstractionPattern origType, + IsTypeExpansionSensitive_t isSensitive) { + llvm_unreachable("todo"); + } + RetTy visitPackType(CanPackType type, AbstractionPattern origType, IsTypeExpansionSensitive_t isSensitive) { @@ -2476,6 +2482,12 @@ namespace { getBuiltinFixedArrayProperties(faType, origType, isSensitive)); } + TypeLowering *visitBuiltinBorrowType(CanBuiltinBorrowType faType, + AbstractionPattern origType, + IsTypeExpansionSensitive_t isSensitive) { + llvm_unreachable("todo"); + } + bool handleResilience(CanType type, NominalTypeDecl *D, SILTypeProperties &properties) { if (D->isResilient()) { diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index bde6e3bc4fb..3c6c61dfc99 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -7488,6 +7488,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, return getTypeMatchFailure(locator); // BuiltinGenericType subclasses + case TypeKind::BuiltinBorrow: case TypeKind::BuiltinFixedArray: { auto *fixed1 = cast(desugar1); auto *fixed2 = cast(desugar2); diff --git a/lib/Serialization/DeclTypeRecordNodes.def b/lib/Serialization/DeclTypeRecordNodes.def index d1462d53cd7..b8f3f737708 100644 --- a/lib/Serialization/DeclTypeRecordNodes.def +++ b/lib/Serialization/DeclTypeRecordNodes.def @@ -123,6 +123,7 @@ TYPE(ERROR) TYPE(INTEGER) TYPE(BUILTIN_FIXED_ARRAY) +TYPE(BUILTIN_BORROW) FIRST_DECL(TYPE_ALIAS, 50) DECL(GENERIC_TYPE_PARAM) diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index fd35d0990a1..aad4055843a 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -740,7 +740,7 @@ SILLayout *ModuleFile::readSILLayout(llvm::BitstreamCursor &Cursor) { decls_block::SILLayoutLayout::readRecord(scratch, rawGenericSig, capturesGenerics, numFields, types); - + SmallVector fields; for (auto fieldInfo : types.slice(0, numFields)) { bool isMutable = fieldInfo & 0x80000000U; @@ -749,7 +749,7 @@ SILLayout *ModuleFile::readSILLayout(llvm::BitstreamCursor &Cursor) { SILField(getType(typeId)->getCanonicalType(), isMutable)); } - + CanGenericSignature canSig; if (auto sig = getGenericSignature(rawGenericSig)) canSig = sig.getCanonicalSignature(); @@ -2251,15 +2251,15 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) { } break; } - + case XREF_OPAQUE_RETURN_TYPE_PATH_PIECE: { IdentifierID DefiningDeclNameID; - + XRefOpaqueReturnTypePathPieceLayout::readRecord(scratch, DefiningDeclNameID); - + auto name = getIdentifier(DefiningDeclNameID); pathTrace.addOpaqueReturnType(name); - + if (auto opaque = baseModule->lookupOpaqueResultType(name.str())) { values.push_back(opaque); } @@ -2351,7 +2351,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) { IdentifierID IID; XRefOpaqueReturnTypePathPieceLayout::readRecord(scratch, IID); auto mangledName = getIdentifier(IID); - + SmallString<64> buf; { llvm::raw_svector_ostream os(buf); @@ -2359,7 +2359,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) { os << mangledName.str(); os << ">>"; } - + result = getContext().getIdentifier(buf); break; } @@ -2615,7 +2615,7 @@ giveUpFastPath: ctorInit = getActualCtorInitializerKind(kind); break; } - + default: fatal(llvm::make_error(recordID, "Unhandled path piece")); @@ -2831,16 +2831,16 @@ giveUpFastPath: break; } - + case XREF_OPAQUE_RETURN_TYPE_PATH_PIECE: { values.clear(); IdentifierID DefiningDeclNameID; - + XRefOpaqueReturnTypePathPieceLayout::readRecord(scratch, DefiningDeclNameID); - + auto name = getIdentifier(DefiningDeclNameID); pathTrace.addOpaqueReturnType(name); - + auto lookupModule = M ? M : baseModule; if (auto opaqueTy = lookupModule->lookupOpaqueResultType(name.str())) { values.push_back(opaqueTy); @@ -4908,7 +4908,7 @@ public: ctx.evaluator.cacheOutput( OperatorPrecedenceGroupRequest{result}, std::move(cast_or_null(precedenceGroup.get()))); - + declOrOffset = result; return result; } @@ -5123,7 +5123,7 @@ public: if (isObjC) { theEnum->setHasFixedRawValues(); } - + if (isImplicit) theEnum->setImplicit(); theEnum->setIsObjC(isObjC); @@ -5314,7 +5314,7 @@ public: SET_OR_RETURN_ERROR(genericParams, MF.maybeReadGenericParams(parent)); if (declOrOffset.isComplete()) return declOrOffset; - + auto staticSpelling = getActualStaticSpellingKind(rawStaticSpelling); if (!staticSpelling.has_value()) return MF.diagnoseFatal(); @@ -6655,7 +6655,7 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { serialization::decls_block::RawLayoutDeclAttrLayout:: readRecord(scratch, isImplicit, typeID, countID, rawSize, rawAlign, movesAsLike); - + if (typeID) { auto type = MF.getTypeChecked(typeID); if (!type) { @@ -6681,7 +6681,7 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { break; } } - + Attr = new (ctx) RawLayoutAttr(rawSize, rawAlign, SourceLoc(), SourceRange()); break; @@ -6868,7 +6868,7 @@ DeclDeserializer::getDeclCheckedImpl( declOrOffset = resolved.get(); break; } - + default: // We don't know how to deserialize this kind of decl. MF.fatal(llvm::make_error(recordID)); @@ -7021,7 +7021,7 @@ getActualSILParameterOptions(uint8_t raw) { options -= serialization::SILParameterInfoFlags::ImplicitLeading; result |= SILParameterInfo::ImplicitLeading; } - + if (options.contains(serialization::SILParameterInfoFlags::Const)) { options -= serialization::SILParameterInfoFlags::Const; result |= SILParameterInfo::Const; @@ -7143,23 +7143,37 @@ DESERIALIZE_TYPE(BUILTIN_FIXED_ARRAY_TYPE)( TypeID elementTypeID; decls_block::BuiltinFixedArrayTypeLayout::readRecord(scratch, sizeID, elementTypeID); - - + auto sizeOrError = MF.getTypeChecked(sizeID); if (!sizeOrError) { return sizeOrError.takeError(); } auto size = sizeOrError.get()->getCanonicalType(); - + auto elementTypeOrError = MF.getTypeChecked(elementTypeID); if (!elementTypeOrError) { return elementTypeOrError.takeError(); } auto elementType = elementTypeOrError.get()->getCanonicalType(); - + return BuiltinFixedArrayType::get(size, elementType); } +Expected +DESERIALIZE_TYPE(BUILTIN_BORROW_TYPE)( + ModuleFile &MF, SmallVectorImpl &scratch, StringRef blobData) +{ + TypeID referentID; + decls_block::BuiltinBorrowTypeLayout::readRecord(scratch, referentID); + + auto referentOrError = MF.getTypeChecked(referentID); + if (!referentOrError) { + return referentOrError.takeError(); + } + auto referent = referentOrError.get()->getCanonicalType(); + + return BuiltinBorrowType::get(referent); +} Expected DESERIALIZE_TYPE(NAME_ALIAS_TYPE)( ModuleFile &MF, SmallVectorImpl &scratch, StringRef blobData) { @@ -8304,7 +8318,7 @@ Expected DESERIALIZE_TYPE(INTEGER_TYPE)(ModuleFile &MF, StringRef blobData) { auto &ctx = MF.getContext(); bool isNegative; - + decls_block::IntegerTypeLayout::readRecord(scratch, isNegative); return IntegerType::get(blobData, isNegative, ctx); @@ -9197,12 +9211,12 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance, bool needToFillInOpaqueValueWitnesses = false; while (valueCount--) { ValueDecl *req; - + auto trySetWitness = [&](Witness w) { if (req) conformance->setWitness(req, w); }; - + auto deserializedReq = getDeclChecked(*rawIDIter++); if (deserializedReq) { req = cast_or_null(*deserializedReq); @@ -9213,7 +9227,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance, } else { fatal(deserializedReq.takeError()); } - + bool isOpaque = false; ValueDecl *witness; auto deserializedWitness = getDeclChecked(*rawIDIter++); @@ -9279,7 +9293,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance, witness, witnessSubstitutions.get(), enterIsolation)); } assert(rawIDIter <= rawIDs.end() && "read too much"); - + // Fill in opaque value witnesses if we need to. if (needToFillInOpaqueValueWitnesses) { for (auto member : proto->getMembers()) { @@ -9288,7 +9302,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance, if (!valueMember || !valueMember->isProtocolRequirement() || isa(valueMember)) continue; - + if (!conformance->hasWitness(valueMember)) conformance->setWitness(valueMember, Witness::forOpaque(valueMember)); } diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 4931739678b..19943d8fea5 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 = 981; // require complete lifetimes +const uint16_t SWIFTMODULE_VERSION_MINOR = 982; // `Builtin.Borrow` /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1311,6 +1311,11 @@ namespace decls_block { TypeIDField // element type ); + TYPE_LAYOUT(BuiltinBorrowTypeLayout, + BUILTIN_BORROW_TYPE, + TypeIDField // referent type + ); + TYPE_LAYOUT(TypeAliasTypeLayout, NAME_ALIAS_TYPE, DeclIDField, // typealias decl diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 71bf2ec52a4..e2fbe5af49a 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -5754,6 +5754,14 @@ public: S.addTypeRef(ty->getElementType())); } + void visitBuiltinBorrowType(BuiltinBorrowType *ty) { + using namespace decls_block; + unsigned abbrCode = S.DeclTypeAbbrCodes[BuiltinBorrowTypeLayout::Code]; + BuiltinBorrowTypeLayout::emitRecord( + S.Out, S.ScratchRecord, abbrCode, + S.addTypeRef(ty->getReferentType())); + } + void visitSILTokenType(SILTokenType *ty) { // This is serialized like a BuiltinType, even though it isn't one. visitBuiltinTypeImpl(ty); @@ -6464,6 +6472,7 @@ void Serializer::writeAllDeclsAndTypes() { using namespace decls_block; registerDeclTypeAbbr(); registerDeclTypeAbbr(); + registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); diff --git a/stdlib/public/RemoteInspection/TypeLowering.cpp b/stdlib/public/RemoteInspection/TypeLowering.cpp index 60958b6c925..e0f4ba9b189 100644 --- a/stdlib/public/RemoteInspection/TypeLowering.cpp +++ b/stdlib/public/RemoteInspection/TypeLowering.cpp @@ -18,6 +18,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/ErrorHandling.h" #if SWIFT_ENABLE_REFLECTION #include "llvm/Support/MathExtras.h" @@ -224,6 +225,13 @@ public: stream << ")"; return; } + + case TypeInfoKind::Borrow: { + printHeader("borrow"); + printBasic(TI); + stream << ")"; + return; + } } swift_unreachable("Bad TypeInfo kind"); @@ -1861,6 +1869,10 @@ public: bool visitBuiltinFixedArrayTypeRef(const BuiltinFixedArrayTypeRef *BA) { return visit(BA->getElementType()); } + + bool visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + return visit(BA->getReferentType()); + } }; bool TypeConverter::hasFixedSize(const TypeRef *TR) { @@ -2021,7 +2033,11 @@ public: } MetatypeRepresentation visitBuiltinFixedArrayTypeRef(const BuiltinFixedArrayTypeRef *BA) { - return visit(BA->getElementType()); + return MetatypeRepresentation::Thin; + } + + MetatypeRepresentation visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + return MetatypeRepresentation::Thin; } }; @@ -2689,6 +2705,12 @@ public: return TC.makeTypeInfo(size, elementTI); } + + const TypeInfo *visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + llvm_unreachable("not implemented"); + // auto referentTI = visit(BA->getReferentType()); + // return TC.makeTypeInfo(referentTI); + } }; const TypeInfo * diff --git a/stdlib/public/RemoteInspection/TypeRef.cpp b/stdlib/public/RemoteInspection/TypeRef.cpp index 0c97ccb7701..4f0bfedd9a3 100644 --- a/stdlib/public/RemoteInspection/TypeRef.cpp +++ b/stdlib/public/RemoteInspection/TypeRef.cpp @@ -451,6 +451,12 @@ public: printRec(BA->getElementType()); stream << ")"; } + + void visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + printHeader("builtin_borrow"); + printRec(BA->getReferentType()); + stream << ")"; + } }; struct TypeRefIsConcrete @@ -598,6 +604,10 @@ struct TypeRefIsConcrete bool visitBuiltinFixedArrayTypeRef(const BuiltinFixedArrayTypeRef *BA) { return visit(BA->getElementType()); } + + bool visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + return visit(BA->getReferentType()); + } }; const OpaqueTypeRef * @@ -1196,6 +1206,13 @@ public: ba->addChild(visit(BA->getSizeType()), Dem); ba->addChild(visit(BA->getElementType()), Dem); + return ba; + } + Demangle::NodePointer visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + auto ba = Dem.createNode(Node::Kind::BuiltinBorrow); + + ba->addChild(visit(BA->getReferentType()), Dem); + return ba; } }; @@ -1452,6 +1469,10 @@ public: return BuiltinFixedArrayTypeRef::create(Builder, visit(BA->getSizeType()), visit(BA->getElementType())); } + + const TypeRef *visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + return BuiltinBorrowTypeRef::create(Builder, visit(BA->getReferentType())); + } }; static const TypeRef * @@ -1835,6 +1856,10 @@ public: return BuiltinFixedArrayTypeRef::create(Builder, visit(BA->getSizeType()), visit(BA->getElementType())); } + + const TypeRef *visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) { + return BuiltinBorrowTypeRef::create(Builder, visit(BA->getReferentType())); + } }; const TypeRef *TypeRef::subst(TypeRefBuilder &Builder, diff --git a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp index 6f76a5c14c8..94e4213c951 100644 --- a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp +++ b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp @@ -561,6 +561,10 @@ swift_layout_kind_t getTypeInfoKind(const TypeInfo &TI) { case TypeInfoKind::Array: { return SWIFT_ARRAY; } + + case TypeInfoKind::Borrow: { + swift_unreachable("not implemented"); + } } swift_unreachable("Unhandled TypeInfoKind in switch"); diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index 04d2edb5459..da3dba2bbc4 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -2480,6 +2480,12 @@ public: size.getValue(), element.getMetadata())); } + + TypeLookupErrorOr createBuiltinBorrowType(BuiltType referent) { + llvm_unreachable("not implemented"); + // return BuiltType(swift_getBorrowTypeMetadata(MetadataState::Abstract, + // referent.getValue()); + } }; } diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt index 46c631528d3..df3a52c408d 100644 --- a/test/Demangle/Inputs/manglings.txt +++ b/test/Demangle/Inputs/manglings.txt @@ -508,3 +508,4 @@ $s3use1xAA3OfPVy3lib1GVyAA1fQryFQOyQo_GAjE1PAAxAeKHD1_AIHO_HCg_Gvp ---> use.x : $sBAIgHgIL_BAIegHgIL_TR ---> {T:} reabstraction thunk helper from @callee_guaranteed @async (@guaranteed Builtin.ImplicitActor) -> () to @escaping @callee_guaranteed @async (@guaranteed Builtin.ImplicitActor) -> () $sBAD ---> Builtin.ImplicitActor $sIeg_BAIegHgIL_TR ---> {T:} reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_guaranteed @async (@guaranteed Builtin.ImplicitActor) -> () +$sSiBW ---> Builtin.Borrow diff --git a/test/Sema/builtin_borrow.swift b/test/Sema/builtin_borrow.swift new file mode 100644 index 00000000000..783ab21d9f0 --- /dev/null +++ b/test/Sema/builtin_borrow.swift @@ -0,0 +1,18 @@ +// RUN: %target-swift-frontend -disable-experimental-parser-round-trip -disable-availability-checking -enable-experimental-feature BuiltinModule -enable-experimental-feature Lifetimes -typecheck -verify %s + +// REQUIRES: swift_feature_BuiltinModule +// REQUIRES: swift_feature_Lifetimes + +import Builtin + +@_lifetime(copy x) +func a(x: Builtin.Borrow) -> Builtin.Borrow { + return x +} + +struct EscapableContainingBorrow { // expected-note {{consider adding '~Escapable'}} + var x: Builtin.Borrow // expected-error {{has non-Escapable type}} +} +struct NonescapableContainingBorrow: ~Escapable { + var x: Builtin.Borrow +} diff --git a/test/TypeDecoder/builtins.swift b/test/TypeDecoder/builtins.swift index 9a2ee4cd724..7d0a7729b8e 100644 --- a/test/TypeDecoder/builtins.swift +++ b/test/TypeDecoder/builtins.swift @@ -112,4 +112,7 @@ // CHECK: Vec8xInt8 // CHECK: Vec16xInt8 // CHECK: Vec32xInt8 -// CHECK: Vec64xInt8 \ No newline at end of file +// CHECK: Vec64xInt8 + +// DEMANGLE: $sSiBW +// CHECK: Borrow