Merge pull request #21124 from xedin/rdar-45218255-5.0
[5.0][CSDiagnostics] Diagnose invalid optional unwrap via fixes
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 8eb79d4..3d30e7d 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -936,10 +936,15 @@
# target_sources(${target}
# PRIVATE
# $<TARGET_OBJECTS:swiftImageRegistrationObject${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}-${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE}>)
+ if(SWIFTLIB_SINGLE_SDK STREQUAL WINDOWS)
+ set(extension .obj)
+ else()
+ set(extension .o)
+ endif()
target_sources(${target}
PRIVATE
- "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swiftrt${CMAKE_C_OUTPUT_EXTENSION}")
- set_source_files_properties("${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swiftrt${CMAKE_C_OUTPUT_EXTENSION}"
+ "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swiftrt${extension}")
+ set_source_files_properties("${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swiftrt${extension}"
PROPERTIES
GENERATED 1)
endif()
@@ -2139,11 +2144,20 @@
# Find the names of dependency library targets.
#
# We don't add the ${ARCH} to the target suffix because we want to link
- # against fat libraries.
- _list_add_string_suffix(
- "${SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES}"
- "-${SWIFT_SDK_${SWIFTEXE_SINGLE_SDK}_LIB_SUBDIR}"
- SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES_TARGETS)
+ # against fat libraries. This only works for the Darwin targets as MachO is
+ # the only format with the fat libraries.
+ if(${SWIFTEXE_SINGLE_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
+ _list_add_string_suffix(
+ "${SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES}"
+ "-${SWIFT_SDK_${SWIFTEXE_SINGLE_SDK}_LIB_SUBDIR}"
+ SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES_TARGETS)
+ else()
+ _list_add_string_suffix(
+ "${SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES}"
+ "-${SWIFT_SDK_${SWIFTEXE_SINGLE_SDK}_LIB_SUBDIR}-${SWIFTEXE_SINGLE_ARCHITECTURE}"
+ SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES_TARGETS)
+ set(SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES ${SWIFTEXE_SINGLE_LINK_FAT_LIBRARIES_TARGETS})
+ endif()
handle_swift_sources(
dependency_target
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 42fd189..1f44445 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -146,7 +146,8 @@
global ::= type protocol-conformance 'WL' // lazy protocol witness table cache variable
global ::= protocol-conformance identifier 'Wt' // associated type metadata accessor (HISTORICAL)
- global ::= protocol-conformance assoc-type-list nominal-type 'WT' // associated type witness table accessor
+ global ::= protocol-conformance assoc-type-list protocol 'WT' // associated type witness table accessor
+ global ::= protocol-conformance protocol 'Wb' // base protocol witness table accessor
global ::= type protocol-conformance 'Wl' // lazy protocol witness table accessor
global ::= type 'WV' // value witness table
@@ -200,6 +201,7 @@
global ::= assoc-type-name 'TM' // default associated type witness accessor (HISTORICAL)
global ::= type assoc-type-list protocol 'Tn' // associated conformance descriptor
global ::= type assoc-type-list protocol 'TN' // default associated conformance witness accessor
+ global ::= type protocol 'Tb' // base conformance descriptor
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index cefbf0b..569c1db 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1875,6 +1875,9 @@
"possibly intended match %0 does not "
"%select{inherit from|conform to}2 %1", (Type, Type, bool))
+NOTE(protocol_witness_circularity,none,
+ "candidate references itself", ())
+
NOTE(protocol_conformance_here,none,
"%select{|class }0%1 declares conformance to protocol %2 here",
(bool, DeclName, DeclName))
@@ -1982,8 +1985,8 @@
ERROR(requires_generic_param_made_equal_to_concrete,none,
"same-type requirement makes generic parameter %0 non-generic",
(Type))
-ERROR(recursive_type_reference,none,
- "%0 %1 references itself", (DescriptiveDeclKind, Identifier))
+ERROR(recursive_decl_reference,none,
+ "%0 %1 references itself", (DescriptiveDeclKind, DeclBaseName))
ERROR(recursive_same_type_constraint,none,
"same-type constraint %0 == %1 is recursive", (Type, Type))
ERROR(recursive_superclass_constraint,none,
@@ -4106,27 +4109,33 @@
"a default argument value|" \
"a property initializer in a '@_fixed_layout' type}"
+#define DECL_OR_ACCESSOR "%select{%0|%0 for}"
+
ERROR(local_type_in_inlinable_function,
none, "type %0 cannot be nested inside " FRAGILE_FUNC_KIND "1",
(DeclName, unsigned))
ERROR(resilience_decl_unavailable,
- none, "%0 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
+ none, DECL_OR_ACCESSOR "4 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
"cannot be referenced from " FRAGILE_FUNC_KIND "3",
- (DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
+ (DescriptiveDeclKind, DeclName, AccessLevel, unsigned, bool))
WARNING(resilience_decl_unavailable_warn,
- none, "%0 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
+ none, DECL_OR_ACCESSOR "4 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
"should not be referenced from " FRAGILE_FUNC_KIND "3",
- (DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
+ (DescriptiveDeclKind, DeclName, AccessLevel, unsigned, bool))
#undef FRAGILE_FUNC_KIND
NOTE(resilience_decl_declared_here_public,
- none, "%0 %1 is not public", (DescriptiveDeclKind, DeclName))
+ none, DECL_OR_ACCESSOR "2 %1 is not public",
+ (DescriptiveDeclKind, DeclName, bool))
NOTE(resilience_decl_declared_here,
- none, "%0 %1 is not '@usableFromInline' or public", (DescriptiveDeclKind, DeclName))
+ none, DECL_OR_ACCESSOR "2 %1 is not '@usableFromInline' or public",
+ (DescriptiveDeclKind, DeclName, bool))
+
+#undef DECL_OR_ACCESSOR
ERROR(class_designated_init_inlinable_resilient,none,
"initializer for class %0 is "
diff --git a/include/swift/AST/ProtocolAssociations.h b/include/swift/AST/ProtocolAssociations.h
index e28202b..968dcb1 100644
--- a/include/swift/AST/ProtocolAssociations.h
+++ b/include/swift/AST/ProtocolAssociations.h
@@ -68,6 +68,27 @@
}
};
+/// A base conformance of a protocol.
+class BaseConformance {
+ ProtocolDecl *Source;
+ ProtocolDecl *Requirement;
+
+public:
+ explicit BaseConformance(ProtocolDecl *source,
+ ProtocolDecl *requirement)
+ : Source(source), Requirement(requirement) {
+ assert(source && requirement);
+ }
+
+ ProtocolDecl *getSourceProtocol() const {
+ return Source;
+ }
+
+ ProtocolDecl *getBaseRequirement() const {
+ return Requirement;
+ }
+};
+
/// A conformance associated with a protocol.
class AssociatedConformance {
ProtocolDecl *Source;
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index e4b1204..76b0d38 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -33,6 +33,7 @@
NODE(AssociatedTypeMetadataAccessor)
NODE(DefaultAssociatedTypeMetadataAccessor)
NODE(AssociatedTypeWitnessTableAccessor)
+NODE(BaseWitnessTableAccessor)
NODE(AutoClosureType)
NODE(BoundGenericClass)
NODE(BoundGenericEnum)
@@ -226,6 +227,7 @@
NODE(ProtocolRequirementsBaseDescriptor)
NODE(AssociatedConformanceDescriptor)
NODE(DefaultAssociatedConformanceAccessor)
+NODE(BaseConformanceDescriptor)
NODE(AssociatedTypeDescriptor)
NODE(ThrowsAnnotation)
NODE(EmptyList)
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index a8ba2c2..f36f2df 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -230,6 +230,13 @@
/// is stored in the data.
DefaultAssociatedConformanceAccessor,
+ /// An descriptor for an base conformance within a protocol, which
+ /// will alias the TargetProtocolRequirement descripting this
+ /// particular base conformance.
+ /// The pointer is a ProtocolDecl*; the index of the base conformance
+ /// is stored in the data.
+ BaseConformanceDescriptor,
+
/// A global function pointer for dynamically replaceable functions.
/// The pointer is a AbstractStorageDecl*.
DynamicallyReplaceableFunctionVariableAST,
@@ -811,6 +818,18 @@
}
static LinkEntity
+ forBaseConformanceDescriptor(BaseConformance conformance) {
+ LinkEntity entity;
+ entity.setForProtocolAndAssociatedConformance(
+ Kind::BaseConformanceDescriptor,
+ conformance.getSourceProtocol(),
+ conformance.getSourceProtocol()->getSelfInterfaceType()
+ ->getCanonicalType(),
+ conformance.getBaseRequirement());
+ return entity;
+ }
+
+ static LinkEntity
forAssociatedTypeWitnessTableAccessFunction(const ProtocolConformance *C,
const AssociatedConformance &association) {
LinkEntity entity;
@@ -963,7 +982,8 @@
}
assert(getKind() == Kind::AssociatedConformanceDescriptor ||
- getKind() == Kind::DefaultAssociatedConformanceAccessor);
+ getKind() == Kind::DefaultAssociatedConformanceAccessor ||
+ getKind() == Kind::BaseConformanceDescriptor);
return getAssociatedConformanceByIndex(
cast<ProtocolDecl>(getDecl()),
LINKENTITY_GET_FIELD(Data, AssociatedConformanceIndex));
diff --git a/include/swift/Runtime/Casting.h b/include/swift/Runtime/Casting.h
index f634a07..56a00da 100644
--- a/include/swift/Runtime/Casting.h
+++ b/include/swift/Runtime/Casting.h
@@ -62,12 +62,16 @@
/// \param object The object to cast.
/// \param targetType The type to which we are casting, which is known to be
/// a Swift class type.
+/// \param file The source filename from which to report failure. May be null.
+/// \param line The source line from which to report failure.
+/// \param column The source column from which to report failure.
///
/// \returns the object.
SWIFT_RUNTIME_EXPORT
const void *
swift_dynamicCastClassUnconditional(const void *object,
- const ClassMetadata *targetType);
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column);
#if SWIFT_OBJC_INTEROP
/// \brief Checked Objective-C-style dynamic cast to a class type.
@@ -103,25 +107,33 @@
/// \param object The object to cast, or nil.
/// \param targetType The type to which we are casting, which is known to be
/// a class type, but not necessarily valid type metadata.
+/// \param file The source filename from which to report failure. May be null.
+/// \param line The source line from which to report failure.
+/// \param column The source column from which to report failure.
///
/// \returns the object.
SWIFT_RUNTIME_EXPORT
const void *
swift_dynamicCastObjCClassUnconditional(const void *object,
- const ClassMetadata *targetType);
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column);
/// \brief Unconditional, checked dynamic cast to a foreign class type.
///
/// \param object The object to cast, or nil.
/// \param targetType The type to which we are casting, which is known to be
/// a foreign class type.
+/// \param file The source filename from which to report failure. May be null.
+/// \param line The source line from which to report failure.
+/// \param column The source column from which to report failure.
///
/// \returns the object if the cast succeeds, or null otherwise.
SWIFT_RUNTIME_EXPORT
const void *
swift_dynamicCastForeignClassUnconditional(
const void *object,
- const ForeignClassMetadata *targetType);
+ const ForeignClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column);
#endif
/// \brief Checked dynamic cast of a class instance pointer to the given type.
@@ -146,11 +158,16 @@
/// \param targetType The type to which we are casting, which may be either a
/// class type or a wrapped Objective-C class type.
///
+/// \param file The source filename from which to report failure. May be null.
+/// \param line The source line from which to report failure.
+/// \param column The source column from which to report failure.
+///
/// \returns the object.
SWIFT_RUNTIME_EXPORT
const void *
swift_dynamicCastUnknownClassUnconditional(const void *object,
- const Metadata *targetType);
+ const Metadata *targetType,
+ const char *file, unsigned line, unsigned column);
SWIFT_RUNTIME_EXPORT
const Metadata *
@@ -159,7 +176,8 @@
SWIFT_RUNTIME_EXPORT
const Metadata *
swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
- const Metadata *targetType);
+ const Metadata *targetType,
+ const char *file, unsigned line, unsigned column);
#if SWIFT_OBJC_INTEROP
SWIFT_RUNTIME_EXPORT
const ClassMetadata *
@@ -168,7 +186,8 @@
SWIFT_RUNTIME_EXPORT
const ClassMetadata *
swift_dynamicCastObjCClassMetatypeUnconditional(const ClassMetadata *sourceType,
- const ClassMetadata *targetType);
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column);
#endif
SWIFT_RUNTIME_EXPORT
@@ -179,7 +198,8 @@
const ClassMetadata *
swift_dynamicCastForeignClassMetatypeUnconditional(
const ClassMetadata *sourceType,
- const ClassMetadata *targetType);
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column);
/// \brief Return the dynamic type of an opaque value.
///
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 06cf69a..4723fe5 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -942,7 +942,7 @@
FUNCTION(DynamicCastClassUnconditional, swift_dynamicCastClassUnconditional,
C_CC,
RETURNS(Int8PtrTy),
- ARGS(Int8PtrTy, Int8PtrTy),
+ ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind, ReadOnly))
// void *swift_dynamicCastObjCClass(void*, void*);
@@ -955,7 +955,7 @@
FUNCTION(DynamicCastObjCClassUnconditional,
swift_dynamicCastObjCClassUnconditional, C_CC,
RETURNS(Int8PtrTy),
- ARGS(Int8PtrTy, Int8PtrTy),
+ ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind, ReadOnly))
// void *swift_dynamicCastUnknownClass(void*, void*);
@@ -968,7 +968,7 @@
FUNCTION(DynamicCastUnknownClassUnconditional,
swift_dynamicCastUnknownClassUnconditional, C_CC,
RETURNS(Int8PtrTy),
- ARGS(Int8PtrTy, Int8PtrTy),
+ ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind, ReadOnly))
// type *swift_dynamicCastMetatype(type*, type*);
@@ -981,7 +981,7 @@
FUNCTION(DynamicCastMetatypeUnconditional,
swift_dynamicCastMetatypeUnconditional, C_CC,
RETURNS(TypeMetadataPtrTy),
- ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy),
+ ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind, ReadOnly))
// objc_class *swift_dynamicCastObjCClassMetatype(objc_class*, objc_class*);
@@ -995,7 +995,7 @@
FUNCTION(DynamicCastObjCClassMetatypeUnconditional,
swift_dynamicCastObjCClassMetatypeUnconditional, C_CC,
RETURNS(ObjCClassPtrTy),
- ARGS(ObjCClassPtrTy, ObjCClassPtrTy),
+ ARGS(ObjCClassPtrTy, ObjCClassPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind, ReadOnly))
// bool swift_dynamicCast(opaque*, opaque*, type*, type*, size_t);
@@ -1011,7 +1011,7 @@
FUNCTION(DynamicCastTypeToObjCProtocolUnconditional,
swift_dynamicCastTypeToObjCProtocolUnconditional, C_CC,
RETURNS(TypeMetadataPtrTy),
- ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy),
+ ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind))
// type* swift_dynamicCastTypeToObjCProtocolConditional(type* object,
@@ -1029,7 +1029,7 @@
FUNCTION(DynamicCastObjCProtocolUnconditional,
swift_dynamicCastObjCProtocolUnconditional, C_CC,
RETURNS(ObjCPtrTy),
- ARGS(ObjCPtrTy, SizeTy, Int8PtrPtrTy),
+ ARGS(ObjCPtrTy, SizeTy, Int8PtrPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind))
// id swift_dynamicCastObjCProtocolConditional(id object,
@@ -1045,7 +1045,7 @@
FUNCTION(DynamicCastMetatypeToObjectUnconditional,
swift_dynamicCastMetatypeToObjectUnconditional, C_CC,
RETURNS(ObjCPtrTy),
- ARGS(TypeMetadataPtrTy),
+ ARGS(TypeMetadataPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
ATTRS(NoUnwind, ReadNone))
// id swift_dynamicCastMetatypeToObjectConditional(type *type);
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 52fe902..940d926 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -934,23 +934,27 @@
case TypeKind::SILBox: {
auto box = cast<SILBoxType>(tybase);
auto layout = box->getLayout();
- SmallVector<TupleTypeElt, 4> fieldsList;
+ bool firstField = true;
for (auto &field : layout->getFields()) {
- auto fieldTy = field.getLoweredType();
- // Use the `inout` mangling to represent a mutable field.
- auto fieldFlag = ParameterTypeFlags().withInOut(field.isMutable());
- fieldsList.push_back(TupleTypeElt(fieldTy, Identifier(), fieldFlag));
+ appendType(field.getLoweredType());
+ if (field.isMutable()) {
+ // Use the `inout` mangling to represent a mutable field.
+ appendOperator("z");
+ }
+ appendListSeparator(firstField);
}
- appendTypeList(TupleType::get(fieldsList, tybase->getASTContext())
- ->getCanonicalType());
+ if (firstField)
+ appendOperator("y");
if (auto sig = layout->getGenericSignature()) {
- fieldsList.clear();
+ bool firstType = true;
for (Type type : box->getSubstitutions().getReplacementTypes()) {
- fieldsList.push_back(TupleTypeElt(type));
+ appendType(type);
+ appendListSeparator(firstType);
}
- appendTypeList(TupleType::get(fieldsList, tybase->getASTContext())
- ->getCanonicalType());
+ if (firstType)
+ appendOperator("y");
+
appendGenericSignature(sig);
appendOperator("XX");
} else {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 37ff731..de66c40 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2411,8 +2411,7 @@
return true;
if (auto *containingProto = dyn_cast<ProtocolDecl>(getDeclContext())) {
- if (isProtocolRequirement() &&
- containingProto->getAttrs().hasAttribute<UsableFromInlineAttr>())
+ if (containingProto->getAttrs().hasAttribute<UsableFromInlineAttr>())
return true;
}
diff --git a/lib/Demangling/Context.cpp b/lib/Demangling/Context.cpp
index fe0121a..0336eb1 100644
--- a/lib/Demangling/Context.cpp
+++ b/lib/Demangling/Context.cpp
@@ -162,6 +162,7 @@
case Node::Kind::LazyProtocolWitnessTableAccessor:
case Node::Kind::AssociatedTypeMetadataAccessor:
case Node::Kind::AssociatedTypeWitnessTableAccessor:
+ case Node::Kind::BaseWitnessTableAccessor:
case Node::Kind::ObjCAttribute:
return false;
default:
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index b186b5f..dd9b798 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -2041,10 +2041,10 @@
case 'n': {
NodePointer requirementTy = popProtocol();
- auto assocTypePath = popAssocTypePath();
+ NodePointer conformingType = popAssocTypePath();
NodePointer protoTy = popNode(Node::Kind::Type);
return createWithChildren(Node::Kind::AssociatedConformanceDescriptor,
- protoTy, assocTypePath, requirementTy);
+ protoTy, conformingType, requirementTy);
}
case 'N': {
@@ -2056,6 +2056,13 @@
protoTy, assocTypePath, requirementTy);
}
+ case 'b': {
+ NodePointer requirementTy = popProtocol();
+ NodePointer protoTy = popNode(Node::Kind::Type);
+ return createWithChildren(Node::Kind::BaseConformanceDescriptor,
+ protoTy, requirementTy);
+ }
+
case 'H':
case 'h': {
auto nodeKind = c == 'H' ? Node::Kind::KeyPathEqualsThunkHelper
@@ -2423,11 +2430,16 @@
}
case 'T': {
NodePointer ProtoTy = popNode(Node::Kind::Type);
- auto AssocTypePath = popAssocTypePath();
-
+ NodePointer ConformingType = popAssocTypePath();
NodePointer Conf = popProtocolConformance();
return createWithChildren(Node::Kind::AssociatedTypeWitnessTableAccessor,
- Conf, AssocTypePath, ProtoTy);
+ Conf, ConformingType, ProtoTy);
+ }
+ case 'b': {
+ NodePointer ProtoTy = popNode(Node::Kind::Type);
+ NodePointer Conf = popProtocolConformance();
+ return createWithChildren(Node::Kind::BaseWitnessTableAccessor,
+ Conf, ProtoTy);
}
case 'O': {
switch (nextChar()) {
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index ac3d133..611609b 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -319,6 +319,8 @@
case Node::Kind::AssociatedTypeMetadataAccessor:
case Node::Kind::AssociatedTypeWitnessTableAccessor:
case Node::Kind::AutoClosureType:
+ case Node::Kind::BaseConformanceDescriptor:
+ case Node::Kind::BaseWitnessTableAccessor:
case Node::Kind::ClassMetadataBaseOffset:
case Node::Kind::CFunctionPointer:
case Node::Kind::Constructor:
@@ -1637,6 +1639,12 @@
Printer << " in ";
print(Node->getChild(0));
return nullptr;
+ case Node::Kind::BaseConformanceDescriptor:
+ Printer << "base conformance descriptor for ";
+ print(Node->getChild(0));
+ Printer << ": ";
+ print(Node->getChild(1));
+ return nullptr;
case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
Printer << "default associated type metadata accessor for ";
print(Node->getChild(0));
@@ -1649,6 +1657,12 @@
Printer << " in ";
print(Node->getChild(0));
return nullptr;
+ case Node::Kind::BaseWitnessTableAccessor:
+ Printer << "base witness table accessor for ";
+ print(Node->getChild(1));
+ Printer << " in ";
+ print(Node->getChild(0));
+ return nullptr;
case Node::Kind::ClassMetadataBaseOffset:
Printer << "class metadata base offset for ";
print(Node->getChild(0));
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index 7a1b115..8caafc6 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -942,6 +942,10 @@
Out << "<default-associated-conformance-descriptor>";
}
+void Remangler::mangleBaseConformanceDescriptor(Node *node) {
+ Out << "<base-conformance-descriptor>";
+}
+
void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
Out << "Wt";
mangleChildNodes(node); // protocol conformance, identifier
@@ -955,10 +959,14 @@
Out << "WT";
assert(node->getNumChildren() == 3);
mangleChildNode(node, 0); // protocol conformance
- mangleChildNode(node, 1); // identifier
+ mangleChildNode(node, 1); // type
mangleProtocolWithoutPrefix(node->begin()[2]); // type
}
+void Remangler::mangleBaseWitnessTableAccessor(Node *node) {
+ Out << "<base-witness-table-accessor>";
+}
+
void Remangler::mangleReabstractionThunkHelper(Node *node) {
Out << "TR";
if (node->getNumChildren() == 3) Out << 'G';
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index ada1dfc..5f6afbb 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -585,6 +585,11 @@
Buffer << "TN";
}
+void Remangler::mangleBaseConformanceDescriptor(Node *node) {
+ mangleChildNodes(node);
+ Buffer << "Tb";
+}
+
void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
mangleChildNodes(node); // protocol conformance, identifier
Buffer << "Wt";
@@ -596,10 +601,15 @@
}
void Remangler::mangleAssociatedTypeWitnessTableAccessor(Node *node) {
- mangleChildNodes(node); // protocol conformance, identifier, type
+ mangleChildNodes(node); // protocol conformance, type, protocol
Buffer << "WT";
}
+void Remangler::mangleBaseWitnessTableAccessor(Node *node) {
+ mangleChildNodes(node); // protocol conformance, protocol
+ Buffer << "Wb";
+}
+
void Remangler::mangleAutoClosureType(Node *node) {
mangleChildNodesReversed(node); // argument tuple, result type
Buffer << "XK";
diff --git a/lib/IRGen/GenCast.cpp b/lib/IRGen/GenCast.cpp
index a49c598..7a4185c 100644
--- a/lib/IRGen/GenCast.cpp
+++ b/lib/IRGen/GenCast.cpp
@@ -133,6 +133,34 @@
return {cond, from};
}
+/// Returns an ArrayRef with the set of arguments to pass to a dynamic cast call.
+///
+/// `argsBuf` should be passed in as a reference to an array with three nullptr
+/// values at the end. These will be dropped from the return ArrayRef for a
+/// conditional cast, or filled in with source location arguments for an
+/// unconditional cast.
+template<unsigned n>
+static ArrayRef<llvm::Value*>
+getDynamicCastArguments(IRGenFunction &IGF,
+ llvm::Value *(&argsBuf)[n], CheckedCastMode mode
+ /*TODO , SILLocation location*/)
+{
+ switch (mode) {
+ case CheckedCastMode::Unconditional:
+ // TODO: Pass along location info if available for unconditional casts, so
+ // that the runtime error for a failed cast can report the source of the
+ // error from user code.
+ argsBuf[n-3] = llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
+ argsBuf[n-2] = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0);
+ argsBuf[n-1] = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0);
+ return argsBuf;
+
+ case CheckedCastMode::Conditional:
+ return llvm::makeArrayRef(argsBuf, n-3);
+ break;
+ }
+}
+
/// Emit a checked unconditional downcast of a class value.
llvm::Value *irgen::emitClassDowncast(IRGenFunction &IGF, llvm::Value *from,
SILType toType, CheckedCastMode mode) {
@@ -206,9 +234,17 @@
if (auto fun = dyn_cast<llvm::Function>(castFn))
cc = fun->getCallingConv();
+ llvm::Value *argsBuf[] = {
+ from,
+ metadataRef,
+ nullptr,
+ nullptr,
+ nullptr,
+ };
+
auto call
- = IGF.Builder.CreateCall(castFn, {from, metadataRef});
- // FIXME: Eventually, we may want to throw.
+ = IGF.Builder.CreateCall(castFn,
+ getDynamicCastArguments(IGF, argsBuf, mode));
call->setCallingConv(cc);
call->setDoesNotThrow();
@@ -267,8 +303,17 @@
auto cc = IGF.IGM.DefaultCC;
if (auto fun = dyn_cast<llvm::Function>(castFn))
cc = fun->getCallingConv();
+
+ llvm::Value *argsBuf[] = {
+ metatype,
+ toMetadata,
+ nullptr,
+ nullptr,
+ nullptr,
+ };
- auto call = IGF.Builder.CreateCall(castFn, {metatype, toMetadata});
+ auto call = IGF.Builder.CreateCall(castFn,
+ getDynamicCastArguments(IGF, argsBuf, mode));
call->setCallingConv(cc);
call->setDoesNotThrow();
ex.add(call);
@@ -486,8 +531,16 @@
auto cc = IGF.IGM.DefaultCC;
if (auto fun = dyn_cast<llvm::Function>(castFn))
cc = fun->getCallingConv();
+
+ llvm::Value *argsBuf[] = {
+ metatypeValue,
+ nullptr,
+ nullptr,
+ nullptr,
+ };
- auto call = IGF.Builder.CreateCall(castFn, metatypeValue);
+ auto call = IGF.Builder.CreateCall(castFn,
+ getDynamicCastArguments(IGF, argsBuf, mode));
call->setCallingConv(cc);
return call;
}
@@ -672,11 +725,18 @@
if (auto fun = dyn_cast<llvm::Function>(castFn))
cc = fun->getCallingConv();
+ llvm::Value *argsBuf[] = {
+ objcCastObject,
+ IGF.IGM.getSize(Size(objcProtos.size())),
+ protoRefsBuf.getAddress(),
+ nullptr,
+ nullptr,
+ nullptr,
+ };
auto call = IGF.Builder.CreateCall(
- castFn,
- {objcCastObject, IGF.IGM.getSize(Size(objcProtos.size())),
- protoRefsBuf.getAddress()});
+ castFn,
+ getDynamicCastArguments(IGF, argsBuf, mode));
call->setCallingConv(cc);
objcCast = call;
resultValue = IGF.Builder.CreateBitCast(objcCast, resultType);
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index bbe3437..73507bd 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3530,6 +3530,19 @@
return defineAlias(entity, definition);
}
+llvm::Constant *IRGenModule::getAddrOfBaseConformanceDescriptor(
+ BaseConformance conformance) {
+ auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
+ return getAddrOfLLVMVariable(entity, ConstantInit(), DebugTypeInfo());
+}
+
+llvm::GlobalValue *IRGenModule::defineBaseConformanceDescriptor(
+ BaseConformance conformance,
+ llvm::Constant *definition) {
+ auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
+ return defineAlias(entity, definition);
+}
+
llvm::Constant *IRGenModule::getAddrOfProtocolConformanceDescriptor(
const RootProtocolConformance *conformance,
ConstantInit definition) {
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 4e6e65a..08d9344 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -729,6 +729,15 @@
B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
}
+ if (entry.isBase()) {
+ // Define a base conformance descriptor, which is just an associated
+ // conformance descriptor for a base protocol.
+ BaseConformance conformance(Proto, entry.getBase());
+ IGM.defineBaseConformanceDescriptor(
+ conformance,
+ B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
+ }
+
auto reqt = B.beginStruct(IGM.ProtocolRequirementStructTy);
auto info = getRequirementInfo(entry);
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index d951a6e..df1642e 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -995,14 +995,9 @@
return false;
}
-static bool hasDependentTypeWitness(const RootProtocolConformance *root) {
- if (auto normal = dyn_cast<NormalProtocolConformance>(root))
- return hasDependentTypeWitness(normal);
- return false; // no associated types
-}
-
static bool isDependentConformance(
const RootProtocolConformance *rootConformance,
+ bool considerResilience,
llvm::SmallPtrSet<const NormalProtocolConformance *, 4> &visited){
// Self-conformances are never dependent.
auto conformance = dyn_cast<NormalProtocolConformance>(rootConformance);
@@ -1015,7 +1010,7 @@
return false;
// If the conformance is resilient, this is always true.
- if (isResilientConformance(conformance))
+ if (considerResilience && isResilientConformance(conformance))
return true;
// Check whether any of the conformances are dependent.
@@ -1033,6 +1028,7 @@
if (assocConformance.isAbstract() ||
isDependentConformance(assocConformance.getConcrete()
->getRootConformance(),
+ considerResilience,
visited))
return true;
}
@@ -1048,9 +1044,10 @@
/// Is there anything about the given conformance that requires witness
/// tables to be dependently-generated?
-static bool isDependentConformance(const RootProtocolConformance *conformance) {
+static bool isDependentConformance(const RootProtocolConformance *conformance,
+ bool considerResilience) {
llvm::SmallPtrSet<const NormalProtocolConformance *, 4> visited;
- return ::isDependentConformance(conformance, visited);
+ return ::isDependentConformance(conformance, considerResilience, visited);
}
static bool isSynthesizedNonUnique(const RootProtocolConformance *conformance) {
@@ -1323,17 +1320,23 @@
void addOutOfLineBaseProtocol(ProtocolDecl *baseProto) {
#ifndef NDEBUG
auto &entry = SILEntries.front();
+#endif
+ SILEntries = SILEntries.slice(1);
+
+ // Resilient conformances get a resilient witness table.
+ if (ResilientConformance)
+ return;
+
+#ifndef NDEBUG
assert(entry.getKind() == SILWitnessTable::BaseProtocol
&& "sil witness table does not match protocol");
assert(entry.getBaseProtocolWitness().Requirement == baseProto
&& "sil witness table does not match protocol");
auto piIndex = PI.getBaseIndex(baseProto);
assert((size_t)piIndex.getValue() ==
- Table.size() - WitnessTableFirstRequirementOffset &&
+ Table.size() - WitnessTableFirstRequirementOffset &&
"offset doesn't match ProtocolInfo layout");
#endif
-
- SILEntries = SILEntries.slice(1);
// TODO: Use the witness entry instead of falling through here.
@@ -1473,6 +1476,7 @@
private:
void addConditionalConformances() {
+ assert(NextPrivateDataIndex == 0);
for (auto conditional : SILConditionalConformances) {
// We don't actually need to know anything about the specific
// conformances here, just make sure we get right private data slots.
@@ -1755,6 +1759,22 @@
continue;
}
+ // Inherited conformance witnesses.
+ if (entry.getKind() == SILWitnessTable::BaseProtocol) {
+ const auto &witness = entry.getBaseProtocolWitness();
+ auto baseProto = witness.Requirement;
+ auto proto = SILWT->getProtocol();
+ CanType selfType = proto->getProtocolSelfType()->getCanonicalType();
+ AssociatedConformance requirement(proto, selfType, baseProto);
+ ProtocolConformanceRef inheritedConformance =
+ ConformanceInContext.getAssociatedConformance(selfType, baseProto);
+ llvm::Constant *witnessEntry =
+ getAssociatedConformanceWitness(requirement, ConcreteType,
+ inheritedConformance);
+ resilientWitnesses.push_back(witnessEntry);
+ continue;
+ }
+
if (entry.getKind() != SILWitnessTable::Method)
continue;
@@ -1772,10 +1792,9 @@
}
llvm::Constant *WitnessTableBuilder::buildInstantiationFunction() {
- // We need an instantiation function if the base conformance
+ // We need an instantiation function if any base conformance
// is non-dependent.
- if (SpecializedBaseConformances.empty() &&
- ConditionalRequirementPrivateDataIndices.empty())
+ if (SpecializedBaseConformances.empty())
return nullptr;
assert(isa<NormalProtocolConformance>(Conformance) &&
@@ -1803,19 +1822,12 @@
IGF.IGM.WitnessTablePtrPtrTy),
PointerAlignment);
- /// Run through the conditional conformance witness tables, pulling them out
- /// of the slice and putting them into the private data of the witness table.
+ // Register local type data for the conditional conformance witness tables.
for (auto idx : indices(ConditionalRequirementPrivateDataIndices)) {
Address conditionalTablePtr =
IGF.Builder.CreateConstArrayGEP(conditionalTables, idx, PointerSize);
- Address slot = getAddressOfPrivateDataSlot(
- IGF, wtable, ConditionalRequirementPrivateDataIndices[idx]);
auto conditionalTable = IGF.Builder.CreateLoad(conditionalTablePtr);
- auto coercedSlot =
- IGF.Builder.CreateElementBitCast(slot, conditionalTable->getType());
- IGF.Builder.CreateStore(conditionalTable, coercedSlot);
- // Register local type data for the conditional conformance witness table.
const auto &condConformance = SILConditionalConformances[idx];
CanType reqTypeInContext =
Conformance.getDeclContext()
@@ -1906,9 +1918,7 @@
Flags = Flags.withNumConditionalRequirements(numConditional);
// Relative reference to the witness table.
- auto witnessTableRef =
- ConstantReference(Description.pattern, ConstantReference::Direct);
- B.addRelativeAddress(witnessTableRef);
+ B.addRelativeAddressOrNull(Description.pattern);
}
void addFlags() {
@@ -1980,6 +1990,15 @@
IGM.getAddrOfLLVMVariableOrGOTEquivalent(
LinkEntity::forAssociatedConformanceDescriptor(requirement));
B.addRelativeAddress(assocConformanceDescriptor);
+ } else if (entry.getKind() == SILWitnessTable::BaseProtocol) {
+ // Associated conformance descriptor for a base protocol.
+ const auto &witness = entry.getBaseProtocolWitness();
+ auto proto = SILWT->getProtocol();
+ BaseConformance requirement(proto, witness.Requirement);
+ auto baseConformanceDescriptor =
+ IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+ LinkEntity::forBaseConformanceDescriptor(requirement));
+ B.addRelativeAddress(baseConformanceDescriptor);
} else if (entry.getKind() == SILWitnessTable::Method) {
// Method descriptor.
auto declRef = entry.getMethodWitness().Requirement;
@@ -2152,7 +2171,7 @@
// so in theory we could allocate them on a BumpPtrAllocator. But there's not
// a good one for us to use. (The ASTContext's outlives the IRGenModule in
// batch mode.)
- if (isDependentConformance(rootConformance) ||
+ if (isDependentConformance(rootConformance, /*considerResilience=*/true) ||
// Foreign types need to go through the accessor to unique the witness
// table.
isSynthesizedNonUnique(rootConformance)) {
@@ -2220,22 +2239,32 @@
// Produce the initializer value.
auto initializer = wtableContents.finishAndCreateFuture();
- bool isDependent = isDependentConformance(conf);
- auto global = cast<llvm::GlobalVariable>(
- isDependent
- ? getAddrOfWitnessTablePattern(cast<NormalProtocolConformance>(conf),
- initializer)
- : getAddrOfWitnessTable(conf, initializer));
- global->setConstant(isConstantWitnessTable(wt));
- global->setAlignment(getWitnessTableAlignment().getValue());
+ llvm::GlobalVariable *global = nullptr;
+ unsigned tableSize;
+ if (!isResilientConformance(conf)) {
+ bool isDependent =
+ isDependentConformance(conf, /*considerResilience=*/false);
+ global = cast<llvm::GlobalVariable>(
+ isDependent
+ ? getAddrOfWitnessTablePattern(cast<NormalProtocolConformance>(conf),
+ initializer)
+ : getAddrOfWitnessTable(conf, initializer));
+ global->setConstant(isConstantWitnessTable(wt));
+ global->setAlignment(getWitnessTableAlignment().getValue());
+ tableSize = wtableBuilder.getTableSize();
+ } else {
+ initializer.abandon();
+ tableSize = 0;
+ }
// Collect the information that will go into the protocol conformance
// descriptor.
- ConformanceDescription description(conf, wt, global,
- wtableBuilder.getTableSize(),
+ ConformanceDescription description(conf, wt, global, tableSize,
wtableBuilder.getTablePrivateSize(),
wtableBuilder.requiresSpecialization(),
- hasDependentTypeWitness(conf));
+ isDependentConformance(
+ conf,
+ /*considerResilience=*/false));
// Build the instantiation function, we if need one.
description.instantiationFn = wtableBuilder.buildInstantiationFunction();
diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h
index 5c7bb60..9f3b7aa 100644
--- a/lib/IRGen/IRGenMangler.h
+++ b/lib/IRGen/IRGenMangler.h
@@ -197,13 +197,27 @@
const ProtocolDecl *requirement) {
beginMangling();
appendAnyGenericType(proto);
- bool isFirstAssociatedTypeIdentifier = true;
- appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier);
+ if (isa<GenericTypeParamType>(subject)) {
+ appendType(subject);
+ } else {
+ bool isFirstAssociatedTypeIdentifier = true;
+ appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier);
+ }
appendProtocolName(requirement);
appendOperator("Tn");
return finalize();
}
+ std::string mangleBaseConformanceDescriptor(
+ const ProtocolDecl *proto,
+ const ProtocolDecl *requirement) {
+ beginMangling();
+ appendAnyGenericType(proto);
+ appendProtocolName(requirement);
+ appendOperator("Tb");
+ return finalize();
+ }
+
std::string mangleDefaultAssociatedConformanceAccessor(
const ProtocolDecl *proto,
CanType subject,
@@ -273,6 +287,16 @@
return finalize();
}
+ std::string mangleBaseWitnessTableAccessFunction(
+ const ProtocolConformance *Conformance,
+ const ProtocolDecl *BaseProto) {
+ beginMangling();
+ appendProtocolConformance(Conformance);
+ appendAnyGenericType(BaseProto);
+ appendOperator("Wb");
+ return finalize();
+ }
+
void appendAssociatedTypePath(CanType associatedType, bool &isFirst) {
if (auto memberType = dyn_cast<DependentMemberType>(associatedType)) {
appendAssociatedTypePath(memberType.getBase(), isFirst);
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 223e983..47df73b 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -82,6 +82,7 @@
class AssociatedConformance;
class AssociatedType;
class ASTContext;
+ class BaseConformance;
class BraceStmt;
class CanType;
class LinkLibrary;
@@ -1296,6 +1297,11 @@
llvm::GlobalValue *defineAssociatedConformanceDescriptor(
AssociatedConformance conformance,
llvm::Constant *definition);
+ llvm::Constant *getAddrOfBaseConformanceDescriptor(
+ BaseConformance conformance);
+ llvm::GlobalValue *defineBaseConformanceDescriptor(
+ BaseConformance conformance,
+ llvm::Constant *definition);
llvm::Constant *getAddrOfProtocolDescriptor(ProtocolDecl *D,
ConstantInit definition = ConstantInit());
diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp
index 9cc0b57..aacb934 100644
--- a/lib/IRGen/Linking.cpp
+++ b/lib/IRGen/Linking.cpp
@@ -202,6 +202,13 @@
assocConformance.second);
}
+ case Kind::BaseConformanceDescriptor: {
+ auto assocConformance = getAssociatedConformance();
+ return mangler.mangleBaseConformanceDescriptor(
+ cast<ProtocolDecl>(getDecl()),
+ assocConformance.second);
+ }
+
case Kind::DefaultAssociatedConformanceAccessor: {
auto assocConformance = getAssociatedConformance();
return mangler.mangleDefaultAssociatedConformanceAccessor(
@@ -240,6 +247,11 @@
case Kind::AssociatedTypeWitnessTableAccessFunction: {
auto assocConf = getAssociatedConformance();
+ if (isa<GenericTypeParamType>(assocConf.first)) {
+ return mangler.mangleBaseWitnessTableAccessFunction(
+ getProtocolConformance(), assocConf.second);
+ }
+
return mangler.mangleAssociatedTypeWitnessTableAccessFunction(
getProtocolConformance(), assocConf.first, assocConf.second);
}
@@ -505,6 +517,7 @@
}
case Kind::AssociatedConformanceDescriptor:
+ case Kind::BaseConformanceDescriptor:
case Kind::ObjCClass:
case Kind::ObjCMetaclass:
case Kind::SwiftMetaclassStub:
@@ -656,6 +669,7 @@
return true;
case Kind::AssociatedConformanceDescriptor:
+ case Kind::BaseConformanceDescriptor:
case Kind::SwiftMetaclassStub:
case Kind::ClassMetadataBaseOffset:
case Kind::PropertyDescriptor:
@@ -737,6 +751,7 @@
return IGM.ProtocolDescriptorStructTy;
case Kind::AssociatedTypeDescriptor:
case Kind::AssociatedConformanceDescriptor:
+ case Kind::BaseConformanceDescriptor:
case Kind::ProtocolRequirementsBaseDescriptor:
return IGM.ProtocolRequirementStructTy;
case Kind::ProtocolConformanceDescriptor:
@@ -818,6 +833,7 @@
case Kind::ProtocolDescriptor:
case Kind::AssociatedTypeDescriptor:
case Kind::AssociatedConformanceDescriptor:
+ case Kind::BaseConformanceDescriptor:
case Kind::ProtocolConformanceDescriptor:
case Kind::ProtocolRequirementsBaseDescriptor:
case Kind::ReflectionBuiltinDescriptor:
@@ -884,6 +900,9 @@
return depMemTy->getAssocType()->isWeakImported(module);
}
+ case Kind::BaseConformanceDescriptor:
+ return cast<ProtocolDecl>(getDecl())->isWeakImported(module);
+
case Kind::TypeMetadata:
case Kind::TypeMetadataAccessFunction: {
if (auto *nominalDecl = getType()->getAnyNominal())
@@ -990,6 +1009,7 @@
case Kind::AssociatedTypeDescriptor:
case Kind::AssociatedConformanceDescriptor:
case Kind::DefaultAssociatedConformanceAccessor:
+ case Kind::BaseConformanceDescriptor:
case Kind::DynamicallyReplaceableFunctionVariableAST:
case Kind::DynamicallyReplaceableFunctionKeyAST:
case Kind::DynamicallyReplaceableFunctionImpl:
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index c25c233..f5b189e 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -134,21 +134,37 @@
downgradeToWarning = DowngradeToWarning::Yes;
}
+ auto diagName = D->getFullName();
+ bool isAccessor = false;
+
+ // Swift 4.2 did not check accessor accessiblity.
+ if (auto accessor = dyn_cast<AccessorDecl>(D)) {
+ isAccessor = true;
+
+ if (!Context.isSwiftVersionAtLeast(5))
+ downgradeToWarning = DowngradeToWarning::Yes;
+
+ // For accessors, diagnose with the name of the storage instead of the
+ // implicit '_'.
+ diagName = accessor->getStorage()->getFullName();
+ }
+
auto diagID = diag::resilience_decl_unavailable;
if (downgradeToWarning == DowngradeToWarning::Yes)
diagID = diag::resilience_decl_unavailable_warn;
diagnose(loc, diagID,
- D->getDescriptiveKind(), D->getFullName(),
+ D->getDescriptiveKind(), diagName,
D->getFormalAccessScope().accessLevelForDiagnostics(),
- static_cast<unsigned>(Kind));
+ static_cast<unsigned>(Kind),
+ isAccessor);
if (TreatUsableFromInlineAsPublic) {
diagnose(D, diag::resilience_decl_declared_here,
- D->getDescriptiveKind(), D->getFullName());
+ D->getDescriptiveKind(), diagName, isAccessor);
} else {
diagnose(D, diag::resilience_decl_declared_here_public,
- D->getDescriptiveKind(), D->getFullName());
+ D->getDescriptiveKind(), diagName, isAccessor);
}
return (downgradeToWarning == DowngradeToWarning::No);
diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp
index ce6bfa0..15bd0c9 100644
--- a/lib/Sema/TypeCheckAvailability.cpp
+++ b/lib/Sema/TypeCheckAvailability.cpp
@@ -1355,12 +1355,12 @@
}
void TypeChecker::diagnosePotentialAccessorUnavailability(
- AccessorDecl *Accessor, SourceRange ReferenceRange,
+ const AccessorDecl *Accessor, SourceRange ReferenceRange,
const DeclContext *ReferenceDC, const UnavailabilityReason &Reason,
bool ForInout) {
assert(Accessor->isGetterOrSetter());
- AbstractStorageDecl *ASD = Accessor->getStorage();
+ const AbstractStorageDecl *ASD = Accessor->getStorage();
DeclName Name = ASD->getFullName();
auto &diag = ForInout ? diag::availability_inout_accessor_only_version_newer
@@ -2355,7 +2355,8 @@
bool diagAvailability(const ValueDecl *D, SourceRange R,
const ApplyExpr *call = nullptr,
bool AllowPotentiallyUnavailableProtocol = false,
- bool SignalOnPotentialUnavailability = true);
+ bool SignalOnPotentialUnavailability = true,
+ bool ForInout = false);
private:
bool diagnoseIncDecRemoval(const ValueDecl *D, SourceRange R,
@@ -2511,32 +2512,13 @@
void diagAccessorAvailability(AccessorDecl *D, SourceRange ReferenceRange,
const DeclContext *ReferenceDC,
bool ForInout) const {
- if (!D) {
+ if (diagnoseDeclAvailability(D, TC,
+ const_cast<DeclContext*>(ReferenceDC),
+ ReferenceRange,
+ /*AllowPotentiallyUnavailableProtocol*/false,
+ /*SignalOnPotentialUnavailability*/false,
+ ForInout))
return;
- }
-
- // If the property/subscript is unconditionally unavailable, don't bother
- // with any of the rest of this.
- if (AvailableAttr::isUnavailable(D->getStorage()))
- return;
-
- if (diagnoseExplicitUnavailability(D, ReferenceRange, ReferenceDC,
- /*call*/nullptr)) {
- return;
- }
-
- // Make sure not to diagnose an accessor's deprecation if we already
- // complained about the property/subscript.
- if (!TypeChecker::getDeprecated(D->getStorage()))
- TC.diagnoseIfDeprecated(ReferenceRange, ReferenceDC, D, /*call*/nullptr);
-
- auto MaybeUnavail = TC.checkDeclarationAvailability(D, ReferenceRange.Start,
- DC);
- if (MaybeUnavail.hasValue()) {
- TC.diagnosePotentialAccessorUnavailability(D, ReferenceRange, ReferenceDC,
- MaybeUnavail.getValue(),
- ForInout);
- }
}
};
} // end anonymous namespace
@@ -2546,7 +2528,8 @@
bool AvailabilityWalker::diagAvailability(const ValueDecl *D, SourceRange R,
const ApplyExpr *call,
bool AllowPotentiallyUnavailableProtocol,
- bool SignalOnPotentialUnavailability) {
+ bool SignalOnPotentialUnavailability,
+ bool ForInout) {
if (!D)
return false;
@@ -2557,6 +2540,16 @@
return true;
}
+ // Keep track if this is an accessor.
+ auto accessor = dyn_cast<AccessorDecl>(D);
+
+ if (accessor) {
+ // If the property/subscript is unconditionally unavailable, don't bother
+ // with any of the rest of this.
+ if (AvailableAttr::isUnavailable(accessor->getStorage()))
+ return false;
+ }
+
if (FragileKind)
if (R.isValid())
if (TC.diagnoseInlinableDeclRef(R.Start, D, DC, *FragileKind,
@@ -2566,8 +2559,14 @@
if (diagnoseExplicitUnavailability(D, R, DC, call))
return true;
+ // Make sure not to diagnose an accessor's deprecation if we already
+ // complained about the property/subscript.
+ bool isAccessorWithDeprecatedStorage =
+ accessor && TypeChecker::getDeprecated(accessor->getStorage());
+
// Diagnose for deprecation
- TC.diagnoseIfDeprecated(R, DC, D, call);
+ if (!isAccessorWithDeprecatedStorage)
+ TC.diagnoseIfDeprecated(R, DC, D, call);
if (AllowPotentiallyUnavailableProtocol && isa<ProtocolDecl>(D))
return false;
@@ -2575,7 +2574,13 @@
// Diagnose (and possibly signal) for potential unavailability
auto maybeUnavail = TC.checkDeclarationAvailability(D, R.Start, DC);
if (maybeUnavail.hasValue()) {
- TC.diagnosePotentialUnavailability(D, R, DC, maybeUnavail.getValue());
+ if (accessor) {
+ TC.diagnosePotentialAccessorUnavailability(accessor, R, DC,
+ maybeUnavail.getValue(),
+ ForInout);
+ } else {
+ TC.diagnosePotentialUnavailability(D, R, DC, maybeUnavail.getValue());
+ }
if (SignalOnPotentialUnavailability)
return true;
}
@@ -2751,10 +2756,12 @@
DeclContext *DC,
SourceRange R,
bool AllowPotentiallyUnavailableProtocol,
- bool SignalOnPotentialUnavailability)
+ bool SignalOnPotentialUnavailability,
+ bool ForInout)
{
AvailabilityWalker AW(TC, DC);
return AW.diagAvailability(Decl, R, nullptr,
AllowPotentiallyUnavailableProtocol,
- SignalOnPotentialUnavailability);
+ SignalOnPotentialUnavailability,
+ ForInout);
}
diff --git a/lib/Sema/TypeCheckAvailability.h b/lib/Sema/TypeCheckAvailability.h
index 23c12a0..54b8396 100644
--- a/lib/Sema/TypeCheckAvailability.h
+++ b/lib/Sema/TypeCheckAvailability.h
@@ -41,7 +41,8 @@
DeclContext *DC,
SourceRange R,
bool AllowPotentiallyUnavailableProtocol,
- bool SignalOnPotentialUnavailability);
+ bool SignalOnPotentialUnavailability,
+ bool ForInout);
void diagnoseUnavailableOverride(ValueDecl *override,
const ValueDecl *base,
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 6fc8fc6..7ee6c0f 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3915,7 +3915,7 @@
});
if (mentionsItself) {
- diagnose(defaultDefinition.getLoc(), diag::recursive_type_reference,
+ diagnose(defaultDefinition.getLoc(), diag::recursive_decl_reference,
assocType->getDescriptiveKind(), assocType->getName());
diagnose(assocType, diag::kind_declared_here, DescriptiveDeclKind::Type);
}
diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp
index 2ee3db6..b14489c 100644
--- a/lib/Sema/TypeCheckDeclObjC.cpp
+++ b/lib/Sema/TypeCheckDeclObjC.cpp
@@ -760,7 +760,7 @@
VD->getASTContext().getLazyResolver()->resolveDeclSignature(
const_cast<VarDecl *>(VD));
if (!VD->hasInterfaceType()) {
- VD->diagnose(diag::recursive_type_reference, VD->getDescriptiveKind(),
+ VD->diagnose(diag::recursive_decl_reference, VD->getDescriptiveKind(),
VD->getName());
return false;
}
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 3a34ed6..10b92ed 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -440,9 +440,12 @@
return RequirementMatch(witness, MatchKind::KindConflict);
// If the witness is invalid, record that and stop now.
- if (witness->isInvalid() || !witness->hasValidSignature())
+ if (witness->isInvalid())
return RequirementMatch(witness, MatchKind::WitnessInvalid);
+ if (!witness->hasValidSignature())
+ return RequirementMatch(witness, MatchKind::Circularity);
+
// Get the requirement and witness attributes.
const auto &reqAttrs = req->getAttrs();
const auto &witnessAttrs = witness->getAttrs();
@@ -1146,15 +1149,9 @@
continue;
}
- if (!witness->hasValidSignature()) {
+ if (!witness->hasValidSignature())
TC.validateDecl(witness);
- if (!witness->hasValidSignature()) {
- doNotDiagnoseMatches = true;
- continue;
- }
- }
-
auto match = matchWitness(TC, ReqEnvironmentCache, Proto, conformance, DC,
requirement, witness);
if (match.isViable()) {
@@ -2130,6 +2127,10 @@
// about them.
break;
+ case MatchKind::Circularity:
+ diags.diagnose(match.Witness, diag::protocol_witness_circularity);
+ break;
+
case MatchKind::TypeConflict: {
auto diag = diags.diagnose(match.Witness,
diag::protocol_witness_type_conflict,
diff --git a/lib/Sema/TypeCheckProtocol.h b/lib/Sema/TypeCheckProtocol.h
index 15dbb19..c58be0d 100644
--- a/lib/Sema/TypeCheckProtocol.h
+++ b/lib/Sema/TypeCheckProtocol.h
@@ -166,6 +166,11 @@
/// \brief The witness is invalid or has an invalid type.
WitnessInvalid,
+ /// The witness is currently being type checked and this type checking in turn
+ /// triggered conformance checking, so the witness cannot be considered as a
+ /// candidate.
+ Circularity,
+
/// \brief The kind of the witness and requirement differ, e.g., one
/// is a function and the other is a variable.
KindConflict,
@@ -405,6 +410,7 @@
return true;
case MatchKind::WitnessInvalid:
+ case MatchKind::Circularity:
case MatchKind::KindConflict:
case MatchKind::TypeConflict:
case MatchKind::MissingRequirement:
@@ -435,6 +441,7 @@
return true;
case MatchKind::WitnessInvalid:
+ case MatchKind::Circularity:
case MatchKind::KindConflict:
case MatchKind::StaticNonStaticConflict:
case MatchKind::SettableConflict:
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index c57e914..e60aa87 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -700,7 +700,7 @@
// FIXME: More principled handling of circularity.
if (!genericDecl->hasValidSignature()) {
- diags.diagnose(loc, diag::recursive_type_reference,
+ diags.diagnose(loc, diag::recursive_decl_reference,
genericDecl->getDescriptiveKind(), genericDecl->getName());
genericDecl->diagnose(diag::kind_declared_here, DescriptiveDeclKind::Type);
return ErrorType::get(ctx);
@@ -922,7 +922,7 @@
// If we were not able to validate recursively, bail out.
if (!typeDecl->hasInterfaceType()) {
- diags.diagnose(loc, diag::recursive_type_reference,
+ diags.diagnose(loc, diag::recursive_decl_reference,
typeDecl->getDescriptiveKind(), typeDecl->getName());
typeDecl->diagnose(diag::kind_declared_here,
DescriptiveDeclKind::Type);
@@ -1515,7 +1515,8 @@
TypeChecker &tc = static_cast<TypeChecker &>(*ctx.getLazyResolver());
if (diagnoseDeclAvailability(typeDecl, tc, DC, comp->getIdLoc(),
AllowPotentiallyUnavailableProtocol,
- /*SignalOnPotentialUnavailability*/false)) {
+ /*SignalOnPotentialUnavailability*/false,
+ /*ForInout*/false)) {
return true;
}
}
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 8ee715b..34ac3e5 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -2077,7 +2077,7 @@
/// Emits a diagnostic for a reference to a storage accessor that is
/// potentially unavailable.
void diagnosePotentialAccessorUnavailability(
- AccessorDecl *Accessor, SourceRange ReferenceRange,
+ const AccessorDecl *Accessor, SourceRange ReferenceRange,
const DeclContext *ReferenceDC, const UnavailabilityReason &Reason,
bool ForInout);
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 4cf0819..1ccac7b 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -105,6 +105,12 @@
addSymbol(entity);
}
+void TBDGenVisitor::addBaseConformanceDescriptor(
+ BaseConformance conformance) {
+ auto entity = LinkEntity::forBaseConformanceDescriptor(conformance);
+ addSymbol(entity);
+}
+
void TBDGenVisitor::addConformances(DeclContext *DC) {
for (auto conformance : DC->getLocalConformances()) {
auto protocol = conformance->getProtocol();
@@ -432,15 +438,18 @@
if (req.getKind() != RequirementKind::Conformance)
continue;
- // Skip inherited requirements.
- if (req.getFirstType()->isEqual(PD->getSelfInterfaceType()))
- continue;
-
- AssociatedConformance conformance(
- PD,
- req.getFirstType()->getCanonicalType(),
- req.getSecondType()->castTo<ProtocolType>()->getDecl());
- addAssociatedConformanceDescriptor(conformance);
+ if (req.getFirstType()->isEqual(PD->getSelfInterfaceType())) {
+ BaseConformance conformance(
+ PD,
+ req.getSecondType()->castTo<ProtocolType>()->getDecl());
+ addBaseConformanceDescriptor(conformance);
+ } else {
+ AssociatedConformance conformance(
+ PD,
+ req.getFirstType()->getCanonicalType(),
+ req.getSecondType()->castTo<ProtocolType>()->getDecl());
+ addAssociatedConformanceDescriptor(conformance);
+ }
}
for (auto *member : PD->getMembers()) {
diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h
index e468265..9f2582e 100644
--- a/lib/TBDGen/TBDGenVisitor.h
+++ b/lib/TBDGen/TBDGenVisitor.h
@@ -67,6 +67,7 @@
void addProtocolRequirementsBaseDescriptor(ProtocolDecl *proto);
void addAssociatedTypeDescriptor(AssociatedTypeDecl *assocType);
void addAssociatedConformanceDescriptor(AssociatedConformance conformance);
+ void addBaseConformanceDescriptor(BaseConformance conformance);
public:
TBDGenVisitor(tapi::internal::InterfaceFile &symbols,
diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt
index 0972ef9..3f4134d 100644
--- a/stdlib/public/CMakeLists.txt
+++ b/stdlib/public/CMakeLists.txt
@@ -55,8 +55,12 @@
add_subdirectory(runtime)
add_subdirectory(stubs)
add_subdirectory(core)
- add_subdirectory(SIMDOperators)
add_subdirectory(SwiftOnoneSupport)
+
+ # NOTE(compnerd) this must come after the SwiftOnoneSupport as the current
+ # cross-compilation support has to hand roll the import library setup which
+ # requires that the target is setup prior to use.
+ add_subdirectory(SIMDOperators)
endif()
if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)
diff --git a/stdlib/public/core/StringComparison.swift b/stdlib/public/core/StringComparison.swift
index 684bf90..9a93af5 100644
--- a/stdlib/public/core/StringComparison.swift
+++ b/stdlib/public/core/StringComparison.swift
@@ -18,9 +18,31 @@
_ lhs: _StringGuts, _ rhs: _StringGuts, expecting: _StringComparisonResult
) -> Bool {
if lhs.rawBits == rhs.rawBits { return expecting == .equal }
+ return _stringCompareWithSmolCheck(lhs, rhs, expecting: expecting)
+}
+
+@usableFromInline
+@_effects(readonly)
+internal func _stringCompareWithSmolCheck(
+ _ lhs: _StringGuts, _ rhs: _StringGuts, expecting: _StringComparisonResult
+) -> Bool {
+ // ASCII small-string fast-path:
+ if lhs.isSmallASCII && rhs.isSmallASCII {
+ let lhsRaw = lhs.asSmall._storage
+ let rhsRaw = rhs.asSmall._storage
+
+ if lhsRaw.0 != rhsRaw.0 {
+ return _lexicographicalCompare(
+ lhsRaw.0.byteSwapped, rhsRaw.0.byteSwapped, expecting: expecting)
+ }
+ return _lexicographicalCompare(
+ lhsRaw.1.byteSwapped, rhsRaw.1.byteSwapped, expecting: expecting)
+ }
+
return _stringCompareInternal(lhs, rhs, expecting: expecting)
}
+@inline(never) // Keep `_stringCompareWithSmolCheck` fast-path fast
@usableFromInline
@_effects(readonly)
internal func _stringCompareInternal(
diff --git a/stdlib/public/core/StringCreate.swift b/stdlib/public/core/StringCreate.swift
index 49fff68..ec032c1 100644
--- a/stdlib/public/core/StringCreate.swift
+++ b/stdlib/public/core/StringCreate.swift
@@ -169,5 +169,16 @@
) -> String {
return String._fromCodeUnits(utf16, encoding: UTF16.self, repair: true)!.0
}
+
+ @usableFromInline
+ internal static func _fromSubstring(
+ _ substring: __shared Substring
+ ) -> String {
+ if substring._offsetRange == substring._wholeString._offsetRange {
+ return substring._wholeString
+ }
+
+ return substring._withUTF8 { return String._uncheckedFromUTF8($0) }
+ }
}
diff --git a/stdlib/public/core/StringGuts.swift b/stdlib/public/core/StringGuts.swift
index f6413e2..718d132 100644
--- a/stdlib/public/core/StringGuts.swift
+++ b/stdlib/public/core/StringGuts.swift
@@ -90,6 +90,10 @@
@inline(__always) get { return _object.isSmall }
}
+ internal var isSmallASCII: Bool {
+ @inline(__always) get { return _object.isSmall && _object.smallIsASCII }
+ }
+
@inlinable
internal var asSmall: _SmallString {
@inline(__always) get { return _SmallString(_object) }
diff --git a/stdlib/public/core/Substring.swift b/stdlib/public/core/Substring.swift
index 6ffcc0a..33e3615 100644
--- a/stdlib/public/core/Substring.swift
+++ b/stdlib/public/core/Substring.swift
@@ -20,7 +20,7 @@
/// - Complexity: O(*n*), where *n* is the length of `substring`.
@inlinable
public init(_ substring: __shared Substring) {
- self = substring._withUTF8 { return String._uncheckedFromUTF8($0) }
+ self = String._fromSubstring(substring)
}
}
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index 5efb7c4..2d97e46 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -294,7 +294,8 @@
/// Dynamically cast a class object to a Swift class type.
static const void *
swift_dynamicCastClassUnconditionalImpl(const void *object,
- const ClassMetadata *targetType) {
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column) {
auto value = swift_dynamicCastClass(object, targetType);
if (value) return value;
@@ -571,7 +572,8 @@
SWIFT_RUNTIME_EXPORT
id
-swift_dynamicCastMetatypeToObjectUnconditional(const Metadata *metatype) {
+swift_dynamicCastMetatypeToObjectUnconditional(const Metadata *metatype,
+ const char *file, unsigned line, unsigned column) {
switch (metatype->getKind()) {
case MetadataKind::Class:
case MetadataKind::ObjCClassWrapper:
@@ -1001,18 +1003,19 @@
/// sort of class type.
static const void *
swift_dynamicCastUnknownClassUnconditionalImpl(const void *object,
- const Metadata *targetType) {
+ const Metadata *targetType,
+ const char *file, unsigned line, unsigned column) {
switch (targetType->getKind()) {
case MetadataKind::Class: {
auto targetClassType = static_cast<const ClassMetadata *>(targetType);
- return swift_dynamicCastClassUnconditional(object, targetClassType);
+ return swift_dynamicCastClassUnconditional(object, targetClassType, file, line, column);
}
case MetadataKind::ObjCClassWrapper: {
#if SWIFT_OBJC_INTEROP
auto targetClassType
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
- return swift_dynamicCastObjCClassUnconditional(object, targetClassType);
+ return swift_dynamicCastObjCClassUnconditional(object, targetClassType, file, line, column);
#else
swift_dynamicCastFailure(_swift_getClass(object), targetType);
#endif
@@ -1021,7 +1024,7 @@
case MetadataKind::ForeignClass: {
#if SWIFT_OBJC_INTEROP
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
- return swift_dynamicCastForeignClassUnconditional(object, targetClassType);
+ return swift_dynamicCastForeignClassUnconditional(object, targetClassType, file, line, column);
#else
swift_dynamicCastFailure(_swift_getClass(object), targetType);
#endif
@@ -1127,7 +1130,8 @@
static const Metadata *
swift_dynamicCastMetatypeUnconditionalImpl(const Metadata *sourceType,
- const Metadata *targetType) {
+ const Metadata *targetType,
+ const char *file, unsigned line, unsigned column) {
auto origSourceType = sourceType;
switch (targetType->getKind()) {
@@ -1151,7 +1155,8 @@
// land.
swift_dynamicCastObjCClassMetatypeUnconditional(
(const ClassMetadata*)sourceType,
- (const ClassMetadata*)targetType);
+ (const ClassMetadata*)targetType,
+ file, line, column);
#else
if (!_dynamicCastClassMetatype((const ClassMetadata*)sourceType,
(const ClassMetadata*)targetType))
@@ -1164,7 +1169,8 @@
// Check if the source is a subclass of the target.
swift_dynamicCastForeignClassMetatypeUnconditional(
(const ClassMetadata*)sourceType,
- (const ClassMetadata*)targetType);
+ (const ClassMetadata*)targetType,
+ file, line, column);
// If we returned, then the cast succeeded.
return origSourceType;
}
@@ -1186,7 +1192,8 @@
// Check if the source is a subclass of the target.
swift_dynamicCastForeignClassMetatypeUnconditional(
(const ClassMetadata*)sourceType,
- (const ClassMetadata*)targetType);
+ (const ClassMetadata*)targetType,
+ file, line, column);
// If we returned, then the cast succeeded.
return origSourceType;
default:
@@ -1209,11 +1216,12 @@
/// Do a dynamic cast to the target class.
static void *_dynamicCastUnknownClass(void *object,
const Metadata *targetType,
+ // TODO: carry through source location info
bool unconditional) {
// The unconditional path avoids some failure logic.
if (unconditional) {
return const_cast<void*>(
- swift_dynamicCastUnknownClassUnconditional(object, targetType));
+ swift_dynamicCastUnknownClassUnconditional(object, targetType, nullptr, 0, 0));
}
return const_cast<void*>(swift_dynamicCastUnknownClass(object, targetType));
@@ -1228,7 +1236,7 @@
// The unconditional path avoids some failure logic.
if (flags & DynamicCastFlags::Unconditional) {
void *result = const_cast<void*>(
- swift_dynamicCastUnknownClassUnconditional(object, targetType));
+ swift_dynamicCastUnknownClassUnconditional(object, targetType, nullptr, 0, 0));
*destSlot = result;
if (!(flags & DynamicCastFlags::TakeOnSuccess)) {
@@ -1438,7 +1446,8 @@
const Metadata *result;
if (flags & DynamicCastFlags::Unconditional) {
result = swift_dynamicCastMetatypeUnconditional(metatype,
- targetType->InstanceType);
+ targetType->InstanceType,
+ nullptr, 0, 0);
} else {
result = swift_dynamicCastMetatype(metatype, targetType->InstanceType);
if (!result) return false;
@@ -2436,6 +2445,10 @@
cast<StructMetadata>(srcType),
cast<StructMetadata>(targetType),
flags);
+ } else if (isAnyHashableType(srcType)) {
+ // AnyHashable casts for enums.
+ return _dynamicCastFromAnyHashable(dest, src, srcType, targetType,
+ flags);
}
break;
diff --git a/stdlib/public/runtime/CompatibilityOverride.def b/stdlib/public/runtime/CompatibilityOverride.def
index 4906a96..07a82e6 100644
--- a/stdlib/public/runtime/CompatibilityOverride.def
+++ b/stdlib/public/runtime/CompatibilityOverride.def
@@ -85,8 +85,9 @@
OVERRIDE_CASTING(dynamicCastClassUnconditional, const void *, , swift::,
(const void *object,
- const ClassMetadata *targetType),
- (object, targetType))
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (object, targetType, file, line, column))
@@ -96,8 +97,9 @@
OVERRIDE_CASTING(dynamicCastUnknownClassUnconditional, const void *, , swift::,
- (const void *object, const Metadata *targetType),
- (object, targetType))
+ (const void *object, const Metadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (object, targetType, file, line, column))
OVERRIDE_CASTING(dynamicCastMetatype, const Metadata *, , swift::,
@@ -108,8 +110,9 @@
OVERRIDE_CASTING(dynamicCastMetatypeUnconditional, const Metadata *, , swift::,
(const Metadata *sourceType,
- const Metadata *targetType),
- (sourceType, targetType))
+ const Metadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (sourceType, targetType, file, line, column))
OVERRIDE_FOREIGN(dynamicCastForeignClassMetatype, const ClassMetadata *, , swift::,
@@ -121,8 +124,9 @@
OVERRIDE_FOREIGN(dynamicCastForeignClassMetatypeUnconditional,
const ClassMetadata *, , swift::,
(const ClassMetadata *sourceType,
- const ClassMetadata *targetType),
- (sourceType, targetType))
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (sourceType, targetType, file, line, column))
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocol, const WitnessTable *, , swift::,
@@ -179,8 +183,9 @@
OVERRIDE_OBJC(dynamicCastObjCClassUnconditional, const void *, , swift::,
(const void *object,
- const ClassMetadata *targetType),
- (object, targetType))
+ const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (object, targetType, file, line, column))
OVERRIDE_OBJC(dynamicCastObjCClassMetatype, const ClassMetadata *, , swift::,
(const ClassMetadata *sourceType,
@@ -189,8 +194,9 @@
OVERRIDE_OBJC(dynamicCastObjCClassMetatypeUnconditional, const ClassMetadata *, , swift::,
- (const ClassMetadata *sourceType, const ClassMetadata *targetType),
- (sourceType, targetType))
+ (const ClassMetadata *sourceType, const ClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (sourceType, targetType, file, line, column))
OVERRIDE_FOREIGN(dynamicCastForeignClass, const void *, , swift::,
@@ -200,8 +206,9 @@
OVERRIDE_FOREIGN(dynamicCastForeignClassUnconditional, const void *, , swift::,
- (const void *object, const ForeignClassMetadata *targetType),
- (object, targetType))
+ (const void *object, const ForeignClassMetadata *targetType,
+ const char *file, unsigned line, unsigned column),
+ (object, targetType, file, line, column))
#endif
diff --git a/stdlib/public/runtime/ExistentialMetadataImpl.h b/stdlib/public/runtime/ExistentialMetadataImpl.h
index bcb8c656..1eed70b 100644
--- a/stdlib/public/runtime/ExistentialMetadataImpl.h
+++ b/stdlib/public/runtime/ExistentialMetadataImpl.h
@@ -624,7 +624,7 @@
ExistentialMetatypeContainer Header;
static unsigned getNumWitnessTables(const Metadata *self) {
- auto castSelf = static_cast<const ExistentialTypeMetadata*>(self);
+ auto castSelf = static_cast<const ExistentialMetatypeMetadata*>(self);
return castSelf->Flags.getNumWitnessTables();
}
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 0f3b905..a6c93e6 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -4002,6 +4002,7 @@
/// witnesses stored in the generic witness table structure itself.
static void initializeResilientWitnessTable(
const ProtocolConformanceDescriptor *conformance,
+ const Metadata *conformingType,
const GenericWitnessTable *genericTable,
void **table) {
auto protocol = conformance->getProtocol();
@@ -4015,7 +4016,7 @@
auto reqDescriptor = witness.Requirement.get();
// The requirement descriptor may be NULL, in which case this is a
- // requirement introduced in a later version of the protocol./
+ // requirement introduced in a later version of the protocol.
if (!reqDescriptor) continue;
// If the requirement descriptor doesn't land within the bounds of the
@@ -4038,14 +4039,24 @@
for (size_t i = 0, e = protocol->NumRequirements; i < e; ++i) {
unsigned witnessIndex = WitnessTableFirstRequirementOffset + i;
+ // If we don't have a witness, fill in the default implementation.
// If we already have a witness, there's nothing to do.
- if (table[witnessIndex])
- continue;
-
- // Otherwise, fill in a default implementation.
auto &reqt = requirements[i];
- void *impl = reqt.DefaultImplementation.get();
- table[witnessIndex] = impl;
+ if (!table[witnessIndex]) {
+ void *impl = reqt.DefaultImplementation.get();
+ table[witnessIndex] = impl;
+ }
+
+ // Realize base protocol witnesses.
+ if (reqt.Flags.getKind() == ProtocolRequirementFlags::Kind::BaseProtocol &&
+ table[witnessIndex]) {
+ // Realize the base protocol witness table.
+ auto baseReq = protocol->getRequirementBaseDescriptor();
+ (void)swift_getAssociatedConformanceWitness((WitnessTable *)table,
+ conformingType,
+ conformingType,
+ baseReq, &reqt);
+ }
}
}
@@ -4079,17 +4090,42 @@
// Advance the address point; the private storage area is accessed via
// negative offsets.
auto table = fullTable + privateSizeInWords;
- auto pattern = reinterpret_cast<void * const *>(
- &*conformance->getWitnessTablePattern());
+ if (auto pattern =
+ reinterpret_cast<void * const *>(
+ &*conformance->getWitnessTablePattern())) {
+ // Fill in the provided part of the requirements from the pattern.
+ for (size_t i = 0, e = numPatternWitnesses; i < e; ++i) {
+ table[i] = pattern[i];
+ }
+ } else {
+ // Put the conformance descriptor in place. Instantiation will fill in the
+ // rest.
+ assert(numPatternWitnesses == 0);
+ table[0] = (void *)conformance;
+ }
- // Fill in the provided part of the requirements from the pattern.
- for (size_t i = 0, e = numPatternWitnesses; i < e; ++i) {
- table[i] = pattern[i];
+ // Copy any instantiation arguments that correspond to conditional
+ // requirements into the private area.
+ {
+ unsigned currentInstantiationArg = 0;
+ auto copyNextInstantiationArg = [&] {
+ assert(currentInstantiationArg < privateSizeInWords);
+ table[-1 - (int)currentInstantiationArg] =
+ const_cast<void *>(instantiationArgs[currentInstantiationArg]);
+ ++currentInstantiationArg;
+ };
+
+ for (const auto &conditionalRequirement
+ : conformance->getConditionalRequirements()) {
+ if (conditionalRequirement.Flags.hasKeyArgument())
+ copyNextInstantiationArg();
+ if (conditionalRequirement.Flags.hasExtraArgument())
+ copyNextInstantiationArg();
+ }
}
// Fill in any default requirements.
- initializeResilientWitnessTable(conformance, genericTable, table);
-
+ initializeResilientWitnessTable(conformance, Type, genericTable, table);
auto castTable = reinterpret_cast<WitnessTable*>(table);
// Call the instantiation function if present.
diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm
index abea0bf..14b8c53 100644
--- a/stdlib/public/runtime/SwiftObject.mm
+++ b/stdlib/public/runtime/SwiftObject.mm
@@ -1116,7 +1116,9 @@
static const void *
swift_dynamicCastObjCClassUnconditionalImpl(const void *object,
- const ClassMetadata *targetType) {
+ const ClassMetadata *targetType,
+ const char *filename,
+ unsigned line, unsigned column) {
// FIXME: We need to decide if this is really how we want to treat 'nil'.
if (object == nullptr)
return nullptr;
@@ -1140,7 +1142,9 @@
static const void *
swift_dynamicCastForeignClassUnconditionalImpl(
const void *object,
- const ForeignClassMetadata *targetType) {
+ const ForeignClassMetadata *targetType,
+ const char *filename,
+ unsigned line, unsigned column) {
// FIXME: Actual compare CFTypeIDs, once they are available in the metadata.
return object;
}
@@ -1160,9 +1164,11 @@
SWIFT_RUNTIME_EXPORT
const Metadata *swift_dynamicCastTypeToObjCProtocolUnconditional(
- const Metadata *type,
- size_t numProtocols,
- Protocol * const *protocols) {
+ const Metadata *type,
+ size_t numProtocols,
+ Protocol * const *protocols,
+ const char *filename,
+ unsigned line, unsigned column) {
Class classObject;
switch (type->getKind()) {
@@ -1233,7 +1239,9 @@
SWIFT_RUNTIME_EXPORT
id swift_dynamicCastObjCProtocolUnconditional(id object,
size_t numProtocols,
- Protocol * const *protocols) {
+ Protocol * const *protocols,
+ const char *filename,
+ unsigned line, unsigned column) {
for (size_t i = 0; i < numProtocols; ++i) {
if (![object conformsToProtocol:protocols[i]]) {
Class sourceType = object_getClass(object);
@@ -1289,7 +1297,9 @@
static const ClassMetadata *
swift_dynamicCastObjCClassMetatypeUnconditionalImpl(const ClassMetadata *source,
- const ClassMetadata *dest) {
+ const ClassMetadata *dest,
+ const char *filename,
+ unsigned line, unsigned column) {
if ([class_const_cast(source) isSubclassOfClass:class_const_cast(dest)])
return source;
@@ -1309,7 +1319,9 @@
static const ClassMetadata *
swift_dynamicCastForeignClassMetatypeUnconditionalImpl(
const ClassMetadata *sourceType,
- const ClassMetadata *targetType)
+ const ClassMetadata *targetType,
+ const char *filename,
+ unsigned line, unsigned column)
{
// FIXME: Actually compare CFTypeIDs, once they arae available in
// the metadata.
diff --git a/test/ClangImporter/objc_ir.swift b/test/ClangImporter/objc_ir.swift
index bd5f39b..10d44b7 100644
--- a/test/ClangImporter/objc_ir.swift
+++ b/test/ClangImporter/objc_ir.swift
@@ -85,7 +85,7 @@
// CHECK: [[CLASS:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_B"
// CHECK: [[T0:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[CLASS]])
// CHECK: [[T1:%.*]] = bitcast %objc_class* [[T0]] to i8*
- // CHECK: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[A:%.*]], i8* [[T1]]) [[NOUNWIND:#[0-9]+]]
+ // CHECK: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[A:%.*]], i8* [[T1]], {{.*}}) [[NOUNWIND:#[0-9]+]]
return a as! B
}
diff --git a/test/Compatibility/attr_inlinable_swift42.swift b/test/Compatibility/attr_inlinable_swift42.swift
new file mode 100644
index 0000000..2b791c8
--- /dev/null
+++ b/test/Compatibility/attr_inlinable_swift42.swift
@@ -0,0 +1,36 @@
+// RUN: %target-typecheck-verify-swift -swift-version 4.2
+// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-testing
+// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience
+// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience -enable-testing
+
+enum InternalEnum {
+ // expected-note@-1 {{type declared here}}
+ case apple
+ case orange
+}
+
+@usableFromInline enum VersionedEnum {
+ case apple
+ case orange
+ case pear(InternalEnum)
+ // expected-warning@-1 {{type of enum case in '@usableFromInline' enum should be '@usableFromInline' or public}}
+ case persimmon(String)
+}
+
+public struct HasInternalSetProperty {
+ public internal(set) var x: Int // expected-note {{setter for 'x' is not '@usableFromInline' or public}}
+
+ @inlinable public mutating func setsX() {
+ x = 10 // expected-warning {{setter for 'x' is internal and should not be referenced from an '@inlinable' function}}
+ }
+}
+
+@usableFromInline protocol P {
+ typealias T = Int
+}
+
+extension P {
+ @inlinable func f() {
+ _ = T.self // typealiases were not checked in Swift 4.2, but P.T inherits @usableFromInline in Swift 4.2 mode
+ }
+}
diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt
index 0bd1123..1fcab70 100644
--- a/test/Demangle/Inputs/manglings.txt
+++ b/test/Demangle/Inputs/manglings.txt
@@ -334,4 +334,4 @@
$S1t1PP10AssocType2_AA1QTN ---> default associated conformance accessor for t.P.AssocType2: t.Q
$sSD5IndexVy__GD ---> $sSD5IndexVy__GD
$s4test3StrCACycfC ---> {T:$s4test3StrCACycfc} test.Str.__allocating_init() -> test.Str
-
+$s18resilient_protocol24ResilientDerivedProtocolPxAA0c4BaseE0Tn --> associated conformance descriptor for resilient_protocol.ResilientDerivedProtocol.A: resilient_protocol.ResilientBaseProtocol
diff --git a/test/IRGen/associated_type_witness.swift b/test/IRGen/associated_type_witness.swift
index 0fb403d..a251440 100644
--- a/test/IRGen/associated_type_witness.swift
+++ b/test/IRGen/associated_type_witness.swift
@@ -146,7 +146,7 @@
// Protocol conformance descriptor for GenericComputed : DerivedFromSimpleAssoc.
// GLOBAL-LABEL: @"$s23associated_type_witness15GenericComputedVyxGAA22DerivedFromSimpleAssocAAMc" = hidden constant
// GLOBAL-SAME: i16 2,
-// GLOBAL-SAME: i16 0,
+// GLOBAL-SAME: i16 1,
// Relative reference to instantiator function
// GLOBAL-SAME: i32 trunc (i64 sub (i64 ptrtoint (void (i8**, %swift.type*, i8**)* @"$s23associated_type_witness15GenericComputedVyxGAA22DerivedFromSimpleAssocAAWI" to i64),
diff --git a/test/IRGen/class_bounded_generics.swift b/test/IRGen/class_bounded_generics.swift
index 642bc8b..a3ae394 100644
--- a/test/IRGen/class_bounded_generics.swift
+++ b/test/IRGen/class_bounded_generics.swift
@@ -168,7 +168,7 @@
// CHECK: [[T0R:%.*]] = call swiftcc %swift.metadata_response @"$s22class_bounded_generics13ConcreteClassCMa"([[INT]] 0)
// CHECK: [[T0:%.*]] = extractvalue %swift.metadata_response [[T0R]], 0
// CHECK: [[T1:%.*]] = bitcast %swift.type* [[T0]] to i8*
- // CHECK: [[OUT_PTR:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[IN_PTR]], i8* [[T1]])
+ // CHECK: [[OUT_PTR:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[IN_PTR]], i8* [[T1]], {{.*}})
// CHECK: [[OUT:%.*]] = bitcast i8* [[OUT_PTR]] to %T22class_bounded_generics13ConcreteClassC*
// CHECK: ret %T22class_bounded_generics13ConcreteClassC* [[OUT]]
}
@@ -180,7 +180,7 @@
// CHECK: [[T0R:%.*]] = call swiftcc %swift.metadata_response @"$s22class_bounded_generics13ConcreteClassCMa"([[INT]] 0)
// CHECK: [[T0:%.*]] = extractvalue %swift.metadata_response [[T0R]], 0
// CHECK: [[T1:%.*]] = bitcast %swift.type* [[T0]] to i8*
- // CHECK: [[OUT_PTR:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[IN_PTR]], i8* [[T1]])
+ // CHECK: [[OUT_PTR:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[IN_PTR]], i8* [[T1]], {{.*}})
// CHECK: [[OUT:%.*]] = bitcast i8* [[OUT_PTR]] to %T22class_bounded_generics13ConcreteClassC*
// CHECK: ret %T22class_bounded_generics13ConcreteClassC* [[OUT]]
}
diff --git a/test/IRGen/deserialize-clang-importer-witness-tables.swift b/test/IRGen/deserialize-clang-importer-witness-tables.swift
index 1615700..e5388bd 100644
--- a/test/IRGen/deserialize-clang-importer-witness-tables.swift
+++ b/test/IRGen/deserialize-clang-importer-witness-tables.swift
@@ -9,8 +9,8 @@
// from the default argument expression passed to `RegEx(pattern:options:)`
// below. Ensure that a local copy of the definition was deserialized
// and lowered to IR.
- // CHECK-LABEL: define {{.*}} void @"$sSo26NSRegularExpressionOptionsVs10SetAlgebraSCsACPxycfCTW"
// CHECK-LABEL: define {{.*}} i8** @"$sSo26NSRegularExpressionOptionsVABSQSCWl"()
+ // CHECK-LABEL: define {{.*}} void @"$sSo26NSRegularExpressionOptionsVs10SetAlgebraSCsACPxycfCTW"
let versionRegex = try! RegEx(pattern: "Apple")
_ = versionRegex.firstMatch(in: line)
}
diff --git a/test/IRGen/newtype.swift b/test/IRGen/newtype.swift
index 31fac5b..0353421 100644
--- a/test/IRGen/newtype.swift
+++ b/test/IRGen/newtype.swift
@@ -8,8 +8,8 @@
// REQUIRES: objc_interop
-// Witness table for synthesized ClosedEnums : _ObjectiveCBridgeable.
-// CHECK: @"$sSo13SNTClosedEnumas21_ObjectiveCBridgeableSCWp" = linkonce_odr
+// Conformance descriptor for synthesized ClosedEnums : _ObjectiveCBridgeable.
+// CHECK: @"$sSo13SNTClosedEnumas21_ObjectiveCBridgeableSCMc" =
// CHECK-LABEL: define swiftcc %TSo8NSStringC* @"$s7newtype14getErrorDomainSo08SNTErrorD0ayF"()
public func getErrorDomain() -> ErrorDomain {
diff --git a/test/IRGen/objc_casts.sil b/test/IRGen/objc_casts.sil
index 71f6fe9..57c2897 100644
--- a/test/IRGen/objc_casts.sil
+++ b/test/IRGen/objc_casts.sil
@@ -15,7 +15,7 @@
// CHECK-LABEL: define hidden swiftcc %TSo8NSObjectC* @checkedClassBoundCast(%swift.type*, %TSo8NSObjectC*, %swift.type* %T) #0 {
// CHECK: [[OPAQUE_OBJ:%.+]] = bitcast %TSo8NSObjectC* %1 to i8*
// CHECK: [[OPAQUE_CLASS:%.+]] = bitcast %swift.type* %T to i8*
-// CHECK: [[OPAQUE_RESULT:%.+]] = call i8* @swift_dynamicCastUnknownClassUnconditional(i8* [[OPAQUE_OBJ]], i8* [[OPAQUE_CLASS]])
+// CHECK: [[OPAQUE_RESULT:%.+]] = call i8* @swift_dynamicCastUnknownClassUnconditional(i8* [[OPAQUE_OBJ]], i8* [[OPAQUE_CLASS]], {{.*}})
// CHECK: [[RESULT:%.+]] = bitcast i8* [[OPAQUE_RESULT]] to %TSo8NSObjectC*
// CHECK: ret %TSo8NSObjectC* [[RESULT]]
// CHECK: {{^}$}}
@@ -30,13 +30,13 @@
// rdar://24924966
// CHECK-LABEL: define hidden swiftcc void @metatype_to_objc_class(%swift.type*, %swift.type* %T)
-// CHECK: [[T0:%.*]] = call %objc_object* @swift_dynamicCastMetatypeToObjectUnconditional(%swift.type* %0)
+// CHECK: [[T0:%.*]] = call %objc_object* @swift_dynamicCastMetatypeToObjectUnconditional(%swift.type* %0, {{.*}})
// TODO: is this really necessary? also, this really shouldn't use a direct reference
// CHECK-NEXT: [[T1:%.*]] = bitcast %objc_object* [[T0]] to i8*
// CHECK-NEXT: [[T2a:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_Foo"
// CHECK-NEXT: [[T2:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T2a]])
// CHECK-NEXT: [[T3:%.*]] = bitcast %objc_class* [[T2]] to i8*
-// CHECK-NEXT: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[T1]], i8* [[T3]])
+// CHECK-NEXT: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[T1]], i8* [[T3]], {{.*}})
sil hidden @metatype_to_objc_class : $@convention(thin) <T> (@thick T.Type) -> () {
bb0(%metatype : $@thick T.Type):
%result = unconditional_checked_cast %metatype : $@thick T.Type to $Foo
@@ -46,13 +46,13 @@
// CHECK-LABEL: define hidden swiftcc void @opt_metatype_to_objc_class({{(i32|i64)}}, %swift.type* %T)
// CHECK: [[ARG:%.*]] = inttoptr {{.*}} %0 to %swift.type*
-// CHECK: [[T0:%.*]] = call %objc_object* @swift_dynamicCastMetatypeToObjectUnconditional(%swift.type* [[ARG]])
+// CHECK: [[T0:%.*]] = call %objc_object* @swift_dynamicCastMetatypeToObjectUnconditional(%swift.type* [[ARG]], {{.*}})
// TODO: is this really necessary? also, this really shouldn't use a direct reference
// CHECK-NEXT: [[T1:%.*]] = bitcast %objc_object* [[T0]] to i8*
// CHECK-NEXT: [[T2a:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_Foo"
// CHECK-NEXT: [[T2:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T2a]])
// CHECK-NEXT: [[T3:%.*]] = bitcast %objc_class* [[T2]] to i8*
-// CHECK-NEXT: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[T1]], i8* [[T3]])
+// CHECK-NEXT: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[T1]], i8* [[T3]], {{.*}})
sil hidden @opt_metatype_to_objc_class : $@convention(thin) <T> (Optional<@thick T.Type>) -> () {
bb0(%metatype : $Optional<@thick T.Type>):
%result = unconditional_checked_cast %metatype : $Optional<@thick T.Type> to $Foo
diff --git a/test/IRGen/objc_extensions.swift b/test/IRGen/objc_extensions.swift
index 0bd9458..23279fa 100644
--- a/test/IRGen/objc_extensions.swift
+++ b/test/IRGen/objc_extensions.swift
@@ -180,7 +180,7 @@
@NSManaged var woof: Int
}
-// CHECK: @"$sSo8NSObjectC15objc_extensionsE8SomeEnum33_1F05E59585E0BB585FCA206FBFF1A92DLLOSQACWp" =
+// CHECK: @"$sSo8NSObjectC15objc_extensionsE8SomeEnum33_1F05E59585E0BB585FCA206FBFF1A92DLLOSQACMc" =
class SwiftSubGizmo : SwiftBaseGizmo {
diff --git a/test/IRGen/protocol_conformance_records.swift b/test/IRGen/protocol_conformance_records.swift
index 984a5ef..2b6bba3 100644
--- a/test/IRGen/protocol_conformance_records.swift
+++ b/test/IRGen/protocol_conformance_records.swift
@@ -119,7 +119,7 @@
// -- nominal type descriptor
// CHECK-SAME: @"{{got.|__imp_}}$sSiMn"
// -- witness table pattern
-// CHECK-SAME: @"$sSi18resilient_protocol22OtherResilientProtocol0B20_conformance_recordsWp"
+// CHECK-SAME: i32 0,
// -- flags
// CHECK-SAME: i32 131144,
// -- module context for retroactive conformance
diff --git a/test/IRGen/protocol_resilience.sil b/test/IRGen/protocol_resilience.sil
index 0f00109..d4b8955 100644
--- a/test/IRGen/protocol_resilience.sil
+++ b/test/IRGen/protocol_resilience.sil
@@ -78,24 +78,15 @@
func f()
}
-// Generic witness table pattern for ConformsWithRequirements : ProtocolWithRequirements
+// No generic witness table pattern for ConformsWithRequirements : ProtocolWithRequirements; it's all resilient
-// CHECK: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp" =
-
-// CHECK-SAME: internal global [1 x i8*] [
-
-// -- conformance descriptor
-// CHECK-SAME: "$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAMc"
-
-// CHECK-SAME: ]
+// CHECK-NOT: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp" =
-// Witness table pattern for conformance with resilient associated type
+// No witness table pattern for conformance with resilient associated type
-// CHECK: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWp" = {{(protected )?}}internal global [3 x i8*] [
-// CHECK-SAME: @"associated conformance 19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AA1TAaDP_010resilient_A005OtherE8Protocol"
-// CHECK-SAME: @"symbolic 19protocol_resilience23ResilientConformingTypeV"
-// CHECK-SAME: ]
+// CHECK-NOT: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWp" = {{(protected )?}}internal
+
// Protocol conformance descriptor for ResilientConformingType : OtherResilientProtocol
@@ -104,7 +95,7 @@
// CHECK-SAME: i32 131072,
// -- number of witness table entries
-// CHECK-SAME: i16 1,
+// CHECK-SAME: i16 0,
// -- size of private area + 'requires instantiation' bit (not set)
// CHECK-SAME: i16 0,
@@ -134,7 +125,7 @@
// CHECK-SAME: @secondWitness
// -- number of witness table entries
-// CHECK-SAME: i16 1,
+// CHECK-SAME: i16 0,
// -- size of private area + 'requires instantiation' bit (not set)
// CHECK-SAME: i16 0,
diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift
index 883f374..388071f 100644
--- a/test/IRGen/protocol_resilience_descriptors.swift
+++ b/test/IRGen/protocol_resilience_descriptors.swift
@@ -29,6 +29,9 @@
// Protocol requirements base descriptor
// CHECK-DEFINITION: @"$s18resilient_protocol21ResilientBaseProtocolTL" ={{( dllexport)?}}{{( protected)?}} alias %swift.protocol_requirement, getelementptr (%swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds (<{ i32, i32, i32, i32, i32, i32, %swift.protocol_requirement }>, <{ i32, i32, i32, i32, i32, i32, %swift.protocol_requirement }>* @"$s18resilient_protocol21ResilientBaseProtocolMp", i32 0, i32 6), i32 -1)
+// Associated conformance descriptor for inherited protocol
+// CHECK-DEFINITION-LABEL: s18resilient_protocol24ResilientDerivedProtocolPAA0c4BaseE0Tb" ={{( dllexport)?}}{{( protected)?}} alias
+
// Associated type and conformance
// CHECK-DEFINITION: @"$s1T18resilient_protocol24ProtocolWithRequirementsPTl" ={{( dllexport)?}}{{( protected)?}} alias
@@ -58,8 +61,9 @@
// CHECK-USAGE-LABEL: @"$s31protocol_resilience_descriptors1YV010resilient_A022OtherResilientProtocolAAMc" =
// CHECK-USAGE-SAME: i32 131072,
-// CHECK-USAGE-SAME: i16 1,
-// CHECK-USAGE-SAME: i16 0
+// CHECK-USAGE-SAME: i16 0,
+// CHECK-USAGE-SAME: i16 0,
+// CHECK-USAGE-SAME: i32 0
extension Y: OtherResilientProtocol { }
// CHECK-USAGE: @"$s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAAMc" =
@@ -76,6 +80,12 @@
public func second() { }
}
+// CHECK-USAGE: @"$s31protocol_resilience_descriptors17ConformsToDerivedV010resilient_A009ResilientF8ProtocolAAMc" =
+// CHECK-SAME: @"associated conformance 31protocol_resilience_descriptors17ConformsToDerivedV010resilient_A009ResilientF8ProtocolAaD0h4BaseI0"
+public struct ConformsToDerived : ResilientDerivedProtocol {
+ public func requirement() -> Int { return 0 }
+}
+
// ----------------------------------------------------------------------------
// Resilient protocol usage
// ----------------------------------------------------------------------------
diff --git a/test/IRGen/protocol_with_superclass.sil b/test/IRGen/protocol_with_superclass.sil
index 172e9c8..effacd4 100644
--- a/test/IRGen/protocol_with_superclass.sil
+++ b/test/IRGen/protocol_with_superclass.sil
@@ -104,7 +104,7 @@
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s24protocol_with_superclass7DerivedCMa"(i{{[0-9]+}} 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
- // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]])
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]], {{.*}})
// CHECK-NEXT: [[REFERENCE:%.*]] = bitcast i8* [[RESULT]] to %T24protocol_with_superclass7DerivedC*
%11 = unconditional_checked_cast %3 : $ProtoRefinesClass to $Derived
@@ -115,7 +115,7 @@
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s24protocol_with_superclass10SubDerivedCMa"(i{{[0-9]+}} 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
- // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]])
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]], {{.*}})
// CHECK-NEXT: [[REFERENCE:%.*]] = bitcast i8* [[RESULT]] to %T24protocol_with_superclass10SubDerivedC*
%12 = unconditional_checked_cast %3 : $ProtoRefinesClass to $SubDerived
@@ -150,7 +150,7 @@
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s24protocol_with_superclass11MoreDerivedCMa"(i{{[0-9]+}} 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
- // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]])
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]], {{.*}})
// CHECK-NEXT: [[REFERENCE:%.*]] = bitcast i8* [[RESULT]] to %T24protocol_with_superclass11MoreDerivedC*
%15 = unconditional_checked_cast %4 : $SubProto to $MoreDerived
diff --git a/test/IRGen/protocol_with_superclass_where_clause.sil b/test/IRGen/protocol_with_superclass_where_clause.sil
index acad2e9..c223fbe 100644
--- a/test/IRGen/protocol_with_superclass_where_clause.sil
+++ b/test/IRGen/protocol_with_superclass_where_clause.sil
@@ -104,7 +104,7 @@
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s24protocol_with_superclass7DerivedCMa"(i{{[0-9]+}} 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
- // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]])
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]], {{.*}})
// CHECK-NEXT: [[REFERENCE:%.*]] = bitcast i8* [[RESULT]] to %T24protocol_with_superclass7DerivedC*
%11 = unconditional_checked_cast %3 : $ProtoRefinesClass to $Derived
@@ -115,7 +115,7 @@
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s24protocol_with_superclass10SubDerivedCMa"(i{{[0-9]+}} 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
- // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]])
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]], {{.*}})
// CHECK-NEXT: [[REFERENCE:%.*]] = bitcast i8* [[RESULT]] to %T24protocol_with_superclass10SubDerivedC*
%12 = unconditional_checked_cast %3 : $ProtoRefinesClass to $SubDerived
@@ -150,7 +150,7 @@
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s24protocol_with_superclass11MoreDerivedCMa"(i{{[0-9]+}} 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
- // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]])
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[OBJECT]], i8* [[METADATA_PTR]], {{.*}})
// CHECK-NEXT: [[REFERENCE:%.*]] = bitcast i8* [[RESULT]] to %T24protocol_with_superclass11MoreDerivedC*
%15 = unconditional_checked_cast %4 : $SubProto to $MoreDerived
diff --git a/test/IRGen/subclass_existentials.sil b/test/IRGen/subclass_existentials.sil
index 28d2b42..488bc1a 100644
--- a/test/IRGen/subclass_existentials.sil
+++ b/test/IRGen/subclass_existentials.sil
@@ -112,7 +112,7 @@
// CHECK-NEXT: [[VALUE:%.*]] = bitcast %T21subclass_existentials1CC* %1 to i8*
// CHECK-NEXT: [[CLASS_ADDR:%.*]] = bitcast %swift.type* [[SUPERCLASS]] to i8*
-// CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[VALUE]], i8* [[CLASS_ADDR]])
+// CHECK-NEXT: [[RESULT:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[VALUE]], i8* [[CLASS_ADDR]], {{.*}})
// CHECK-NEXT: [[VALUE:%.*]] = bitcast i8* [[RESULT]] to %T21subclass_existentials1DC*
%3 = unconditional_checked_cast %1 : $C & P to $D
@@ -193,7 +193,7 @@
// CHECK-NEXT: [[WTABLE:%.*]] = extractvalue { i8*, i8** } [[RESULT]], 1
%2 = unconditional_checked_cast %0 : $@thick C.Type to $@thick (D & R).Type
-// CHECK-NEXT: [[RESULT:%.*]] = call %swift.type* @swift_dynamicCastMetatypeUnconditional(%swift.type* %1, %swift.type* [[SUPERCLASS]])
+// CHECK-NEXT: [[RESULT:%.*]] = call %swift.type* @swift_dynamicCastMetatypeUnconditional(%swift.type* %1, %swift.type* [[SUPERCLASS]], {{.*}})
%3 = unconditional_checked_cast %1 : $@thick (C & P).Type to $@thick D.Type
// CHECK-NEXT: ret void
diff --git a/test/IRGen/unconditional_checked_cast.sil b/test/IRGen/unconditional_checked_cast.sil
index ad96c9a..fbe49cb 100644
--- a/test/IRGen/unconditional_checked_cast.sil
+++ b/test/IRGen/unconditional_checked_cast.sil
@@ -17,7 +17,7 @@
// CHECK-NEXT: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s26unconditional_checked_cast1DCMa"(i64 0)
// CHECK-NEXT: [[T0:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
// CHECK-NEXT: [[T1:%.*]] = bitcast %swift.type* [[T0]] to i8*
-// CHECK-NEXT: [[I8RESULTPTR:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[I8INPUTPTR]], i8* [[T1]])
+// CHECK-NEXT: [[I8RESULTPTR:%.*]] = call i8* @swift_dynamicCastClassUnconditional(i8* [[I8INPUTPTR]], i8* [[T1]], {{.*}})
// CHECK-NEXT: [[DOWNCASTINPUTPTR:%[0-9]+]] = bitcast i8* [[I8RESULTPTR]] to %T26unconditional_checked_cast1DC*
// CHECK-NEXT: store %T26unconditional_checked_cast1DC* [[DOWNCASTINPUTPTR]], %T26unconditional_checked_cast1DC** {{%[0-9]+}}, align 8
// CHECK-NEXT: ret void
diff --git a/test/Inputs/conditional_conformance_basic_conformances.swift b/test/Inputs/conditional_conformance_basic_conformances.swift
index 67facc1..06cc820 100644
--- a/test/Inputs/conditional_conformance_basic_conformances.swift
+++ b/test/Inputs/conditional_conformance_basic_conformances.swift
@@ -238,44 +238,6 @@
// CHECK-NEXT: }
-// # Witness table instantiators
-
-// witness table instantiator for Single : P1
-
-// CHECK-LABEL: define internal void @"$s42conditional_conformance_basic_conformances6SingleVyxGAA2P1A2A2P2RzlWI"(i8**, %swift.type* %"Single<A>", i8**)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TABLES:%.*]] = bitcast i8** %1 to i8***
-
-// CHECK-NEXT: [[A_P2_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 0
-// CHECK-NEXT: [[A_P2_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -1
-// CHECK-NEXT: [[A_P2:%.*]] = load i8**, i8*** [[A_P2_SRC]], align 8
-// CHECK-NEXT: [[CAST_A_P2_DEST:%.*]] = bitcast i8** [[A_P2_DEST]] to i8***
-// CHECK-NEXT: store i8** [[A_P2]], i8*** [[CAST_A_P2_DEST]], align 8
-
-// CHECK-NEXT: ret void
-// CHECK-NEXT: }
-
-// witness table instantiator for Double : P1
-
-// CHECK-LABEL: define internal void @"$s42conditional_conformance_basic_conformances6DoubleVyxq_GAA2P1A2A2P2RzAA2P3R_rlWI"(i8**, %swift.type* %"Double<B, C>", i8**)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TABLES:%.*]] = bitcast i8** %1 to i8***
-
-// CHECK-NEXT: [[B_P2_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 0
-// CHECK-NEXT: [[B_P2_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -1
-// CHECK-NEXT: [[B_P2:%.*]] = load i8**, i8*** [[B_P2_SRC]], align 8
-// CHECK-NEXT: [[CAST_B_P2_DEST:%.*]] = bitcast i8** [[B_P2_DEST]] to i8***
-// CHECK-NEXT: store i8** [[B_P2]], i8*** [[CAST_B_P2_DEST]], align 8
-
-// CHECK-NEXT: [[C_P3_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 1
-// CHECK-NEXT: [[C_P3_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -2
-// CHECK-NEXT: [[C_P3:%.*]] = load i8**, i8*** [[C_P3_SRC]], align 8
-// CHECK-NEXT: [[CAST_C_P3_DEST:%.*]] = bitcast i8** [[C_P3_DEST]] to i8***
-// CHECK-NEXT: store i8** [[C_P3]], i8*** [[CAST_C_P3_DEST]], align 8
-
-// CHECK-NEXT: ret void
-// CHECK-NEXT: }
-
func dynamicCastToP1(_ value: Any) -> P1? {
return value as? P1
}
diff --git a/test/Inputs/conditional_conformance_recursive.swift b/test/Inputs/conditional_conformance_recursive.swift
index e7dfcc7..fab1de6 100644
--- a/test/Inputs/conditional_conformance_recursive.swift
+++ b/test/Inputs/conditional_conformance_recursive.swift
@@ -18,11 +18,6 @@
extension Wrapper: P3 where T: P3 { }
-// instantiation function for Wrapper<T>: P3
-// CHECK-LABEL: define internal void @"$s33conditional_conformance_recursive7WrapperVyxGAA2P3A2aERzrlWI"
-// CHECK-NOT: ret
-// CHECK: call i8** @swift_getWitnessTable
-
// associated type witness table accessor for A : P2 in Wrapper<T>: P2
// CHECK-LABEL: define internal swiftcc i8** @"$s33conditional_conformance_recursive7WrapperVyxGAA2P2A2aERzrl1A_AaEPWT"
// CHECK: [[CONDITIONAL_REQ_BUFFER:%.*]] = alloca [1 x i8**]
diff --git a/test/Inputs/conditional_conformance_subclass.swift b/test/Inputs/conditional_conformance_subclass.swift
index 0febe9c..f3c6c26 100644
--- a/test/Inputs/conditional_conformance_subclass.swift
+++ b/test/Inputs/conditional_conformance_subclass.swift
@@ -166,21 +166,3 @@
// CHECK-NEXT: [[T0:%.*]] = phi i8** [ [[CACHE]], %entry ], [ [[Base_P1]], %cacheIsNull ]
// CHECK-NEXT: ret i8** [[T0]]
// CHECK-NEXT: }
-
-
-// witness tabel instantiation function for Base : P1
-
-// CHECK-LABEL: define internal void @"$s32conditional_conformance_subclass4BaseCyxGAA2P1A2A2P2RzlWI"(i8**, %swift.type* %"Base<A>", i8**)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TABLES:%.*]] = bitcast i8** %1 to i8***
-
-// CHECK-NEXT: [[A_P2_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 0
-// CHECK-NEXT: [[A_P2_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -1
-// CHECK-NEXT: [[A_P2:%.*]] = load i8**, i8*** [[A_P2_SRC]], align 8
-// CHECK-NEXT: [[CAST_A_P2_DEST:%.*]] = bitcast i8** [[A_P2_DEST]] to i8***
-// CHECK-NEXT: store i8** [[A_P2]], i8*** [[CAST_A_P2_DEST]], align 8
-
-// CHECK-NEXT: ret void
-// CHECK-NEXT: }
-
-
diff --git a/test/Inputs/conditional_conformance_with_assoc.swift b/test/Inputs/conditional_conformance_with_assoc.swift
index 7ec5f6c..23a3009 100644
--- a/test/Inputs/conditional_conformance_with_assoc.swift
+++ b/test/Inputs/conditional_conformance_with_assoc.swift
@@ -220,33 +220,6 @@
-// witness table instantiator for Double : P1
-
-// CHECK-LABEL: define internal void @"$s34conditional_conformance_with_assoc6DoubleVyxq_GAA2P1A2A2P3R_AA2P23AT2RpzAafH_AhaGP3AT3RPzrlWI"(i8**, %swift.type* %"Double<B, C>", i8**)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TABLES:%.*]] = bitcast i8** %1 to i8***
-
-// CHECK-NEXT: [[C_P3_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 0
-// CHECK-NEXT: [[C_P3_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -1
-// CHECK-NEXT: [[C_P3:%.*]] = load i8**, i8*** [[C_P3_SRC]], align 8
-// CHECK-NEXT: [[CAST_C_P3_DEST:%.*]] = bitcast i8** [[C_P3_DEST]] to i8***
-// CHECK-NEXT: store i8** [[C_P3]], i8*** [[CAST_C_P3_DEST]], align 8
-
-// CHECK-NEXT: [[B_AT2_P2_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 1
-// CHECK-NEXT: [[B_AT2_P2_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -2
-// CHECK-NEXT: [[B_AT2_P2:%.*]] = load i8**, i8*** [[B_AT2_P2_SRC]], align 8
-// CHECK-NEXT: [[CAST_B_AT2_P2_DEST:%.*]] = bitcast i8** [[B_AT2_P2_DEST]] to i8***
-// CHECK-NEXT: store i8** [[B_AT2_P2]], i8*** [[CAST_B_AT2_P2_DEST]], align 8
-
-// CHECK-NEXT: [[B_AT2_AT2_AT3_P3_SRC:%.*]] = getelementptr inbounds i8**, i8*** [[TABLES]], i32 2
-// CHECK-NEXT: [[B_AT2_AT2_AT3_P3_DEST:%.*]] = getelementptr inbounds i8*, i8** %0, i32 -3
-// CHECK-NEXT: [[B_AT2_AT2_AT3_P3:%.*]] = load i8**, i8*** [[B_AT2_AT2_AT3_P3_SRC]], align 8
-// CHECK-NEXT: [[CAST_B_AT2_AT2_AT3_P3_DEST:%.*]] = bitcast i8** [[B_AT2_AT2_AT3_P3_DEST]] to i8***
-// CHECK-NEXT: store i8** [[B_AT2_AT2_AT3_P3]], i8*** [[CAST_B_AT2_AT2_AT3_P3_DEST]], align 8
-
-// CHECK-NEXT: ret void
-// CHECK-NEXT: }
-
protocol Base {
}
@@ -261,13 +234,3 @@
extension X: Sub where T: Sub, T.S == T {
typealias S = X<T>
}
-
-// Make sure we can recover the type metadata from X<T>.Type.
-// CHECK: define internal void @"$s34conditional_conformance_with_assoc1XVyxGAA3SubA2aERz1SQzRszlWI"(i8**, %swift.type* %"X<T>", i8**)
-// CHECK: entry:
-// CHECK: [[XT_TYPE:%.*]] = bitcast %swift.type* %"X<T>" to %swift.type**
-// CHECK: [[ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[XT_TYPE]], i64 2
-// CHECK: [[T:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
-// CHECK: %T.Base = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** {{.*}}, %swift.type* %T, %swift.type* %T
-// CHECK: ret void
-// CHECK: }
diff --git a/test/SILOptimizer/closure_specialize.sil b/test/SILOptimizer/closure_specialize.sil
index dfd4c72..e50ec5f 100644
--- a/test/SILOptimizer/closure_specialize.sil
+++ b/test/SILOptimizer/closure_specialize.sil
@@ -478,6 +478,46 @@
return %7 : $()
}
+// Check that we don't crash with this:
+// CHECK-LABEL: sil @test_box_with_named_elements_tuple
+sil @test_box_with_named_elements_tuple: $@convention(thin) () -> Builtin.Int32 {
+bb0:
+ %0 = alloc_box ${ let (first: Builtin.Int32, second: Builtin.Int32) }
+ %0p = project_box %0 : ${ let (first: Builtin.Int32, second: Builtin.Int32) }, 0
+ %0a = tuple_element_addr %0p : $*(first: Builtin.Int32, second: Builtin.Int32), 0
+ %0b = tuple_element_addr %0p : $*(first: Builtin.Int32, second: Builtin.Int32), 1
+ %1 = integer_literal $Builtin.Int32, 0
+ store %1 to %0a : $*Builtin.Int32
+ store %1 to %0b : $*Builtin.Int32
+ %4 = function_ref @closure_with_named_elements_tuple : $@convention(thin) (Builtin.Int32, @owned { let (first: Builtin.Int32, second: Builtin.Int32) }) -> ()
+ strong_retain %0 : ${ let (first: Builtin.Int32, second: Builtin.Int32) }
+ %6 = partial_apply %4(%0) : $@convention(thin) (Builtin.Int32, @owned { let (first: Builtin.Int32, second: Builtin.Int32) }) -> ()
+ %7 = alloc_stack $Builtin.Int32
+ %9 = integer_literal $Builtin.Int32, 1
+ store %9 to %7 : $*Builtin.Int32
+ %12 = function_ref @$s4main5inneryys5Int32Vz_yADctF: $@convention(thin) (@inout Builtin.Int32, @owned @callee_owned (Builtin.Int32) -> ()) -> ()
+ strong_retain %6 : $@callee_owned (Builtin.Int32) -> ()
+ %14 = apply %12(%7, %6) : $@convention(thin) (@inout Builtin.Int32, @owned @callee_owned (Builtin.Int32) -> ()) -> ()
+ strong_release %6 : $@callee_owned (Builtin.Int32) -> ()
+ %16 = tuple ()
+ dealloc_stack %7 : $*Builtin.Int32
+ %18 = load %0a : $*Builtin.Int32
+ strong_release %0 : ${ let (first: Builtin.Int32, second: Builtin.Int32) }
+ return %18 : $Builtin.Int32
+}
+
+// CHECK-LABEL: sil shared @closure_with_named_elements_tuple
+sil shared @closure_with_named_elements_tuple : $@convention(thin) (Builtin.Int32, @owned { let (first: Builtin.Int32, second: Builtin.Int32) }) -> () {
+bb0(%0 : $Builtin.Int32, %1 : ${ let (first: Builtin.Int32, second: Builtin.Int32) }):
+ %3 = project_box %1 : ${ let (first: Builtin.Int32, second: Builtin.Int32) }, 0
+ %4 = tuple_element_addr %3 : $*(first: Builtin.Int32, second: Builtin.Int32), 0
+ store %0 to %4 : $*Builtin.Int32
+ strong_release %1 : ${ let (first: Builtin.Int32, second: Builtin.Int32) }
+ %7 = tuple ()
+ return %7 : $()
+}
+
+
// The specialized function should always be a thin function, regardless of the
// representation of the original function.
diff --git a/test/attr/attr_inlinable.swift b/test/attr/attr_inlinable.swift
index fb45443..5de1f21 100644
--- a/test/attr/attr_inlinable.swift
+++ b/test/attr/attr_inlinable.swift
@@ -1,7 +1,7 @@
-// RUN: %target-typecheck-verify-swift -swift-version 4.2
-// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-testing
-// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience
-// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience -enable-testing
+// RUN: %target-typecheck-verify-swift -swift-version 5
+// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-testing
+// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-resilience
+// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-resilience -enable-testing
@inlinable struct TestInlinableStruct {}
// expected-error@-1 {{'@inlinable' attribute cannot be applied to this declaration}}
@@ -157,7 +157,7 @@
case apple
case orange
case pear(InternalEnum)
- // expected-warning@-1 {{type of enum case in '@usableFromInline' enum should be '@usableFromInline' or public}}
+ // expected-error@-1 {{type of enum case in '@usableFromInline' enum must be '@usableFromInline' or public}}
case persimmon(String)
}
@@ -248,3 +248,22 @@
// expected-error@-1 {{property 'x' is internal and cannot be referenced from an '@inlinable' function}}
}
}
+
+public struct HasInternalSetProperty {
+ public internal(set) var x: Int // expected-note {{setter for 'x' is not '@usableFromInline' or public}}
+
+ @inlinable public mutating func setsX() {
+ x = 10 // expected-error {{setter for 'x' is internal and cannot be referenced from an '@inlinable' function}}
+ }
+}
+
+@usableFromInline protocol P {
+ typealias T = Int
+}
+
+extension P {
+ @inlinable func f() {
+ _ = T.self // ok, typealias inherits @usableFromInline from P
+ }
+}
+
diff --git a/test/decl/protocol/conforms/circular_validation.swift b/test/decl/protocol/conforms/circular_validation.swift
new file mode 100644
index 0000000..ecb234e
--- /dev/null
+++ b/test/decl/protocol/conforms/circular_validation.swift
@@ -0,0 +1,13 @@
+// RUN: %target-typecheck-verify-swift
+
+// With a bit of effort, we could make this work -- but for now, let's just
+// not crash.
+
+protocol P {
+ var x: Int { get set } // expected-note {{protocol requires property 'x' with type 'Int'; do you want to add a stub?}}
+}
+
+struct S : P { // expected-error {{type 'S' does not conform to protocol 'P'}}
+ static var x = 0 // expected-note {{candidate operates on a type, not an instance as required}}
+ var x = S.x // expected-note {{candidate references itself}}
+}
diff --git a/test/stdlib/AnyHashableCasts.swift.gyb b/test/stdlib/AnyHashableCasts.swift.gyb
index ad5cd2f..4500018 100644
--- a/test/stdlib/AnyHashableCasts.swift.gyb
+++ b/test/stdlib/AnyHashableCasts.swift.gyb
@@ -79,10 +79,16 @@
("AnyHashable(5)", "Any", "Int", "5"),
("HashableStruct(value: 5)", "HashableStruct", "AnyHashable",
"AnyHashable(HashableStruct(value: 5))"),
+ ("HashableStruct(value: 5)", "AnyHashable", "HashableStruct",
+ "AnyHashable(HashableStruct(value: 5))"),
("HashableClass(value: 5)", "HashableClass", "AnyHashable",
"AnyHashable(HashableClass(value: 5))"),
+ ("HashableClass(value: 5)", "AnyHashable", "HashableClass",
+ "AnyHashable(HashableClass(value: 5))"),
("HashableEnum.value(5)", "HashableEnum", "AnyHashable",
"AnyHashable(HashableEnum.value(5))"),
+ ("HashableEnum.value(5)", "AnyHashable", "HashableEnum",
+ "AnyHashable(HashableEnum.value(5))"),
]
}%
diff --git a/test/stdlib/Runtime.swift.gyb b/test/stdlib/Runtime.swift.gyb
index 01ab281..938137f 100644
--- a/test/stdlib/Runtime.swift.gyb
+++ b/test/stdlib/Runtime.swift.gyb
@@ -666,6 +666,18 @@
}
+class C: Q1 & Codable { }
+
+Reflection.test("multiprotocolTypes") {
+ // [SR-8158]: Printing type(of: Codable & Protocol type ) EXC_BAD_ACCESS
+ // This use of String(reflecting:) exercises a previously incorrect cast in
+ // NonFixedExistentialMetatypeBox::Container::getNumWitnessTables.
+ let obj: Q1 & Codable = C()
+ let t = type(of: obj)
+ let x = String(reflecting: t)
+ expectEqual("a.C", x)
+}
+
var BitTwiddlingTestSuite = TestSuite("BitTwiddling")
diff --git a/unittests/runtime/CompatibilityOverride.cpp b/unittests/runtime/CompatibilityOverride.cpp
index 953e655..456711f 100644
--- a/unittests/runtime/CompatibilityOverride.cpp
+++ b/unittests/runtime/CompatibilityOverride.cpp
@@ -98,7 +98,7 @@
}
TEST_F(CompatibilityOverrideTest, test_swift_dynamicCastClassUnconditional) {
- auto Result = swift_dynamicCastClassUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastClassUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}
@@ -108,7 +108,7 @@
}
TEST_F(CompatibilityOverrideTest, test_swift_dynamicCastObjCClassUnconditional) {
- auto Result = swift_dynamicCastObjCClassUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastObjCClassUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}
@@ -118,7 +118,7 @@
}
TEST_F(CompatibilityOverrideTest, test_swift_dynamicCastForeignClassUnconditional) {
- auto Result = swift_dynamicCastForeignClassUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastForeignClassUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}
@@ -128,7 +128,7 @@
}
TEST_F(CompatibilityOverrideTest, test_swift_dynamicCastUnknownClassUnconditional) {
- auto Result = swift_dynamicCastUnknownClassUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastUnknownClassUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}
@@ -138,7 +138,7 @@
}
TEST_F(CompatibilityOverrideTest, test_swift_dynamicCastMetatypeUnconditional) {
- auto Result = swift_dynamicCastMetatypeUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastMetatypeUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}
@@ -148,7 +148,7 @@
}
TEST_F(CompatibilityOverrideTest, test_swift_dynamicCastObjCClassMetatypeUnconditional) {
- auto Result = swift_dynamicCastObjCClassMetatypeUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastObjCClassMetatypeUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}
@@ -159,7 +159,7 @@
TEST_F(CompatibilityOverrideTest,
test_swift_dynamicCastForeignClassMetatypeUnconditional) {
- auto Result = swift_dynamicCastForeignClassMetatypeUnconditional(nullptr, nullptr);
+ auto Result = swift_dynamicCastForeignClassMetatypeUnconditional(nullptr, nullptr, nullptr, 0, 0);
ASSERT_EQ(Result, nullptr);
}