Merge pull request #19389 from mikeash/patch-bundleforclass
[Runtime][Foundation] Supplement the class_getImageName patch with a patch to +[NSBundle bundleForClass:] on older "embedded" targets
diff --git a/README.md b/README.md
index 1ebe13d..e7add90 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@
#### macOS
-To build for macOS, you need [Xcode 10 beta 6](https://developer.apple.com/xcode/downloads/).
+To build for macOS, you need [Xcode 10.0](https://developer.apple.com/xcode/downloads/).
The required version of Xcode changes frequently, and is often a beta release.
Check this document or the host information on <https://ci.swift.org> for the
current required version.
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 71a8090..cf33184 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -141,7 +141,8 @@
global ::= protocol 'TL' // protocol requirements base descriptor
global ::= assoc-type-name 'Tl' // associated type descriptor
global ::= assoc-type-name 'TM' // default associated type witness accessor
-
+ global ::= type assoc-type-path protocol 'Tn' // associated conformance descriptor
+ global ::= type assoc-type-path protocol 'TN' // default associated conformance witness accessor
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index ff0ee4a..370dcf8 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -3979,6 +3979,19 @@
/// Record the default witness for a requirement.
void setDefaultWitness(ValueDecl *requirement, Witness witness);
+ /// Returns the default associated conformance witness for an associated
+ /// type, or \c None if there is no default.
+ Optional<ProtocolConformanceRef> getDefaultAssociatedConformanceWitness(
+ CanType association,
+ ProtocolDecl *requirement) const;
+
+ /// Set the default associated conformance witness for the given
+ /// associated conformance.
+ void setDefaultAssociatedConformanceWitness(
+ CanType association,
+ ProtocolDecl *requirement,
+ ProtocolConformanceRef conformance);
+
/// Retrieve the name to use for this protocol when interoperating
/// with the Objective-C runtime.
StringRef getObjCRuntimeName(llvm::SmallVectorImpl<char> &buffer) const;
diff --git a/include/swift/AST/DiagnosticsModuleDiffer.def b/include/swift/AST/DiagnosticsModuleDiffer.def
index c5b0a7d..24adcfb 100644
--- a/include/swift/AST/DiagnosticsModuleDiffer.def
+++ b/include/swift/AST/DiagnosticsModuleDiffer.def
@@ -52,6 +52,12 @@
ERROR(decl_new_attr,none,"%0 is now %1", (StringRef, StringRef))
+ERROR(decl_reorder,none,"%0 in a non-resilient type changes position from %1 to %2", (StringRef, unsigned, unsigned))
+
+ERROR(decl_added,none,"%0 is added to a non-resilient type", (StringRef))
+
+ERROR(default_arg_removed,none,"%0 has removed default argument from %1", (StringRef, StringRef))
+
#ifndef DIAG_NO_UNDEF
# if defined(DIAG)
# undef DIAG
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index e8653c3..d85dd41 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1696,6 +1696,11 @@
NOTE(witness_fix_access,none,
"mark the %0 as '%select{%error|fileprivate|internal|public|%error}1' to "
"satisfy the requirement", (DescriptiveDeclKind, AccessLevel))
+WARNING(assoc_type_default_conformance_failed,none,
+ "default type %0 for associated type %1 does not satisfy constraint "
+ "%2: %3", (Type, DeclName, Type, Type))
+NOTE(assoc_type_default_here,none,
+ "associated type %0 has default type %1 written here", (DeclName, Type))
ERROR(protocol_access,none,
"%select{protocol must be declared %select{"
diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h
index a600fdf..b2911aa 100644
--- a/include/swift/AST/LazyResolver.h
+++ b/include/swift/AST/LazyResolver.h
@@ -63,9 +63,6 @@
/// Resolve the generic environment of the given protocol.
virtual void resolveProtocolEnvironment(ProtocolDecl *proto) = 0;
- /// Bind an extension to its extended type.
- virtual void bindExtension(ExtensionDecl *ext) = 0;
-
/// Resolve the type of an extension.
///
/// This can be called to ensure that the members of an extension can be
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index cb1d6f3..ed283d6 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -211,6 +211,7 @@
NODE(MethodDescriptor)
NODE(ProtocolRequirementsBaseDescriptor)
NODE(AssociatedConformanceDescriptor)
+NODE(DefaultAssociatedConformanceAccessor)
NODE(AssociatedTypeDescriptor)
NODE(ThrowsAnnotation)
NODE(EmptyList)
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 0092af8..f730523 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -100,6 +100,7 @@
KEY(mutating)
KEY(static)
KEY(deprecated)
+KEY(implicit)
KEY(typeAttributes)
KEY(declAttributes)
KEY(declKind)
@@ -109,6 +110,7 @@
KEY(conformingProtocols)
KEY(enumRawTypeName)
KEY(genericSig)
+KEY(fixedbinaryorder)
KNOWN_TYPE(Optional)
KNOWN_TYPE(ImplicitlyUnwrappedOptional)
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index e5d486f..2e99868 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -213,6 +213,11 @@
/// is stored in the data.
AssociatedConformanceDescriptor,
+ /// A default accessor for an associated conformance of a protocol.
+ /// The pointer is a ProtocolDecl*; the index of the associated conformance
+ /// is stored in the data.
+ DefaultAssociatedConformanceAccessor,
+
/// A function which returns the default type metadata for the associated
/// type of a protocol. The secondary pointer is a ProtocolDecl*.
/// The index of the associated type declaration is stored in the data.
@@ -795,14 +800,13 @@
}
static LinkEntity
- forAssociatedConformanceDescriptor(ProtocolDecl *proto,
- CanType associatedType,
- ProtocolDecl *associatedProtocol) {
+ forAssociatedConformanceDescriptor(AssociatedConformance conformance) {
LinkEntity entity;
entity.setForProtocolAndAssociatedConformance(
Kind::AssociatedConformanceDescriptor,
- proto, associatedType,
- associatedProtocol);
+ conformance.getSourceProtocol(),
+ conformance.getAssociation(),
+ conformance.getAssociatedRequirement());
return entity;
}
@@ -835,6 +839,17 @@
return entity;
}
+ static LinkEntity
+ forDefaultAssociatedConformanceAccessor(AssociatedConformance conformance) {
+ LinkEntity entity;
+ entity.setForProtocolAndAssociatedConformance(
+ Kind::DefaultAssociatedConformanceAccessor,
+ conformance.getSourceProtocol(),
+ conformance.getAssociation(),
+ conformance.getAssociatedRequirement());
+ return entity;
+ }
+
static LinkEntity forReflectionBuiltinDescriptor(CanType type) {
LinkEntity entity;
entity.setForType(Kind::ReflectionBuiltinDescriptor, type);
@@ -925,7 +940,8 @@
LINKENTITY_GET_FIELD(Data, AssociatedConformanceIndex));
}
- assert(getKind() == Kind::AssociatedConformanceDescriptor);
+ assert(getKind() == Kind::AssociatedConformanceDescriptor ||
+ getKind() == Kind::DefaultAssociatedConformanceAccessor);
return getAssociatedConformanceByIndex(
cast<ProtocolDecl>(getDecl()),
LINKENTITY_GET_FIELD(Data, AssociatedConformanceIndex));
diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h
index 1942d5e..723bbb9 100644
--- a/include/swift/Serialization/Validation.h
+++ b/include/swift/Serialization/Validation.h
@@ -20,6 +20,7 @@
namespace swift {
+class ModuleFile;
enum class ResilienceStrategy : unsigned;
namespace serialization {
@@ -147,6 +148,24 @@
validateSerializedAST(StringRef data,
ExtendedValidationInfo *extendedInfo = nullptr);
+/// Emit diagnostics explaining a failure to load a serialized AST.
+///
+/// - \p Ctx is an AST context through which any diagnostics are surfaced.
+/// - \p diagLoc is the (possibly invalid) location used in the diagnostics.
+/// - \p loadInfo and \p extendedInfo describe the attempt to load an AST
+/// (\ref validateSerializedAST). Note that loadInfo.Status must not be
+/// Status::Valid.
+/// - \p moduleBufferID and \p moduleDocBufferID are the buffer identifiers
+/// of the module input and doc input buffers respectively (\ref
+/// SerializedModuleLoader::loadAST, \ref ModuleFile::load).
+/// - \p loadedModuleFile is an invalid loaded module.
+/// - \p ModuleName is the name used to refer to the module in diagnostics.
+void diagnoseSerializedASTLoadFailure(
+ ASTContext &Ctx, SourceLoc diagLoc, const ValidationInfo &loadInfo,
+ const ExtendedValidationInfo &extendedInfo, StringRef moduleBufferID,
+ StringRef moduleDocBufferID, ModuleFile *loadedModuleFile,
+ Identifier ModuleName);
+
} // end namespace serialization
} // end namespace swift
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index ea0de37..b0cea9a 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -285,6 +285,11 @@
llvm::DenseMap<std::pair<const ProtocolDecl *, AssociatedTypeDecl *>, Type>
DefaultTypeWitnesses;
+ /// Default associated conformance witnesses for protocols.
+ llvm::DenseMap<std::tuple<const ProtocolDecl *, CanType, ProtocolDecl *>,
+ ProtocolConformanceRef>
+ DefaultAssociatedConformanceWitnesses;
+
/// \brief Structure that captures data that is segregated into different
/// arenas.
struct Arena {
@@ -1709,6 +1714,32 @@
(void)pair;
}
+Optional<ProtocolConformanceRef>
+ProtocolDecl::getDefaultAssociatedConformanceWitness(
+ CanType association,
+ ProtocolDecl *requirement) const {
+ auto &ctx = getASTContext();
+ auto found =
+ ctx.getImpl().DefaultAssociatedConformanceWitnesses.find(
+ std::make_tuple(this, association, requirement));
+ if (found == ctx.getImpl().DefaultAssociatedConformanceWitnesses.end())
+ return None;
+
+ return found->second;
+}
+
+void ProtocolDecl::setDefaultAssociatedConformanceWitness(
+ CanType association,
+ ProtocolDecl *requirement,
+ ProtocolConformanceRef conformance) {
+ auto &ctx = getASTContext();
+ auto pair = ctx.getImpl().DefaultAssociatedConformanceWitnesses.insert(
+ std::make_pair(std::make_tuple(this, association, requirement),
+ conformance));
+ assert(pair.second && "Already have a default associated conformance");
+ (void)pair;
+}
+
bool ASTContext::canImportModule(std::pair<Identifier, SourceLoc> ModulePath) {
// If this module has already been successfully imported, it is importable.
if (getLoadedModule(ModulePath) != nullptr)
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 99b3928..635bb09 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -821,6 +821,11 @@
Options.ExcludeAttrList.push_back(DAK_Final);
}
+ // Don't print 'final' on accessors.
+ if (Options.PrintImplicitAttrs && isa<AccessorDecl>(D)) {
+ Options.ExcludeAttrList.push_back(DAK_Final);
+ }
+
// If the declaration is implicitly @objc, print the attribute now.
if (Options.PrintImplicitAttrs) {
if (auto VD = dyn_cast<ValueDecl>(D)) {
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 925e667..55bbda3 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -92,7 +92,11 @@
const_cast<ProtocolDecl *>(proto)->createGenericParamsIfMissing();
}
- return getGenericParamsOfContext()->getParams().front()
+ auto *genericParams = getGenericParamsOfContext();
+ if (genericParams == nullptr)
+ return nullptr;
+
+ return genericParams->getParams().front()
->getDeclaredInterfaceType()
->castTo<GenericTypeParamType>();
}
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 1ef30d5..699a8b7 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -564,6 +564,9 @@
ASTContext &ctx = proto->getASTContext();
TinyPtrVector<NominalTypeDecl *> result;
+ if (!ext->getGenericParams())
+ return result;
+
for (const auto &req : ext->getGenericParams()->getTrailingRequirements()) {
// We only care about type constraints.
if (req.getKind() != RequirementReprKind::TypeConstraint)
@@ -709,6 +712,7 @@
};
if (Loc.isValid() &&
+ DC->getParentSourceFile() &&
DC->getParentSourceFile()->Kind != SourceFileKind::REPL &&
Ctx.LangOpts.EnableASTScopeLookup) {
// Find the source file in which we are performing the lookup.
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index eafed55..cb3a04c 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -56,7 +56,7 @@
bool ClangImporter::Implementation::isOverAligned(clang::QualType type) {
auto align = getClangASTContext().getTypeAlignInChars(type);
- return align.getQuantity() > MaximumAlignment;
+ return align > clang::CharUnits::fromQuantity(MaximumAlignment);
}
namespace {
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index a41f978..9048834 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -1841,6 +1841,15 @@
protoTy, assocTypePath, requirementTy);
}
+ case 'N': {
+ NodePointer requirementTy = popProtocol();
+ auto assocTypePath = popAssocTypePath();
+ NodePointer protoTy = popNode(Node::Kind::Type);
+ return createWithChildren(
+ Node::Kind::DefaultAssociatedConformanceAccessor,
+ protoTy, assocTypePath, requirementTy);
+ }
+
case 'H':
case 'h': {
auto nodeKind = c == 'H' ? Node::Kind::KeyPathEqualsThunkHelper
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index 50e451b..363d552 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -323,6 +323,7 @@
case Node::Kind::DeclContext:
case Node::Kind::DefaultArgumentInitializer:
case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
+ case Node::Kind::DefaultAssociatedConformanceAccessor:
case Node::Kind::DependentAssociatedTypeRef:
case Node::Kind::DependentGenericSignature:
case Node::Kind::DependentGenericParamCount:
@@ -1564,6 +1565,14 @@
Printer << ": ";
print(Node->getChild(2));
return nullptr;
+ case Node::Kind::DefaultAssociatedConformanceAccessor:
+ Printer << "default associated conformance accessor for ";
+ print(Node->getChild(0));
+ Printer << ".";
+ print(Node->getChild(1));
+ Printer << ": ";
+ print(Node->getChild(2));
+ return nullptr;
case Node::Kind::AssociatedTypeDescriptor:
Printer << "associated type descriptor for ";
print(Node->getChild(0));
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index 2549d1a..e4f08ee 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -888,6 +888,10 @@
Out << "<associated-conformance-descriptor>";
}
+void Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node) {
+ Out << "<default-associated-conformance-descriptor>";
+}
+
void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
Out << "Wt";
mangleChildNodes(node); // protocol conformance, identifier
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index f7ffe88..348b288 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -579,6 +579,11 @@
Buffer << "Tn";
}
+void Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node) {
+ mangleChildNodes(node);
+ Buffer << "TN";
+}
+
void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
mangleChildNodes(node); // protocol conformance, identifier
Buffer << "Wt";
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index ec487ba..23048cd 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -517,7 +517,9 @@
}
FrontendStatsTracer tracer(Context->Stats, "perform-sema");
- Context->LoadedModules[MainModule->getName()] = getMainModule();
+
+ ModuleDecl *mainModule = getMainModule();
+ Context->LoadedModules[mainModule->getName()] = mainModule;
if (Invocation.getInputKind() == InputFileKind::SIL) {
assert(!InputSourceCodeBufferIDs.empty());
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index d48d029..0cc89af 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3389,21 +3389,15 @@
llvm::Constant *IRGenModule::getAddrOfAssociatedConformanceDescriptor(
AssociatedConformance conformance) {
- auto entity = LinkEntity::forAssociatedConformanceDescriptor(
- conformance.getSourceProtocol(),
- conformance.getAssociation(),
- conformance.getAssociatedRequirement());
+ auto entity = LinkEntity::forAssociatedConformanceDescriptor(conformance);
return getAddrOfLLVMVariable(entity, getPointerAlignment(), ConstantInit(),
ProtocolRequirementStructTy, DebugTypeInfo());
}
llvm::GlobalValue *IRGenModule::defineAssociatedConformanceDescriptor(
- ProtocolDecl *proto,
- CanType subject,
- ProtocolDecl *requirement,
- llvm::Constant *definition) {
- auto entity = LinkEntity::forAssociatedConformanceDescriptor(proto, subject,
- requirement);
+ AssociatedConformance conformance,
+ llvm::Constant *definition) {
+ auto entity = LinkEntity::forAssociatedConformanceDescriptor(conformance);
return defineAlias(entity, definition);
}
@@ -3989,6 +3983,25 @@
}
llvm::Function *
+IRGenModule::getAddrOfDefaultAssociatedConformanceAccessor(
+ AssociatedConformance requirement) {
+ auto forDefinition = ForDefinition;
+
+ LinkEntity entity =
+ LinkEntity::forDefaultAssociatedConformanceAccessor(requirement);
+ llvm::Function *&entry = GlobalFuncs[entity];
+ if (entry) {
+ if (forDefinition) updateLinkageForDefinition(*this, entry, entity);
+ return entry;
+ }
+
+ auto signature = getAssociatedTypeWitnessTableAccessFunctionSignature();
+ LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
+ entry = createFunction(*this, link, signature);
+ return entry;
+}
+
+llvm::Function *
IRGenModule::getAddrOfContinuationPrototype(CanSILFunctionType fnType) {
LinkEntity entity = LinkEntity::forCoroutineContinuationPrototype(fnType);
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index f0198cf..a75abe0 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -647,7 +647,14 @@
if (entry.isAssociatedConformance()) {
auto flags = Flags(Flags::Kind::AssociatedConformanceAccessFunction);
- return { flags, nullptr };
+
+ // Look for a default witness.
+ llvm::Constant *defaultImpl =
+ findDefaultAssociatedConformanceWitness(
+ entry.getAssociatedConformancePath(),
+ entry.getAssociatedConformanceRequirement());
+
+ return { flags, defaultImpl };
}
assert(entry.isFunction());
@@ -712,10 +719,12 @@
if (entry.isAssociatedConformance()) {
// Define the associated conformance descriptor to point to the
// current position in the protocol descriptor.
+ AssociatedConformance conformance(
+ Proto,
+ entry.getAssociatedConformancePath(),
+ entry.getAssociatedConformanceRequirement());
IGM.defineAssociatedConformanceDescriptor(
- Proto,
- entry.getAssociatedConformancePath(),
- entry.getAssociatedConformanceRequirement(),
+ conformance,
B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
}
@@ -800,6 +809,89 @@
IGF.Builder.CreateRet(returnValue);
return accessor;
}
+
+ llvm::Constant *findDefaultAssociatedConformanceWitness(
+ CanType association,
+ ProtocolDecl *requirement) {
+ if (!DefaultWitnesses) return nullptr;
+
+ for (auto &entry : DefaultWitnesses->getEntries()) {
+ if (!entry.isValid() ||
+ entry.getKind() != SILWitnessTable::AssociatedTypeProtocol ||
+ entry.getAssociatedTypeProtocolWitness().Protocol != requirement ||
+ entry.getAssociatedTypeProtocolWitness().Requirement != association)
+ continue;
+
+ auto witness = entry.getAssociatedTypeProtocolWitness().Witness;
+ return getDefaultAssociatedConformanceAccessFunction(
+ AssociatedConformance(Proto, association, requirement),
+ witness);
+ }
+
+ return nullptr;
+ }
+
+ llvm::Constant *getDefaultAssociatedConformanceAccessFunction(
+ AssociatedConformance requirement,
+ ProtocolConformanceRef conformance) {
+ auto accessor =
+ IGM.getAddrOfDefaultAssociatedConformanceAccessor(requirement);
+
+ IRGenFunction IGF(IGM, accessor);
+ if (IGM.DebugInfo)
+ IGM.DebugInfo->emitArtificialFunction(IGF, accessor);
+
+ Explosion parameters = IGF.collectParameters();
+
+ llvm::Value *associatedTypeMetadata = parameters.claimNext();
+ llvm::Value *self = parameters.claimNext();
+ llvm::Value *wtable = parameters.claimNext();
+
+ bool hasArchetype =
+ !conformance.isConcrete() ||
+ conformance.getConcrete()->getType()->hasArchetype();
+ if (hasArchetype) {
+ // Bind local Self type data from the metadata argument.
+ CanType selfInContext =
+ Proto->mapTypeIntoContext(Proto->getProtocolSelfType())
+ ->getCanonicalType();
+ IGF.bindLocalTypeDataFromTypeMetadata(selfInContext, IsExact, self,
+ MetadataState::Abstract);
+ IGF.setUnscopedLocalTypeData(
+ selfInContext,
+ LocalTypeDataKind::forAbstractProtocolWitnessTable(Proto),
+ wtable);
+
+ // Bind the associated type metadata.
+ IGF.bindLocalTypeDataFromTypeMetadata(requirement.getAssociation(),
+ IsExact,
+ associatedTypeMetadata,
+ MetadataState::Abstract);
+ }
+
+ // For a concrete witness table, call it.
+ ProtocolDecl *associatedProtocol = requirement.getAssociatedRequirement();
+ if (conformance.isConcrete()) {
+ auto conformanceI = &IGM.getConformanceInfo(associatedProtocol,
+ conformance.getConcrete());
+ auto returnValue = conformanceI->getTable(IGF, &associatedTypeMetadata);
+ IGF.Builder.CreateRet(returnValue);
+ return accessor;
+ }
+
+ // For an abstract table, emit a reference to the witness table.
+ CanType associatedTypeInContext
+ = Proto->mapTypeIntoContext(requirement.getAssociation())
+ ->getCanonicalType();
+ auto returnValue =
+ emitArchetypeWitnessTableRef(
+ IGF,
+ cast<ArchetypeType>(associatedTypeInContext),
+ associatedProtocol);
+ IGF.Builder.CreateRet(returnValue);
+ return accessor;
+ }
+
void addAssociatedTypeNames() {
std::string AssociatedTypeNames;
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 0cf4f02..a04e8ae 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -1385,6 +1385,13 @@
void addAssociatedConformance(AssociatedConformance requirement) {
// FIXME: Add static witness tables for type conformances.
+ auto &entry = SILEntries.front();
+ (void)entry;
+ SILEntries = SILEntries.slice(1);
+
+ if (ResilientConformance)
+ return;
+
auto associate =
ConformanceInContext.getAssociatedType(
requirement.getAssociation())->getCanonicalType();
@@ -1394,9 +1401,8 @@
requirement.getAssociation(),
requirement.getAssociatedRequirement());
+
#ifndef NDEBUG
- auto &entry = SILEntries.front();
- (void)entry;
assert(entry.getKind() == SILWitnessTable::AssociatedTypeProtocol
&& "sil witness table does not match protocol");
auto associatedWitness = entry.getAssociatedTypeProtocolWitness();
@@ -1411,8 +1417,6 @@
"offset doesn't match ProtocolInfo layout");
#endif
- SILEntries = SILEntries.slice(1);
-
llvm::Constant *wtableAccessFunction =
getAssociatedTypeWitnessTableAccessFunction(requirement,
associate,
@@ -1644,7 +1648,8 @@
getAssociatedTypeWitnessTableAccessFunction(AssociatedConformance requirement,
CanType associatedType,
ProtocolConformanceRef associatedConformance) {
- if (!associatedType->hasArchetype()) {
+ bool hasArchetype = associatedType->hasArchetype();
+ if (!hasArchetype && !ResilientConformance) {
assert(associatedConformance.isConcrete() &&
"no concrete conformance for non-dependent type");
return getOrCreateWitnessTableAccessFunction(IGM,
@@ -1682,13 +1687,6 @@
Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
setProtocolWitnessTableName(IGM, destTable.getAddress(), ConcreteType,
Conformance.getProtocol());
- IGF.bindLocalTypeDataFromSelfWitnessTable(
- &Conformance,
- destTable.getAddress(),
- [&](CanType type) {
- return Conformance.getDeclContext()->mapTypeIntoContext(type)
- ->getCanonicalType();
- });
ProtocolDecl *associatedProtocol = requirement.getAssociatedRequirement();
@@ -1710,6 +1708,24 @@
}
}
+ // If there are no archetypes, return a reference to the table. There is
+ // no need for a cache.
+ if (!hasArchetype) {
+ auto wtable = MetadataResponse::forComplete(
+ conformanceI->getTable(IGF, &associatedTypeMetadata))
+ .getMetadata();
+ IGF.Builder.CreateRet(wtable);
+ return accessor;
+ }
+
+ IGF.bindLocalTypeDataFromSelfWitnessTable(
+ &Conformance,
+ destTable.getAddress(),
+ [&](CanType type) {
+ return Conformance.getDeclContext()->mapTypeIntoContext(type)
+ ->getCanonicalType();
+ });
+
// If the witness table is directly fulfillable from the type,
// we don't need a cache entry.
// TODO: maybe we should have a cache entry anyway if the fulfillment
@@ -1869,7 +1885,8 @@
unsigned count = 0;
for (auto &entry : SILWT->getEntries()) {
if (entry.getKind() != SILWitnessTable::Method &&
- entry.getKind() != SILWitnessTable::AssociatedType)
+ entry.getKind() != SILWitnessTable::AssociatedType &&
+ entry.getKind() != SILWitnessTable::AssociatedTypeProtocol)
continue;
count++;
@@ -1907,6 +1924,36 @@
continue;
}
+ // Associated conformance access function.
+ if (entry.getKind() == SILWitnessTable::AssociatedTypeProtocol) {
+ const auto &witness = entry.getAssociatedTypeProtocolWitness();
+
+ // Associated type descriptor.
+ AssociatedConformance requirement(SILWT->getConformance()->getProtocol(),
+ witness.Requirement,
+ witness.Protocol);
+ auto assocConformanceDescriptor =
+ IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+ LinkEntity::forAssociatedConformanceDescriptor(requirement),
+ Alignment(4), IGM.ProtocolRequirementStructTy);
+ table.addRelativeAddress(assocConformanceDescriptor);
+
+ auto associate =
+ ConformanceInContext.getAssociatedType(
+ witness.Requirement)->getCanonicalType();
+
+ ProtocolConformanceRef associatedConformance =
+ ConformanceInContext.getAssociatedConformance(witness.Requirement,
+ witness.Protocol);
+
+ llvm::Constant *wtableAccessFunction =
+ getAssociatedTypeWitnessTableAccessFunction(requirement,
+ associate,
+ associatedConformance);
+ table.addRelativeAddress(wtableAccessFunction);
+ continue;
+ }
+
if (entry.getKind() != SILWitnessTable::Method)
continue;
diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h
index edd7713..37c5b95 100644
--- a/lib/IRGen/IRGenMangler.h
+++ b/lib/IRGen/IRGenMangler.h
@@ -197,6 +197,19 @@
return finalize();
}
+ std::string mangleDefaultAssociatedConformanceAccessor(
+ const ProtocolDecl *proto,
+ CanType subject,
+ const ProtocolDecl *requirement) {
+ beginMangling();
+ appendAnyGenericType(proto);
+ bool isFirstAssociatedTypeIdentifier = true;
+ appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier);
+ appendProtocolName(requirement);
+ appendOperator("TN");
+ return finalize();
+ }
+
std::string mangleProtocolConformanceDescriptor(
const ProtocolConformance *Conformance) {
beginMangling();
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index fb33001..0c98b82 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -1237,10 +1237,8 @@
llvm::Constant *getAddrOfAssociatedConformanceDescriptor(
AssociatedConformance conformance);
llvm::GlobalValue *defineAssociatedConformanceDescriptor(
- ProtocolDecl *proto,
- CanType subject,
- ProtocolDecl *requirement,
- llvm::Constant *definition);
+ AssociatedConformance conformance,
+ llvm::Constant *definition);
llvm::Constant *getAddrOfProtocolDescriptor(ProtocolDecl *D,
ConstantInit definition = ConstantInit());
@@ -1293,6 +1291,8 @@
const AssociatedConformance &association);
llvm::Function *getAddrOfDefaultAssociatedTypeMetadataAccessFunction(
AssociatedType association);
+ llvm::Function *getAddrOfDefaultAssociatedConformanceAccessor(
+ AssociatedConformance requirement);
Address getAddrOfObjCISAMask();
diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp
index 6562b50..b24a247 100644
--- a/lib/IRGen/Linking.cpp
+++ b/lib/IRGen/Linking.cpp
@@ -187,6 +187,14 @@
assocConformance.second);
}
+ case Kind::DefaultAssociatedConformanceAccessor: {
+ auto assocConformance = getAssociatedConformance();
+ return mangler.mangleDefaultAssociatedConformanceAccessor(
+ cast<ProtocolDecl>(getDecl()),
+ assocConformance.first,
+ assocConformance.second);
+ }
+
case Kind::ProtocolConformanceDescriptor:
return mangler.mangleProtocolConformanceDescriptor(
cast<NormalProtocolConformance>(getProtocolConformance()));
@@ -498,6 +506,7 @@
case Kind::AssociatedTypeMetadataAccessFunction:
case Kind::DefaultAssociatedTypeMetadataAccessFunction:
case Kind::AssociatedTypeWitnessTableAccessFunction:
+ case Kind::DefaultAssociatedConformanceAccessor:
case Kind::GenericProtocolWitnessTableCache:
case Kind::GenericProtocolWitnessTableInstantiationFunction:
return SILLinkage::Private;
@@ -629,6 +638,7 @@
case Kind::TypeMetadataCompletionFunction:
case Kind::TypeMetadataPattern:
case Kind::DefaultAssociatedTypeMetadataAccessFunction:
+ case Kind::DefaultAssociatedConformanceAccessor:
return false;
case Kind::ValueWitness:
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index e655e14..75d0bc7 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -181,7 +181,8 @@
ProtocolConformance *
parseProtocolConformanceHelper(ProtocolDecl *&proto,
GenericEnvironment *GenericEnv,
- bool localScope);
+ bool localScope,
+ ProtocolDecl *defaultForProto);
public:
SILParser(Parser &P)
: P(P), SILMod(static_cast<SILParserTUState *>(P.SIL)->M),
@@ -391,15 +392,18 @@
bool isStartOfSILInstruction();
bool parseSubstitutions(SmallVectorImpl<ParsedSubstitution> &parsed,
- GenericEnvironment *GenericEnv=nullptr);
+ GenericEnvironment *GenericEnv=nullptr,
+ ProtocolDecl *defaultForProto = nullptr);
ProtocolConformance *parseProtocolConformance(ProtocolDecl *&proto,
GenericEnvironment *&genericEnv,
- bool localScope);
- ProtocolConformance *parseProtocolConformance() {
+ bool localScope,
+ ProtocolDecl *defaultForProto);
+ ProtocolConformance *parseProtocolConformance(
+ ProtocolDecl *defaultForProto) {
ProtocolDecl *dummy;
GenericEnvironment *env;
- return parseProtocolConformance(dummy, env, true);
+ return parseProtocolConformance(dummy, env, true, defaultForProto);
}
Optional<llvm::coverage::Counter>
@@ -1012,6 +1016,8 @@
if (!DC)
DC = &P.SF;
+ else if (!GenericEnv)
+ GenericEnv = DC->getGenericEnvironmentOfContext();
return swift::performTypeLocChecking(P.Context, T,
/*isSILMode=*/true, IsSILType,
@@ -1510,10 +1516,46 @@
return false;
}
+/// Bind any unqualified 'Self' references to the given protocol's 'Self'
+/// generic parameter.
+///
+/// FIXME: This is a hack to work around the lack of a DeclContext for
+/// witness tables.
+static void bindProtocolSelfInTypeRepr(TypeLoc &TL, ProtocolDecl *proto) {
+ if (auto typeRepr = TL.getTypeRepr()) {
+ // AST walker to update 'Self' references.
+ class BindProtocolSelf : public ASTWalker {
+ ProtocolDecl *proto;
+ GenericTypeParamDecl *selfParam;
+ Identifier selfId;
+
+ public:
+ BindProtocolSelf(ProtocolDecl *proto)
+ : proto(proto),
+ selfParam(proto->getProtocolSelfType()->getDecl()),
+ selfId(proto->getASTContext().Id_Self) {
+ }
+
+ virtual bool walkToTypeReprPre(TypeRepr *T) override {
+ if (auto ident = dyn_cast<IdentTypeRepr>(T)) {
+ auto firstComponent = ident->getComponentRange().front();
+ if (firstComponent->getIdentifier() == selfId)
+ firstComponent->setValue(selfParam, proto);
+ }
+
+ return true;
+ }
+ };
+
+ typeRepr->walk(BindProtocolSelf(proto));
+ }
+}
+
/// Parse the substitution list for an apply instruction or
/// specialized protocol conformance.
bool SILParser::parseSubstitutions(SmallVectorImpl<ParsedSubstitution> &parsed,
- GenericEnvironment *GenericEnv) {
+ GenericEnvironment *GenericEnv,
+ ProtocolDecl *defaultForProto) {
// Check for an opening '<' bracket.
if (!P.Tok.isContextualPunctuator("<"))
return false;
@@ -1529,7 +1571,10 @@
if (TyR.isNull())
return true;
TypeLoc Ty = TyR.get();
- if (performTypeLocChecking(Ty, /*IsSILType=*/ false, GenericEnv))
+ if (defaultForProto)
+ bindProtocolSelfInTypeRepr(Ty, defaultForProto);
+ if (performTypeLocChecking(Ty, /*IsSILType=*/ false, GenericEnv,
+ defaultForProto))
return true;
parsed.push_back({Loc, Ty.getType()});
} while (P.consumeIf(tok::comma));
@@ -5725,7 +5770,8 @@
ProtocolConformance *SILParser::parseProtocolConformance(
ProtocolDecl *&proto,
GenericEnvironment *&genericEnv,
- bool localScope) {
+ bool localScope,
+ ProtocolDecl *defaultForProto) {
// Parse generic params for the protocol conformance. We need to make sure
// they have the right scope.
Optional<Scope> GenericsScope;
@@ -5741,7 +5787,8 @@
}
ProtocolConformance *retVal =
- parseProtocolConformanceHelper(proto, genericEnv, localScope);
+ parseProtocolConformanceHelper(proto, genericEnv, localScope,
+ defaultForProto);
if (localScope) {
GenericsScope.reset();
@@ -5752,13 +5799,19 @@
ProtocolConformance *SILParser::parseProtocolConformanceHelper(
ProtocolDecl *&proto,
GenericEnvironment *witnessEnv,
- bool localScope) {
+ bool localScope,
+ ProtocolDecl *defaultForProto) {
// Parse AST type.
ParserResult<TypeRepr> TyR = P.parseType();
if (TyR.isNull())
return nullptr;
TypeLoc Ty = TyR.get();
- if (performTypeLocChecking(Ty, /*IsSILType=*/ false, witnessEnv))
+ if (defaultForProto) {
+ bindProtocolSelfInTypeRepr(Ty, defaultForProto);
+ }
+
+ if (performTypeLocChecking(Ty, /*IsSILType=*/ false, witnessEnv,
+ defaultForProto))
return nullptr;
auto ConformingTy = Ty.getType();
@@ -5770,7 +5823,7 @@
// Parse substitutions for specialized conformance.
SmallVector<ParsedSubstitution, 4> parsedSubs;
- if (parseSubstitutions(parsedSubs, witnessEnv))
+ if (parseSubstitutions(parsedSubs, witnessEnv, defaultForProto))
return nullptr;
if (P.parseToken(tok::l_paren, diag::expected_sil_witness_lparen))
@@ -5778,7 +5831,8 @@
ProtocolDecl *dummy;
GenericEnvironment *specializedEnv;
auto genericConform =
- parseProtocolConformance(dummy, specializedEnv, localScope);
+ parseProtocolConformance(dummy, specializedEnv, localScope,
+ defaultForProto);
if (!genericConform)
return nullptr;
if (P.parseToken(tok::r_paren, diag::expected_sil_witness_rparen))
@@ -5799,7 +5853,7 @@
if (P.parseToken(tok::l_paren, diag::expected_sil_witness_lparen))
return nullptr;
- auto baseConform = parseProtocolConformance();
+ auto baseConform = parseProtocolConformance(defaultForProto);
if (!baseConform)
return nullptr;
if (P.parseToken(tok::r_paren, diag::expected_sil_witness_rparen))
@@ -5812,41 +5866,6 @@
return retVal;
}
-/// Bind any unqualified 'Self' references to the given protocol's 'Self'
-/// generic parameter.
-///
-/// FIXME: This is a hack to work around the lack of a DeclContext for
-/// witness tables.
-static void bindProtocolSelfInTypeRepr(TypeLoc &TL, ProtocolDecl *proto) {
- if (auto typeRepr = TL.getTypeRepr()) {
- // AST walker to update 'Self' references.
- class BindProtocolSelf : public ASTWalker {
- ProtocolDecl *proto;
- GenericTypeParamDecl *selfParam;
- Identifier selfId;
-
- public:
- BindProtocolSelf(ProtocolDecl *proto)
- : proto(proto),
- selfParam(proto->getProtocolSelfType()->getDecl()),
- selfId(proto->getASTContext().Id_Self) {
- }
-
- virtual bool walkToTypeReprPre(TypeRepr *T) override {
- if (auto ident = dyn_cast<IdentTypeRepr>(T)) {
- auto firstComponent = ident->getComponentRange().front();
- if (firstComponent->getIdentifier() == selfId)
- firstComponent->setValue(selfParam, proto);
- }
-
- return true;
- }
- };
-
- typeRepr->walk(BindProtocolSelf(proto));
- }
-}
-
/// Parser a single SIL vtable entry and add it to either \p witnessEntries
/// or \c conditionalConformances.
static bool parseSILVTableEntry(
@@ -5859,6 +5878,7 @@
std::vector<SILWitnessTable::Entry> &witnessEntries,
std::vector<SILWitnessTable::ConditionalConformance>
&conditionalConformances) {
+ ProtocolDecl *defaultForProto = isDefaultWitnessTable ? proto : nullptr;
Identifier EntryKeyword;
SourceLoc KeywordLoc;
if (P.parseIdentifier(EntryKeyword, KeywordLoc,
@@ -5878,7 +5898,8 @@
return true;
if (P.parseToken(tok::colon, diag::expected_sil_witness_colon))
return true;
- ProtocolConformance *conform = witnessState.parseProtocolConformance();
+ ProtocolConformance *conform =
+ witnessState.parseProtocolConformance(defaultForProto);
if (!conform) // Ignore this witness entry for now.
return false;
@@ -5925,7 +5946,7 @@
ProtocolConformanceRef conformance(proto);
if (P.Tok.getText() != "dependent") {
- auto concrete = witnessState.parseProtocolConformance();
+ auto concrete = witnessState.parseProtocolConformance(defaultForProto);
if (!concrete) // Ignore this witness entry for now.
return false;
conformance = ProtocolConformanceRef(concrete);
@@ -6045,7 +6066,8 @@
GenericEnvironment *witnessEnv;
auto conf = WitnessState.parseProtocolConformance(proto,
witnessEnv,
- false/*localScope*/);
+ false/*localScope*/,
+ nullptr);
WitnessState.ContextGenericEnv = witnessEnv;
NormalProtocolConformance *theConformance = conf ?
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 1350026..4182f48 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -769,7 +769,19 @@
}
void addAssociatedConformance(const AssociatedConformance &req) {
- addMissingDefault();
+ auto witness =
+ Proto->getDefaultAssociatedConformanceWitness(
+ req.getAssociation(),
+ req.getAssociatedRequirement());
+ if (!witness)
+ return addMissingDefault();
+
+ auto entry =
+ SILWitnessTable::AssociatedTypeProtocolWitness{
+ req.getAssociation(),
+ req.getAssociatedRequirement(),
+ *witness};
+ DefaultWitnesses.push_back(entry);
}
};
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 564da3e..dcd7e17 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -19,6 +19,7 @@
#include "TypeCheckType.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/TypeWalker.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
@@ -1226,15 +1227,9 @@
void ConstraintSystem::solve(SmallVectorImpl<Solution> &solutions) {
assert(solverState);
- SmallVector<SolverStep *, 16> workList;
+ SmallVector<std::unique_ptr<SolverStep>, 16> workList;
// First step is always wraps whole constraint system.
- workList.push_back(SplitterStep::create(*this, solutions));
-
- SWIFT_DEFER {
- // Delete all of the leftover steps from the work list.
- while (!workList.empty())
- delete workList.pop_back_val();
- };
+ workList.push_back(llvm::make_unique<SplitterStep>(*this, solutions));
// Indicate whether previous step in the stack has failed
// (returned StepResult::Kind = Error), this is useful to
@@ -1251,9 +1246,6 @@
}
currentState = step->getState();
- assert(currentState == StepState::Ready ||
- currentState == StepState::Suspended);
-
step->transitionTo(StepState::Running);
return currentState == StepState::Ready ? step->take(prevFailed)
: step->resume(prevFailed);
@@ -1264,17 +1256,13 @@
// a solution, or producing another set of mergeable
// steps to take before arriving to solution.
while (!workList.empty()) {
- auto *step = workList.back();
+ auto &step = workList.back();
// Now let's try to advance to the next step or re-take previous,
// which should produce another steps to follow,
// or error, which means that current path is inconsistent.
{
- assert(!(step->getState() == StepState::Running ||
- step->getState() == StepState::Done) &&
- "Cannot re-take already running/done step.");
-
- auto result = advance(step, prevFailed);
+ auto result = advance(step.get(), prevFailed);
switch (result.getKind()) {
// It was impossible to solve this step, let's note that
// for followup steps, to propogate the error.
@@ -1286,7 +1274,6 @@
// toward that solution.
case SolutionKind::Solved: {
workList.pop_back();
- delete step;
break;
}
diff --git a/lib/Sema/CSStep.cpp b/lib/Sema/CSStep.cpp
index a2c0512..aa48e66 100644
--- a/lib/Sema/CSStep.cpp
+++ b/lib/Sema/CSStep.cpp
@@ -49,7 +49,7 @@
if (prevFailed || CS.failedConstraint || CS.simplify())
return done(/*isSuccess=*/false);
- SmallVector<ComponentStep *, 4> components;
+ SmallVector<std::unique_ptr<ComponentStep>, 4> components;
// Try to run "connected components" algorithm and split
// type variables and their constraints into independent
// sub-systems to solve.
@@ -59,10 +59,14 @@
// try to merge solutions, "split" step should be considered
// done and replaced by a single component step.
if (components.size() < 2)
- return replaceWith(components.front());
+ return replaceWith(std::move(components.front()));
+
+ SmallVector<std::unique_ptr<SolverStep>, 4> followup;
+ for (auto &step : components)
+ followup.push_back(std::move(step));
/// Wait until all of the component steps are done.
- return suspend<ComponentStep>(components);
+ return suspend(followup);
}
StepResult SplitterStep::resume(bool prevFailed) {
@@ -83,7 +87,7 @@
}
void SplitterStep::computeFollowupSteps(
- SmallVectorImpl<ComponentStep *> &componentSteps) {
+ SmallVectorImpl<std::unique_ptr<ComponentStep>> &componentSteps) {
// Compute next steps based on that connected components
// algorithm tells us is splittable.
@@ -99,7 +103,7 @@
SmallVector<unsigned, 16> components;
unsigned numComponents = CG.computeConnectedComponents(typeVars, components);
if (numComponents < 2) {
- componentSteps.push_back(ComponentStep::create(
+ componentSteps.push_back(llvm::make_unique<ComponentStep>(
CS, 0, /*single=*/true, &CS.InactiveConstraints, Solutions));
return;
}
@@ -109,7 +113,7 @@
new SmallVector<Solution, 4>[numComponents]);
for (unsigned i = 0, n = numComponents; i != n; ++i) {
- componentSteps.push_back(ComponentStep::create(
+ componentSteps.push_back(llvm::make_unique<ComponentStep>(
CS, i, /*single=*/false, &Components[i], PartialSolutions[i]));
}
@@ -186,7 +190,8 @@
// since components are going to be executed in LIFO order, we'd
// want to have smaller/faster components at the back of the list.
std::sort(componentSteps.begin(), componentSteps.end(),
- [](const ComponentStep *lhs, const ComponentStep *rhs) {
+ [](const std::unique_ptr<ComponentStep> &lhs,
+ const std::unique_ptr<ComponentStep> &rhs) {
return lhs->disjunctionCount() > rhs->disjunctionCount();
});
}
@@ -256,10 +261,12 @@
if (bestBindings && (!disjunction || (!bestBindings->InvolvesTypeVariables &&
!bestBindings->FullyBound))) {
// Produce a type variable step.
- return suspend(TypeVariableStep::create(CS, *bestBindings, Solutions));
+ return suspend(
+ llvm::make_unique<TypeVariableStep>(CS, *bestBindings, Solutions));
} else if (disjunction) {
// Produce a disjunction step.
- return suspend(DisjunctionStep::create(CS, disjunction, Solutions));
+ return suspend(
+ llvm::make_unique<DisjunctionStep>(CS, disjunction, Solutions));
}
// If there are no disjunctions or type variables to bind
@@ -353,24 +360,11 @@
bool TypeVariableStep::attempt(const TypeVariableBinding &choice) {
++CS.solverState->NumTypeVariableBindings;
- if (isDebugMode()) {
- auto &log = getDebugLogger();
- log << "(trying ";
- choice.print(log, &CS.getASTContext().SourceMgr);
- log << '\n';
- }
-
if (choice.hasDefaultedProtocol())
SawFirstLiteralConstraint = true;
// Try to solve the system with typeVar := type
- if (!choice.attempt(CS)) {
- if (isDebugMode())
- getDebugLogger() << ")\n";
- return false;
- }
-
- return true;
+ return choice.attempt(CS);
}
StepResult TypeVariableStep::resume(bool prevFailed) {
@@ -380,16 +374,16 @@
// that active binding has a solution.
AnySolved |= !prevFailed;
- if (isDebugMode())
- getDebugLogger() << ")\n";
-
- const auto choice = ActiveChoice->second;
+ bool shouldStop = shouldStopAfter(ActiveChoice->second);
// Rewind back all of the changes made to constraint system.
ActiveChoice.reset();
+ if (isDebugMode())
+ getDebugLogger() << ")\n";
+
// Let's check if we should stop right before
// attempting any new bindings.
- if (shouldStopAfter(choice))
+ if (shouldStop)
return done(/*isSuccess=*/AnySolved);
// Attempt next type variable binding.
@@ -560,11 +554,5 @@
}
}
- if (!choice.attempt(CS)) {
- if (isDebugMode())
- getDebugLogger() << ")\n";
- return false;
- }
-
- return true;
+ return choice.attempt(CS);
}
diff --git a/lib/Sema/CSStep.h b/lib/Sema/CSStep.h
index 3fd6495..38dfa4f 100644
--- a/lib/Sema/CSStep.h
+++ b/lib/Sema/CSStep.h
@@ -49,15 +49,15 @@
private:
Kind ResultKind;
- SmallVector<SolverStep *, 4> NextSteps;
+ SmallVector<std::unique_ptr<SolverStep>, 4> NextSteps;
StepResult(Kind kind) : ResultKind(kind) {}
- StepResult(Kind kind, SolverStep *step) : ResultKind(kind) {
- NextSteps.push_back(step);
+ StepResult(Kind kind, std::unique_ptr<SolverStep> step) : ResultKind(kind) {
+ NextSteps.push_back(std::move(step));
}
- StepResult(Kind kind, SmallVectorImpl<SolverStep *> &followup)
+ StepResult(Kind kind, SmallVectorImpl<std::unique_ptr<SolverStep>> &followup)
: ResultKind(kind), NextSteps(std::move(followup)) {}
public:
@@ -65,29 +65,24 @@
Kind getKind() const { return ResultKind; }
- void transfer(SmallVectorImpl<SolverStep *> &workList) {
+ void transfer(SmallVectorImpl<std::unique_ptr<SolverStep>> &workList) {
workList.reserve(NextSteps.size());
- workList.append(NextSteps.begin(), NextSteps.end());
+ for (auto &step : NextSteps)
+ workList.push_back(std::move(step));
}
private:
static StepResult success() { return StepResult(Kind::Solved); }
static StepResult failure() { return StepResult(Kind::Error); }
- static StepResult unsolved(SolverStep *singleStep) {
- return StepResult(Kind::Unsolved, singleStep);
+ static StepResult unsolved(std::unique_ptr<SolverStep> singleStep) {
+ return StepResult(Kind::Unsolved, std::move(singleStep));
}
- static StepResult unsolved(SmallVectorImpl<SolverStep *> &followup) {
+ static StepResult
+ unsolved(SmallVectorImpl<std::unique_ptr<SolverStep>> &followup) {
return StepResult(Kind::Unsolved, followup);
}
-
- template <typename T> static StepResult unsolved(ArrayRef<T *> followup) {
- auto result = StepResult(Kind::Unsolved);
- for (auto *step : followup)
- result.NextSteps.push_back(static_cast<SolverStep *>(step));
- return result;
- }
};
/// Represents a single independently solvable part of
@@ -156,9 +151,32 @@
///
/// \param newState The new state this step should be in.
void transitionTo(StepState newState) {
- // TODO: Make sure that ordering of the state transitions is correct,
- // because `setup -> ready -> running [-> suspended]* -> done`
- // is the only reasonable state transition path.
+#ifndef NDEBUG
+ // Make sure that ordering of the state transitions is correct,
+ // because `setup -> ready -> running [-> suspended]* -> done`
+ // is the only reasonable state transition path.
+ switch (State) {
+ case StepState::Setup:
+ assert(newState == StepState::Ready);
+ break;
+
+ case StepState::Ready:
+ assert(newState == StepState::Running);
+ break;
+
+ case StepState::Running:
+ assert(newState == StepState::Suspended || newState == StepState::Done);
+ break;
+
+ case StepState::Suspended:
+ assert(newState == StepState::Running);
+ break;
+
+ case StepState::Done:
+ llvm_unreachable("step is already done.");
+ }
+#endif
+
State = newState;
}
@@ -167,22 +185,17 @@
return isSuccess ? StepResult::success() : StepResult::failure();
}
- StepResult replaceWith(SolverStep *replacement) {
+ StepResult replaceWith(std::unique_ptr<SolverStep> replacement) {
transitionTo(StepState::Done);
- return StepResult(StepResult::Kind::Solved, replacement);
+ return StepResult(StepResult::Kind::Solved, std::move(replacement));
}
- StepResult suspend(SolverStep *followup) {
+ StepResult suspend(std::unique_ptr<SolverStep> followup) {
transitionTo(StepState::Suspended);
- return StepResult::unsolved(followup);
+ return StepResult::unsolved(std::move(followup));
}
- StepResult suspend(SmallVectorImpl<SolverStep *> &followup) {
- transitionTo(StepState::Suspended);
- return StepResult::unsolved(followup);
- }
-
- template <typename T> StepResult suspend(ArrayRef<T *> followup) {
+ StepResult suspend(SmallVectorImpl<std::unique_ptr<SolverStep>> &followup) {
transitionTo(StepState::Suspended);
return StepResult::unsolved(followup);
}
@@ -244,10 +257,10 @@
SmallVector<Constraint *, 4> OrphanedConstraints;
+public:
SplitterStep(ConstraintSystem &cs, SmallVectorImpl<Solution> &solutions)
: SolverStep(cs, solutions) {}
-public:
StepResult take(bool prevFailed) override;
StepResult resume(bool prevFailed) override;
@@ -255,15 +268,11 @@
Out << "SplitterStep with #" << Components.size() << " components\n";
}
- static SplitterStep *create(ConstraintSystem &cs,
- SmallVectorImpl<Solution> &solutions) {
- return new SplitterStep(cs, solutions);
- }
-
private:
/// If current step needs follow-up steps to get completely solved,
/// let's compute them using connected components algorithm.
- void computeFollowupSteps(SmallVectorImpl<ComponentStep *> &componentSteps);
+ void computeFollowupSteps(
+ SmallVectorImpl<std::unique_ptr<ComponentStep>> &componentSteps);
/// Once all of the follow-up steps are complete, let's try
/// to merge resulting solutions together, to form final solution(s)
@@ -339,6 +348,7 @@
/// with it, which makes it disconnected in the graph.
Constraint *OrphanedConstraint = nullptr;
+public:
ComponentStep(ConstraintSystem &cs, unsigned index, bool single,
ConstraintList *constraints,
SmallVectorImpl<Solution> &solutions)
@@ -346,7 +356,6 @@
OriginalScore(getCurrentScore()), OriginalBestScore(getBestScore()),
Constraints(constraints) {}
-public:
/// Record a type variable as associated with this step.
void record(TypeVariableType *typeVar) { TypeVars.push_back(typeVar); }
@@ -388,12 +397,6 @@
void print(llvm::raw_ostream &Out) override {
Out << "ComponentStep with at #" << Index << '\n';
}
-
- static ComponentStep *create(ConstraintSystem &cs, unsigned index,
- bool single, ConstraintList *constraints,
- SmallVectorImpl<Solution> &solutions) {
- return new ComponentStep(cs, index, single, constraints, solutions);
- }
};
template <typename P> class BindingStep : public SolverStep {
@@ -425,14 +428,24 @@
if (shouldStopAt(*choice))
break;
+ if (isDebugMode()) {
+ auto &log = getDebugLogger();
+ log << "(attempting ";
+ choice->print(log, &CS.getASTContext().SourceMgr);
+ log << '\n';
+ }
+
{
auto scope = llvm::make_unique<Scope>(CS);
if (attempt(*choice)) {
ActiveChoice.emplace(std::move(scope), *choice);
- return suspend(SplitterStep::create(CS, Solutions));
+ return suspend(llvm::make_unique<SplitterStep>(CS, Solutions));
}
}
+ if (isDebugMode())
+ getDebugLogger() << ")\n";
+
// If this binding didn't match, let's check if we've attempted
// enough bindings to stop, because some producers might need
// to compute next step of bindings to try, which we'd want to avoid.
@@ -490,12 +503,12 @@
/// attempting other bindings in certain conditions.
bool SawFirstLiteralConstraint = false;
+public:
TypeVariableStep(ConstraintSystem &cs, BindingContainer &bindings,
SmallVectorImpl<Solution> &solutions)
: BindingStep(cs, {cs, bindings}, solutions), TypeVar(bindings.TypeVar),
InitialBindings(bindings.Bindings.begin(), bindings.Bindings.end()) {}
-public:
void setup() override;
StepResult resume(bool prevFailed) override;
@@ -505,12 +518,6 @@
<< InitialBindings.size() << " initial bindings\n";
}
- static TypeVariableStep *create(ConstraintSystem &cs,
- BindingContainer &bindings,
- SmallVectorImpl<Solution> &solutions) {
- return new TypeVariableStep(cs, bindings, solutions);
- }
-
protected:
bool attempt(const TypeVariableBinding &choice) override;
@@ -574,11 +581,6 @@
Out << '\n';
}
- static DisjunctionStep *create(ConstraintSystem &cs, Constraint *disjunction,
- SmallVectorImpl<Solution> &solutions) {
- return new DisjunctionStep(cs, disjunction, solutions);
- }
-
private:
bool shouldSkip(const DisjunctionChoice &choice) const override;
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index eef1a1f..35b3ddb 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -3373,6 +3373,7 @@
bool isSymmetricOperator() const;
void print(llvm::raw_ostream &Out, SourceManager *SM) const {
+ Out << "disjunction choice ";
Choice->print(Out, SM);
}
@@ -3420,7 +3421,8 @@
bool attempt(ConstraintSystem &cs) const;
void print(llvm::raw_ostream &Out, SourceManager *) const {
- Out << TypeVar->getString() << " := " << Binding.BindingType->getString();
+ Out << "type variable " << TypeVar->getString()
+ << " := " << Binding.BindingType->getString();
}
};
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index bf1f963..194f65b 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4689,7 +4689,25 @@
(void)decl->isDynamic();
}
-bool swift::isPassThroughTypealias(TypeAliasDecl *typealias) {
+/// Determine whether this is a "pass-through" typealias, which has the
+/// same type parameters as the nominal type it references and specializes
+/// the underlying nominal type with exactly those type parameters.
+/// For example, the following typealias \c GX is a pass-through typealias:
+///
+/// \code
+/// struct X<T, U> { }
+/// typealias GX<A, B> = X<A, B>
+/// \endcode
+///
+/// whereas \c GX2 and \c GX3 are not pass-through because \c GX2 has
+/// different type parameters and \c GX3 doesn't pass its type parameters
+/// directly through.
+///
+/// \code
+/// typealias GX2<A> = X<A, A>
+/// typealias GX3<A, B> = X<B, A>
+/// \endcode
+static bool isPassThroughTypealias(TypeAliasDecl *typealias) {
// Pass-through only makes sense when the typealias refers to a nominal
// type.
Type underlyingType = typealias->getUnderlyingTypeLoc().getType();
@@ -4877,31 +4895,78 @@
if (ext->hasValidationStarted())
return;
- bindExtension(ext);
-
DeclValidationRAII IBV(ext);
- // If the extension is already known to be invalid, we're done.
- if (ext->isInvalid())
- return;
+ auto dc = ext->getDeclContext();
- // FIXME: We need to check whether anything is specialized, because
- // the innermost extended type might itself be a non-generic type
- // within a generic type.
+ // If we didn't parse a type, fill in an error type and bail out.
+ if (!ext->getExtendedTypeLoc().getTypeRepr()) {
+ ext->setInvalid();
+ ext->getExtendedTypeLoc().setInvalidType(Context);
+ return;
+ }
+
+ // Validate the extended type.
+ TypeResolutionOptions options(TypeResolverContext::ExtensionBinding);
+ options |= TypeResolutionFlags::AllowUnboundGenerics;
+ if (validateType(ext->getExtendedTypeLoc(),
+ TypeResolution::forContextual(dc), options)) {
+ ext->setInvalid();
+ ext->getExtendedTypeLoc().setInvalidType(Context);
+ return;
+ }
+
+ // Dig out the extended type.
auto extendedType = ext->getExtendedType();
- if (extendedType.isNull() || extendedType->hasError())
+ // Hack to allow extending a generic typealias.
+ if (auto *unboundGeneric = extendedType->getAs<UnboundGenericType>()) {
+ if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(unboundGeneric->getDecl())) {
+ auto extendedNominal = aliasDecl->getDeclaredInterfaceType()->getAnyNominal();
+ if (extendedNominal) {
+ extendedType = extendedNominal->getDeclaredType();
+ if (!isPassThroughTypealias(aliasDecl))
+ ext->getExtendedTypeLoc().setType(extendedType);
+ }
+ }
+ }
+
+ // Cannot extend a metatype.
+ if (extendedType->is<AnyMetatypeType>()) {
+ diagnose(ext->getLoc(), diag::extension_metatype, extendedType)
+ .highlight(ext->getExtendedTypeLoc().getSourceRange());
+ ext->setInvalid();
+ ext->getExtendedTypeLoc().setInvalidType(Context);
+ return;
+ }
+
+ // Cannot extend a bound generic type.
+ if (extendedType->isSpecialized()) {
+ diagnose(ext->getLoc(), diag::extension_specialization,
+ extendedType->getAnyNominal()->getName())
+ .highlight(ext->getExtendedTypeLoc().getSourceRange());
+ ext->setInvalid();
+ ext->getExtendedTypeLoc().setInvalidType(Context);
+ return;
+ }
+
+ auto *nominal = extendedType->getAnyNominal();
+
+ // Cannot extend function types, tuple types, etc.
+ if (nominal == nullptr) {
+ diagnose(ext->getLoc(), diag::non_nominal_extension, extendedType)
+ .highlight(ext->getExtendedTypeLoc().getSourceRange());
+ ext->setInvalid();
+ ext->getExtendedTypeLoc().setInvalidType(Context);
+ return;
+ }
+
+ // Extensions nested inside other declarations are invalid and we
+ // do not bind them.
+ if (!isa<SourceFile>(dc))
return;
// Validate the nominal type declaration being extended.
- NominalTypeDecl *nominal = extendedType->getAnyNominal();
- if (!nominal) {
- auto unbound = cast<UnboundGenericType>(extendedType.getPointer());
- auto typealias = cast<TypeAliasDecl>(unbound->getDecl());
- validateDecl(typealias);
-
- nominal = typealias->getUnderlyingTypeLoc().getType()->getAnyNominal();
- }
validateDecl(nominal);
if (nominal->getGenericParamsOfContext()) {
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 9cc6860..4b1f7a5 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -5252,6 +5252,30 @@
void TypeChecker::inferDefaultWitnesses(ProtocolDecl *proto) {
DefaultWitnessChecker checker(*this, proto);
+ // Find the default for the given associated type.
+ auto findAssociatedTypeDefault =
+ [&](AssociatedTypeDecl *assocType,
+ AssociatedTypeDecl **defaultedAssocTypeOut = nullptr) -> Type {
+ auto defaultedAssocType =
+ AssociatedTypeInference::findDefaultedAssociatedType(*this, assocType);
+ if (!defaultedAssocType)
+ return nullptr;;
+
+ Type defaultType = defaultedAssocType->getDefaultDefinitionLoc().getType();
+ if (!defaultType)
+ return nullptr;
+
+ // Map out of its protocol context...
+ defaultType = defaultType->mapTypeOutOfContext();
+ if (defaultType->hasError())
+ return nullptr;
+
+ if (defaultedAssocTypeOut)
+ *defaultedAssocTypeOut = defaultedAssocType;
+
+ return defaultType;
+ };
+
for (auto *requirement : proto->getMembers()) {
if (requirement->isInvalid())
continue;
@@ -5262,19 +5286,8 @@
if (auto assocType = dyn_cast<AssociatedTypeDecl>(valueDecl)) {
if (assocType->getOverriddenDecls().empty()) {
- if (auto defaultedAssocType =
- AssociatedTypeInference::findDefaultedAssociatedType(
- *this, assocType)) {
- Type defaultType =
- defaultedAssocType->getDefaultDefinitionLoc().getType();
-
- // Map out of its protocol context...
- defaultType = defaultType->mapTypeOutOfContext();
-
- if (!defaultType->hasError()) {
- proto->setDefaultTypeWitness(assocType, defaultType);
- }
- }
+ if (Type defaultType = findAssociatedTypeDefault(assocType))
+ proto->setDefaultTypeWitness(assocType, defaultType);
}
continue;
@@ -5288,6 +5301,77 @@
checker.resolveWitnessViaLookup(valueDecl);
}
+
+ // Find defaults for any associated conformances rooted on defaulted
+ // associated types.
+ for (const auto &req : proto->getRequirementSignature()) {
+ if (req.getKind() != RequirementKind::Conformance)
+ continue;
+ if (req.getFirstType()->isEqual(proto->getProtocolSelfType()))
+ continue;
+
+ // Find the innermost dependent member type (e.g., Self.AssocType), so
+ // we can look at the associated type.
+ auto depMemTy = req.getFirstType()->getAs<DependentMemberType>();
+ if (!depMemTy)
+ continue;
+
+ while (auto innerDepMemTy =
+ depMemTy->getBase()->getAs<DependentMemberType>())
+ depMemTy = innerDepMemTy;
+
+ if (!depMemTy->getBase()->isEqual(proto->getProtocolSelfType()))
+ continue;
+
+ auto assocType = depMemTy->getAssocType();
+ if (!assocType)
+ continue;
+
+ // Find the associated type nearest our own protocol, which might have
+ // a default not available in the associated type referenced by the
+ // (canonicalized) requirement.
+ if (assocType->getProtocol() != proto) {
+ SmallVector<ValueDecl *, 2> found;
+ proto->getModuleContext()->lookupQualified(
+ proto, assocType->getFullName(),
+ NL_QualifiedDefault|NL_ProtocolMembers|NL_OnlyTypes,
+ found);
+ if (found.size() == 1 && isa<AssociatedTypeDecl>(found[0]))
+ assocType = cast<AssociatedTypeDecl>(found[0]);
+ }
+
+ // Dig out the default associated type definition.
+ AssociatedTypeDecl *defaultedAssocType = nullptr;
+ Type defaultAssocType = findAssociatedTypeDefault(assocType,
+ &defaultedAssocType);
+ if (!defaultAssocType)
+ continue;
+
+ Type defaultAssocTypeInContext =
+ proto->mapTypeIntoContext(defaultAssocType);
+ auto requirementProto =
+ req.getSecondType()->castTo<ProtocolType>()->getDecl();
+ auto conformance = conformsToProtocol(defaultAssocTypeInContext,
+ requirementProto, proto,
+ ConformanceCheckFlags::Used);
+ if (!conformance) {
+ // Diagnose the lack of a conformance. This is potentially an ABI
+ // incompatibility.
+ diagnose(proto, diag::assoc_type_default_conformance_failed,
+ defaultAssocType, assocType->getFullName(), req.getFirstType(),
+ req.getSecondType());
+ diagnose(defaultedAssocType, diag::assoc_type_default_here,
+ assocType->getFullName(), defaultAssocType)
+ .highlight(
+ defaultedAssocType->getDefaultDefinitionLoc().getSourceRange());
+
+ continue;
+ }
+
+ // Record the default associated conformance.
+ proto->setDefaultAssociatedConformanceWitness(
+ req.getFirstType()->getCanonicalType(), requirementProto, *conformance);
+ }
}
void TypeChecker::recordKnownWitness(NormalProtocolConformance *conformance,
diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp
index 8f441ac..615cb50 100644
--- a/lib/Sema/TypeCheckProtocolInference.cpp
+++ b/lib/Sema/TypeCheckProtocolInference.cpp
@@ -183,15 +183,19 @@
if (extension == conformanceExtension)
return true;
- tc.bindExtension(extension);
+ auto *extendedNominal = extension->getExtendedNominal();
+
+ // Invalid case.
+ if (extendedNominal == nullptr)
+ return true;
// Assume unconstrained concrete extensions we found witnesses in are
// always viable.
- if (!extension->getExtendedType()->isAnyExistentialType()) {
- // TODO: When constrained extensions are a thing, we'll need an "is
- // as specialized as" kind of check here.
+ if (!isa<ProtocolDecl>(extendedNominal))
return !extension->isConstrainedExtension();
- }
+
+ // Build a generic signature.
+ tc.validateExtension(extension);
// The extension may not have a generic signature set up yet, as a
// recursion breaker, in which case we can't yet confidently reject its
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index 07fe209..90ab00d 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -346,80 +346,6 @@
nominal->addExtension(ext);
}
-static void bindExtensionDecl(ExtensionDecl *ED, TypeChecker &TC) {
- if (ED->getExtendedType())
- return;
-
- // If we didn't parse a type, fill in an error type and bail out.
- if (!ED->getExtendedTypeLoc().getTypeRepr()) {
- ED->setInvalid();
- ED->getExtendedTypeLoc().setInvalidType(TC.Context);
- return;
- }
-
- auto dc = ED->getDeclContext();
-
- // Validate the representation.
- // FIXME: Perform some kind of "shallow" validation here?
- TypeResolutionOptions options(TypeResolverContext::ExtensionBinding);
- options |= TypeResolutionFlags::AllowUnboundGenerics;
- if (TC.validateType(ED->getExtendedTypeLoc(),
- TypeResolution::forContextual(dc), options)) {
- ED->setInvalid();
- ED->getExtendedTypeLoc().setInvalidType(TC.Context);
- return;
- }
-
- // Dig out the extended type.
- auto extendedType = ED->getExtendedType();
-
- // Hack to allow extending a generic typealias.
- if (auto *unboundGeneric = extendedType->getAs<UnboundGenericType>()) {
- if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(unboundGeneric->getDecl())) {
- auto extendedNominal = aliasDecl->getDeclaredInterfaceType()->getAnyNominal();
- if (extendedNominal) {
- extendedType = extendedNominal->getDeclaredType();
- if (!isPassThroughTypealias(aliasDecl))
- ED->getExtendedTypeLoc().setType(extendedType);
- }
- }
- }
-
- // Handle easy cases.
-
- // Cannot extend a metatype.
- if (extendedType->is<AnyMetatypeType>()) {
- TC.diagnose(ED->getLoc(), diag::extension_metatype, extendedType)
- .highlight(ED->getExtendedTypeLoc().getSourceRange());
- ED->setInvalid();
- ED->getExtendedTypeLoc().setInvalidType(TC.Context);
- return;
- }
-
- // Cannot extend a bound generic type.
- if (extendedType->isSpecialized()) {
- TC.diagnose(ED->getLoc(), diag::extension_specialization,
- extendedType->getAnyNominal()->getName())
- .highlight(ED->getExtendedTypeLoc().getSourceRange());
- ED->setInvalid();
- ED->getExtendedTypeLoc().setInvalidType(TC.Context);
- return;
- }
-
- // Dig out the nominal type being extended.
- NominalTypeDecl *extendedNominal = extendedType->getAnyNominal();
- if (!extendedNominal) {
- TC.diagnose(ED->getLoc(), diag::non_nominal_extension, extendedType)
- .highlight(ED->getExtendedTypeLoc().getSourceRange());
- ED->setInvalid();
- ED->getExtendedTypeLoc().setInvalidType(TC.Context);
- return;
- }
- assert(extendedNominal && "Should have the nominal type being extended");
-
- bindExtensionToNominal(ED, extendedNominal);
-}
-
static void bindExtensions(SourceFile &SF, TypeChecker &TC) {
// Utility function to try and resolve the extended type without diagnosing.
// If we succeed, we go ahead and bind the extension. Otherwise, return false.
@@ -467,14 +393,8 @@
}
} while(changed);
- // Phase 3 - anything that remains on the worklist cannot be resolved, which
- // means its invalid. Diagnose.
- for (auto *ext : worklist)
- bindExtensionDecl(ext, TC);
-}
-
-void TypeChecker::bindExtension(ExtensionDecl *ext) {
- ::bindExtensionDecl(ext, *this);
+ // Any remaining extensions are invalid. They will be diagnosed later by
+ // typeCheckDecl().
}
static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC) {
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 6dc3db3..6d13959 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1106,8 +1106,6 @@
validateDecl(proto);
}
- virtual void bindExtension(ExtensionDecl *ext) override;
-
virtual void resolveExtension(ExtensionDecl *ext) override {
validateExtension(ext);
}
@@ -2173,26 +2171,6 @@
DeclContext *DC,
TypeChecker &TC);
-/// Determine whether this is a "pass-through" typealias, which has the
-/// same type parameters as the nominal type it references and specializes
-/// the underlying nominal type with exactly those type parameters.
-/// For example, the following typealias \c GX is a pass-through typealias:
-///
-/// \code
-/// struct X<T, U> { }
-/// typealias GX<A, B> = X<A, B>
-/// \endcode
-///
-/// whereas \c GX2 and \c GX3 are not pass-through because \c GX2 has
-/// different type parameters and \c GX3 doesn't pass its type parameters
-/// directly through.
-///
-/// \code
-/// typealias GX2<A> = X<A, A>
-/// typealias GX3<A, B> = X<B, A>
-/// \endcode
-bool isPassThroughTypealias(TypeAliasDecl *typealias);
-
/// Whether an overriding declaration requires the 'override' keyword.
enum class OverrideRequiresKeyword {
/// The keyword is never required.
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index 09b95d2..a97621d 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -326,9 +326,19 @@
if (auto orphanedBuffer = loadedModuleFile->takeBufferForDiagnostics())
OrphanedMemoryBuffers.push_back(std::move(orphanedBuffer));
- if (!diagLoc)
- return nullptr;
+ if (diagLoc)
+ serialization::diagnoseSerializedASTLoadFailure(
+ Ctx, *diagLoc, loadInfo, extendedInfo, moduleBufferID,
+ moduleDocBufferID, loadedModuleFile.get(), M.getName());
+ return nullptr;
+}
+void swift::serialization::diagnoseSerializedASTLoadFailure(
+ ASTContext &Ctx, SourceLoc diagLoc,
+ const serialization::ValidationInfo &loadInfo,
+ const serialization::ExtendedValidationInfo &extendedInfo,
+ StringRef moduleBufferID, StringRef moduleDocBufferID,
+ ModuleFile *loadedModuleFile, Identifier ModuleName) {
auto diagnoseDifferentLanguageVersion = [&](StringRef shortVersion) -> bool {
if (shortVersion.empty())
return false;
@@ -339,10 +349,9 @@
if (versionString.str() == shortVersion)
return false;
- Ctx.Diags.diagnose(*diagLoc,
- diag::serialization_module_language_version_mismatch,
- loadInfo.shortVersion, versionString.str(),
- moduleBufferID);
+ Ctx.Diags.diagnose(
+ diagLoc, diag::serialization_module_language_version_mismatch,
+ loadInfo.shortVersion, versionString.str(), moduleBufferID);
return true;
};
@@ -353,23 +362,23 @@
case serialization::Status::FormatTooNew:
if (diagnoseDifferentLanguageVersion(loadInfo.shortVersion))
break;
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_new,
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_module_too_new,
moduleBufferID);
break;
case serialization::Status::FormatTooOld:
if (diagnoseDifferentLanguageVersion(loadInfo.shortVersion))
break;
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_old,
- M.getName(), moduleBufferID);
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_module_too_old, ModuleName,
+ moduleBufferID);
break;
case serialization::Status::Malformed:
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_malformed_module,
moduleBufferID);
break;
case serialization::Status::MalformedDocumentation:
assert(!moduleDocBufferID.empty());
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_malformed_module,
moduleDocBufferID);
break;
@@ -379,19 +388,19 @@
// not now.
llvm::StringSet<> duplicates;
llvm::SmallVector<ModuleFile::Dependency, 4> missing;
- std::copy_if(loadedModuleFile->getDependencies().begin(),
- loadedModuleFile->getDependencies().end(),
- std::back_inserter(missing),
- [&duplicates](const ModuleFile::Dependency &dependency)->bool {
- if (dependency.isLoaded() || dependency.isHeader())
- return false;
- return duplicates.insert(dependency.RawPath).second;
- });
+ std::copy_if(
+ loadedModuleFile->getDependencies().begin(),
+ loadedModuleFile->getDependencies().end(), std::back_inserter(missing),
+ [&duplicates](const ModuleFile::Dependency &dependency) -> bool {
+ if (dependency.isLoaded() || dependency.isHeader())
+ return false;
+ return duplicates.insert(dependency.RawPath).second;
+ });
// FIXME: only show module part of RawAccessPath
assert(!missing.empty() && "unknown missing dependency?");
if (missing.size() == 1) {
- Ctx.Diags.diagnose(*diagLoc,diag::serialization_missing_single_dependency,
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_single_dependency,
missing.front().getPrettyPrintedPath());
} else {
llvm::SmallString<64> missingNames;
@@ -403,7 +412,7 @@
[&] { missingNames += "', '"; });
missingNames += '\'';
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_dependencies,
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_dependencies,
missingNames);
}
@@ -419,24 +428,25 @@
auto circularDependencyIter =
llvm::find_if(loadedModuleFile->getDependencies(),
[](const ModuleFile::Dependency &next) {
- return !next.Import.second->hasResolvedImports();
- });
- assert(circularDependencyIter != loadedModuleFile->getDependencies().end()
- && "circular dependency reported, but no module with unresolved "
- "imports found");
+ return !next.Import.second->hasResolvedImports();
+ });
+ assert(circularDependencyIter !=
+ loadedModuleFile->getDependencies().end() &&
+ "circular dependency reported, but no module with unresolved "
+ "imports found");
// FIXME: We should include the path of the circularity as well, but that's
// hard because we're discovering this /while/ resolving imports, which
// means the problematic modules haven't been recorded yet.
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_circular_dependency,
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_circular_dependency,
circularDependencyIter->getPrettyPrintedPath(),
- M.getName());
+ ModuleName);
break;
}
case serialization::Status::MissingShadowedModule: {
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_shadowed_module,
- M.getName());
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_shadowed_module,
+ ModuleName);
if (Ctx.SearchPathOpts.SDKPath.empty() &&
llvm::Triple(llvm::sys::getProcessTriple()).isMacOSX()) {
Ctx.Diags.diagnose(SourceLoc(), diag::sema_no_import_no_sdk);
@@ -448,7 +458,7 @@
case serialization::Status::FailedToLoadBridgingHeader:
// We already emitted a diagnostic about the bridging header. Just emit
// a generic message here.
- Ctx.Diags.diagnose(*diagLoc, diag::serialization_load_failed, M.getName());
+ Ctx.Diags.diagnose(diagLoc, diag::serialization_load_failed, ModuleName);
break;
case serialization::Status::NameMismatch: {
@@ -457,8 +467,7 @@
auto diagKind = diag::serialization_name_mismatch;
if (Ctx.LangOpts.DebuggerSupport)
diagKind = diag::serialization_name_mismatch_repl;
- Ctx.Diags.diagnose(*diagLoc, diagKind,
- loadInfo.name, M.getName());
+ Ctx.Diags.diagnose(diagLoc, diagKind, loadInfo.name, ModuleName);
break;
}
@@ -468,8 +477,8 @@
auto diagKind = diag::serialization_target_incompatible;
if (Ctx.LangOpts.DebuggerSupport)
diagKind = diag::serialization_target_incompatible_repl;
- Ctx.Diags.diagnose(*diagLoc, diagKind,
- M.getName(), loadInfo.targetTriple, moduleBufferID);
+ Ctx.Diags.diagnose(diagLoc, diagKind, ModuleName, loadInfo.targetTriple,
+ moduleBufferID);
break;
}
@@ -486,14 +495,12 @@
auto diagKind = diag::serialization_target_too_new;
if (Ctx.LangOpts.DebuggerSupport)
diagKind = diag::serialization_target_too_new_repl;
- Ctx.Diags.diagnose(*diagLoc, diagKind,
- compilationOSInfo.first, compilationOSInfo.second,
- M.getName(), moduleOSInfo.second, moduleBufferID);
+ Ctx.Diags.diagnose(diagLoc, diagKind, compilationOSInfo.first,
+ compilationOSInfo.second, ModuleName,
+ moduleOSInfo.second, moduleBufferID);
break;
}
}
-
- return nullptr;
}
bool
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 68e0d42..384cd05 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -100,11 +100,8 @@
}
void TBDGenVisitor::addAssociatedConformanceDescriptor(
- ProtocolDecl *proto,
- CanType subject,
- ProtocolDecl *requirement) {
- auto entity = LinkEntity::forAssociatedConformanceDescriptor(proto, subject,
- requirement);
+ AssociatedConformance conformance) {
+ auto entity = LinkEntity::forAssociatedConformanceDescriptor(conformance);
addSymbol(entity);
}
@@ -426,10 +423,11 @@
if (req.getFirstType()->isEqual(PD->getProtocolSelfType()))
continue;
- addAssociatedConformanceDescriptor(
- PD,
- req.getFirstType()->getCanonicalType(),
- req.getSecondType()->castTo<ProtocolType>()->getDecl());
+ AssociatedConformance conformance(
+ PD,
+ req.getFirstType()->getCanonicalType(),
+ req.getSecondType()->castTo<ProtocolType>()->getDecl());
+ addAssociatedConformanceDescriptor(conformance);
}
for (auto *member : PD->getMembers()) {
@@ -442,7 +440,8 @@
}
}
- // Always produce associated type descriptors.
+ // Always produce associated type descriptors, because they can
+ // be referenced by generic signatures.
if (auto *assocType = dyn_cast<AssociatedTypeDecl>(member)) {
if (assocType->getOverriddenDecls().empty())
addAssociatedTypeDescriptor(assocType);
diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h
index 9db482e..e468265 100644
--- a/lib/TBDGen/TBDGenVisitor.h
+++ b/lib/TBDGen/TBDGenVisitor.h
@@ -66,9 +66,7 @@
void addProtocolRequirementsBaseDescriptor(ProtocolDecl *proto);
void addAssociatedTypeDescriptor(AssociatedTypeDecl *assocType);
- void addAssociatedConformanceDescriptor(ProtocolDecl *proto,
- CanType subject,
- ProtocolDecl *requirement);
+ void addAssociatedConformanceDescriptor(AssociatedConformance conformance);
public:
TBDGenVisitor(tapi::internal::InterfaceFile &symbols,
diff --git a/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift b/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
index f9dc7fa..79c5d88 100644
--- a/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
+++ b/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
@@ -13,8 +13,6 @@
//===----------------------------------------------------------------------===//
import Swift
-@_frozen // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
internal enum _Prespecialize {
// Create specializations for the arrays of most
// popular builtin integer and floating point types.
diff --git a/stdlib/public/core/DropWhile.swift b/stdlib/public/core/DropWhile.swift
index 8c78847..d8ce1d9 100644
--- a/stdlib/public/core/DropWhile.swift
+++ b/stdlib/public/core/DropWhile.swift
@@ -12,21 +12,21 @@
/// A sequence whose elements consist of the elements that follow the initial
/// consecutive elements of some base sequence that satisfy a given predicate.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // lazy-performance
public struct LazyDropWhileSequence<Base: Sequence> {
public typealias Element = Base.Element
/// Create an instance with elements `transform(x)` for each element
/// `x` of base.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
self._base = _base
self._predicate = predicate
}
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Element) -> Bool
}
@@ -37,27 +37,27 @@
/// This is the associated iterator for the `LazyDropWhileSequence`,
/// `LazyDropWhileCollection`, and `LazyDropWhileBidirectionalCollection`
/// types.
- @_fixed_layout // FIXME(sil-serialize-all)
+ @_fixed_layout // lazy-performance
public struct Iterator {
public typealias Element = Base.Element
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base.Iterator, predicate: @escaping (Element) -> Bool) {
self._base = _base
self._predicate = predicate
}
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _predicateHasFailed = false
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base.Iterator
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Element) -> Bool
}
}
extension LazyDropWhileSequence.Iterator: IteratorProtocol {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public mutating func next() -> Element? {
// Once the predicate has failed for the first time, the base iterator
// can be used for the rest of the elements.
@@ -83,7 +83,7 @@
/// Returns an iterator over the elements of this sequence.
///
/// - Complexity: O(1).
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func makeIterator() -> Iterator {
return Iterator(_base: _base.makeIterator(), predicate: _predicate)
}
@@ -101,7 +101,7 @@
/// its argument and returns `true` if the element should be skipped or
/// `false` otherwise. Once `predicate` returns `false` it will not be
/// called again.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func drop(
while predicate: @escaping (Elements.Element) -> Bool
) -> LazyDropWhileSequence<Self.Elements> {
@@ -119,19 +119,19 @@
/// performance given by the `Collection` protocol. Be aware, therefore,
/// that general operations on lazy collections may not have the
/// documented complexity.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // lazy-performance
public struct LazyDropWhileCollection<Base: Collection> {
public typealias Element = Base.Element
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
self._base = _base
self._predicate = predicate
}
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Element) -> Bool
}
@@ -141,7 +141,7 @@
/// Returns an iterator over the elements of this sequence.
///
/// - Complexity: O(1).
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func makeIterator() -> Iterator {
return Iterator(_base: _base.makeIterator(), predicate: _predicate)
}
@@ -152,12 +152,12 @@
/// A position in a `LazyDropWhileCollection` or
/// `LazyDropWhileBidirectionalCollection` instance.
- @_fixed_layout // FIXME(sil-serialize-all)
+ @_fixed_layout // lazy-performance
public struct Index {
/// The position corresponding to `self` in the underlying collection.
public let base: Base.Index
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base.Index) {
self.base = _base
}
@@ -165,7 +165,7 @@
}
extension LazyDropWhileCollection.Index: Equatable, Comparable {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public static func == (
lhs: LazyDropWhileCollection<Base>.Index,
rhs: LazyDropWhileCollection<Base>.Index
@@ -173,7 +173,7 @@
return lhs.base == rhs.base
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public static func < (
lhs: LazyDropWhileCollection<Base>.Index,
rhs: LazyDropWhileCollection<Base>.Index
@@ -201,7 +201,7 @@
}
extension LazyDropWhileCollection: Collection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public var startIndex: Index {
var index = _base.startIndex
while index != _base.endIndex && _predicate(_base[index]) {
@@ -210,19 +210,19 @@
return Index(_base: index)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public var endIndex: Index {
return Index(_base: _base.endIndex)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func index(after i: Index) -> Index {
_precondition(i.base < _base.endIndex, "Can't advance past endIndex")
return Index(_base: _base.index(after: i.base))
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public subscript(position: Index) -> Element {
return _base[position.base]
}
@@ -232,7 +232,7 @@
extension LazyDropWhileCollection: BidirectionalCollection
where Base: BidirectionalCollection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func index(before i: Index) -> Index {
_precondition(i > startIndex, "Can't move before startIndex")
return Index(_base: _base.index(before: i.base))
@@ -247,7 +247,7 @@
/// as its argument and returns `true` if the element should be skipped or
/// `false` otherwise. Once `predicate` returns `false` it will not be
/// called again.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func drop(
while predicate: @escaping (Elements.Element) -> Bool
) -> LazyDropWhileCollection<Self.Elements> {
diff --git a/stdlib/public/core/Filter.swift b/stdlib/public/core/Filter.swift
index 9b13baa..c630af2 100644
--- a/stdlib/public/core/Filter.swift
+++ b/stdlib/public/core/Filter.swift
@@ -18,17 +18,17 @@
/// is a `LazyFilterSequence`.
@_fixed_layout // lazy-performance
public struct LazyFilterSequence<Base: Sequence> {
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base
/// The predicate used to determine which elements produced by
/// `base` are also produced by `self`.
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Base.Element) -> Bool
/// Creates an instance consisting of the elements `x` of `base` for
/// which `isIncluded(x) == true`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public // @testable
init(_base base: Base, _ isIncluded: @escaping (Base.Element) -> Bool) {
self._base = base
diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift
index 0418e5a..2c00e90 100644
--- a/stdlib/public/core/Integers.swift
+++ b/stdlib/public/core/Integers.swift
@@ -303,7 +303,7 @@
///
/// - Parameter x: A signed number.
/// - Returns: The absolute value of `x`.
-@_transparent
+@inlinable
public func abs<T : SignedNumeric>(_ x: T) -> T
where T.Magnitude == T {
return x.magnitude
@@ -322,9 +322,9 @@
///
/// - Parameter x: A signed number.
/// - Returns: The absolute value of `x`.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable
public func abs<T : SignedNumeric & Comparable>(_ x: T) -> T {
- return x < 0 ? -x : x
+ return x < (0 as T) ? -x : x
}
extension Numeric {
@@ -1185,7 +1185,7 @@
///
/// - Returns: The sign of this number, expressed as an integer of the same
/// type.
- @_transparent
+ @inlinable
public func signum() -> Self {
return (self > (0 as Self) ? 1 : 0) - (self < (0 as Self) ? 1 : 0)
}
@@ -1196,7 +1196,7 @@
return it.next() ?? 0
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public func _binaryLogarithm() -> Int {
_precondition(self > (0 as Self))
var (quotient, remainder) =
@@ -1233,7 +1233,7 @@
/// - Parameter rhs: The value to divide this value by.
/// - Returns: A tuple containing the quotient and remainder of this value
/// divided by `rhs`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public func quotientAndRemainder(dividingBy rhs: Self)
-> (quotient: Self, remainder: Self) {
return (self / rhs, self % rhs)
@@ -1370,7 +1370,7 @@
/// - lhs: The value to shift.
/// - rhs: The number of bits to shift `lhs` to the right.
@_semantics("optimize.sil.specialize.generic.partial.never")
- @inlinable
+ @_transparent
public static func >> <RHS: BinaryInteger>(lhs: Self, rhs: RHS) -> Self {
var r = lhs
r >>= rhs
@@ -1416,7 +1416,7 @@
/// - lhs: The value to shift.
/// - rhs: The number of bits to shift `lhs` to the left.
@_semantics("optimize.sil.specialize.generic.partial.never")
- @inlinable
+ @_transparent
public static func << <RHS: BinaryInteger>(lhs: Self, rhs: RHS) -> Self {
var r = lhs
r <<= rhs
@@ -1493,7 +1493,6 @@
}
/// A textual representation of this value.
- @inlinable // FIXME(sil-serialize-all)
public var description: String {
return _description(radix: 10, uppercase: false)
}
@@ -1505,7 +1504,6 @@
//===----------------------------------------------------------------------===//
extension BinaryInteger {
- // FIXME(ABI): using Int as the return type is wrong.
/// Returns the distance from this value to the given value, expressed as a
/// stride.
///
@@ -1514,7 +1512,7 @@
///
/// - Parameter other: The value to calculate the distance to.
/// - Returns: The distance from this value to `other`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@inline(__always)
public func distance(to other: Self) -> Int {
if !Self.isSigned {
@@ -1542,7 +1540,6 @@
_preconditionFailure("Distance is not representable in Int")
}
- // FIXME(ABI): using Int as the parameter type is wrong.
/// Returns a value that is offset the specified distance from this value.
///
/// Use the `advanced(by:)` method in generic code to offset a value by a
@@ -1554,7 +1551,7 @@
///
/// - Parameter n: The distance to advance this value.
/// - Returns: A value that is offset from this value by `n`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@inline(__always)
public func advanced(by n: Int) -> Self {
if !Self.isSigned {
@@ -1594,8 +1591,7 @@
/// - Parameters:
/// - lhs: An integer to compare.
/// - rhs: Another integer to compare.
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func == <
Other : BinaryInteger
>(lhs: Self, rhs: Other) -> Bool {
@@ -1669,8 +1665,7 @@
/// - Parameters:
/// - lhs: An integer to compare.
/// - rhs: Another integer to compare.
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func < <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
let lhsNegative = Self.isSigned && lhs < (0 as Self)
let rhsNegative = Other.isSigned && rhs < (0 as Other)
@@ -1713,7 +1708,6 @@
/// - lhs: An integer to compare.
/// - rhs: Another integer to compare.
@_transparent
- //@inline(__always)
public static func <= <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
return !(rhs < lhs)
}
@@ -1729,7 +1723,6 @@
/// - lhs: An integer to compare.
/// - rhs: Another integer to compare.
@_transparent
- //@inline(__always)
public static func >= <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
return !(lhs < rhs)
}
@@ -1745,7 +1738,6 @@
/// - lhs: An integer to compare.
/// - rhs: Another integer to compare.
@_transparent
- //@inline(__always)
public static func > <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
return rhs < lhs
}
@@ -1773,20 +1765,17 @@
return !(lhs == rhs)
}
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func <= (lhs: Self, rhs: Self) -> Bool {
return !(rhs < lhs)
}
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func >= (lhs: Self, rhs: Self) -> Bool {
return !(lhs < rhs)
}
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func > (lhs: Self, rhs: Self) -> Bool {
return rhs < lhs
}
@@ -2214,7 +2203,7 @@
@inlinable
public var bitWidth: Int { return Self.bitWidth }
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public func _binaryLogarithm() -> Int {
_precondition(self > (0 as Self))
return Self.bitWidth &- (leadingZeroBitCount &+ 1)
@@ -2225,7 +2214,7 @@
///
/// - Parameter value: A value to use as the little-endian representation of
/// the new integer.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public init(littleEndian value: Self) {
#if _endian(little)
self = value
@@ -2239,7 +2228,7 @@
///
/// - Parameter value: A value to use as the big-endian representation of the
/// new integer.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public init(bigEndian value: Self) {
#if _endian(big)
self = value
@@ -2253,7 +2242,7 @@
/// If necessary, the byte order of this value is reversed from the typical
/// byte order of this integer type. On a little-endian platform, for any
/// integer `x`, `x == x.littleEndian`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public var littleEndian: Self {
#if _endian(little)
return self
@@ -2267,7 +2256,7 @@
/// If necessary, the byte order of this value is reversed from the typical
/// byte order of this integer type. On a big-endian platform, for any
/// integer `x`, `x == x.bigEndian`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public var bigEndian: Self {
#if _endian(big)
return self
@@ -2310,7 +2299,6 @@
/// - rhs: The number of bits to shift `lhs` to the right. If `rhs` is
/// outside the range `0..<lhs.bitWidth`, it is masked to produce a
/// value within that range.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
public static func &>> (lhs: Self, rhs: Self) -> Self {
@@ -2354,7 +2342,7 @@
/// outside the range `0..<lhs.bitWidth`, it is masked to produce a
/// value within that range.
@_semantics("optimize.sil.specialize.generic.partial.never")
- @inlinable
+ @_transparent
public static func &>> <
Other : BinaryInteger
>(lhs: Self, rhs: Other) -> Self {
@@ -2389,7 +2377,6 @@
/// - rhs: The number of bits to shift `lhs` to the right. If `rhs` is
/// outside the range `0..<lhs.bitWidth`, it is masked to produce a
/// value within that range.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
public static func &>>= <
@@ -2432,7 +2419,6 @@
/// - rhs: The number of bits to shift `lhs` to the left. If `rhs` is
/// outside the range `0..<lhs.bitWidth`, it is masked to produce a
/// value within that range.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
public static func &<< (lhs: Self, rhs: Self) -> Self {
@@ -2476,7 +2462,7 @@
/// outside the range `0..<lhs.bitWidth`, it is masked to produce a
/// value within that range.
@_semantics("optimize.sil.specialize.generic.partial.never")
- @inlinable
+ @_transparent
public static func &<< <
Other : BinaryInteger
>(lhs: Self, rhs: Other) -> Self {
@@ -2511,7 +2497,6 @@
/// - rhs: The number of bits to shift `lhs` to the left. If `rhs` is
/// outside the range `0..<lhs.bitWidth`, it is masked to produce a
/// value within that range.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
public static func &<<= <
@@ -2756,7 +2741,6 @@
/// - Parameters:
/// - lhs: The value to shift.
/// - rhs: The number of bits to shift `lhs` to the right.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
public static func >> <
@@ -2785,8 +2769,7 @@
lhs = _nonMaskingRightShift(lhs, shift)
}
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func _nonMaskingRightShift(_ lhs: Self, _ rhs: Int) -> Self {
let overshiftR = Self.isSigned ? lhs &>> (Self.bitWidth - 1) : 0
let overshiftL: Self = 0
@@ -2845,7 +2828,6 @@
/// - Parameters:
/// - lhs: The value to shift.
/// - rhs: The number of bits to shift `lhs` to the left.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
public static func << <
@@ -2874,8 +2856,7 @@
lhs = _nonMaskingLeftShift(lhs, shift)
}
- @inlinable // FIXME(sil-serialize-all)
- @inline(__always)
+ @_transparent
public static func _nonMaskingLeftShift(_ lhs: Self, _ rhs: Int) -> Self {
let overshiftR = Self.isSigned ? lhs &>> (Self.bitWidth - 1) : 0
let overshiftL: Self = 0
@@ -2972,9 +2953,8 @@
/// // y == nil
///
/// - Parameter source: A floating-point value to convert to an integer.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
- @inline(__always)
+ @inlinable
public init?<T : BinaryFloatingPoint>(exactly source: T) {
let (temporary, exact) = Self._convert(from: source)
guard exact, let value = temporary else {
@@ -3003,7 +2983,7 @@
/// // y == 0
///
/// - Parameter source: An integer to convert to this type.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@_semantics("optimize.sil.specialize.generic.partial.never")
public init<Other : BinaryInteger>(clamping source: Other) {
if _slowPath(source < Self.min) {
@@ -3033,7 +3013,7 @@
///
/// - Parameter rhs: The value to add to this value.
/// - Returns: The sum of this value and `rhs`.
- @_transparent
+ @inline(__always)
public func unsafeAdding(_ other: Self) -> Self {
let (result, overflow) = self.addingReportingOverflow(other)
@@ -3066,7 +3046,7 @@
///
/// - Parameter rhs: The value to subtract from this value.
/// - Returns: The result of subtracting `rhs` from this value.
- @_transparent
+ @inline(__always)
public func unsafeSubtracting(_ other: Self) -> Self {
let (result, overflow) = self.subtractingReportingOverflow(other)
@@ -3099,7 +3079,7 @@
///
/// - Parameter rhs: The value to multiply by this value.
/// - Returns: The product of this value and `rhs`.
- @_transparent
+ @inline(__always)
public func unsafeMultiplied(by other: Self) -> Self {
let (result, overflow) = self.multipliedReportingOverflow(by: other)
@@ -3128,7 +3108,7 @@
///
/// - Parameter rhs: The value to divide this value by.
/// - Returns: The result of dividing this value by `rhs`.
- @_transparent
+ @inline(__always)
public func unsafeDivided(by other: Self) -> Self {
let (result, overflow) = self.dividedReportingOverflow(by: other)
@@ -3179,7 +3159,6 @@
/// // 'y' has a binary representation of 11111111_11101011
///
/// - Parameter source: An integer to convert to this type.
- @inlinable // FIXME(sil-serialize-all)
@inline(__always)
public init<T : BinaryInteger>(truncatingIfNeeded source: T) {
if Self.bitWidth <= Int.bitWidth {
@@ -3421,14 +3400,18 @@
/// to find an absolute value. In addition, because `abs(_:)` always returns
/// a value of the same type, even in a generic context, using the function
/// instead of the `magnitude` property is encouraged.
- @_transparent
- public var magnitude: Self { return self }
+ public var magnitude: Self {
+ @inline(__always)
+ get { return self }
+ }
/// A Boolean value indicating whether this type is a signed integer type.
///
/// This property is always `false` for unsigned integer types.
- @_transparent
- public static var isSigned: Bool { return false }
+ public static var isSigned: Bool {
+ @inline(__always)
+ get { return false }
+ }
}
extension UnsignedInteger where Self : FixedWidthInteger {
@@ -3451,7 +3434,6 @@
///
/// - Parameter source: A value to convert to this type of integer. The value
/// passed as `source` must be representable in this type.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@inline(__always)
public init<T : BinaryInteger>(_ source: T) {
@@ -3482,7 +3464,6 @@
/// // y == nil
///
/// - Parameter source: A value to convert to this type of integer.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@inline(__always)
public init?<T : BinaryInteger>(exactly source: T) {
@@ -3503,17 +3484,13 @@
/// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where
/// `**` is exponentiation.
@_transparent
- public static var max: Self {
- return ~0
- }
+ public static var max: Self { return ~0 }
/// The minimum representable integer in this type.
///
/// For unsigned integer types, this value is always `0`.
@_transparent
- public static var min: Self {
- return 0
- }
+ public static var min: Self { return 0 }
}
@@ -3532,8 +3509,10 @@
/// A Boolean value indicating whether this type is a signed integer type.
///
/// This property is always `true` for signed integer types.
- @_transparent
- public static var isSigned: Bool { return true }
+ public static var isSigned: Bool {
+ @inline(__always)
+ get { return true }
+ }
}
extension SignedInteger where Self : FixedWidthInteger {
@@ -3556,7 +3535,6 @@
///
/// - Parameter source: A value to convert to this type of integer. The value
/// passed as `source` must be representable in this type.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@inline(__always)
public init<T : BinaryInteger>(_ source: T) {
@@ -3589,7 +3567,6 @@
/// // y == nil
///
/// - Parameter source: A value to convert to this type of integer.
- @inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.partial.never")
@inline(__always)
public init?<T : BinaryInteger>(exactly source: T) {
@@ -3611,9 +3588,7 @@
/// For signed integer types, this value is `(2 ** (bitWidth - 1)) - 1`,
/// where `**` is exponentiation.
@_transparent
- public static var max: Self {
- return ~min
- }
+ public static var max: Self { return ~min }
/// The minimum representable integer in this type.
///
@@ -3657,7 +3632,7 @@
///
/// - Parameter x: The integer to convert, and instance of type `T`.
/// - Returns: The value of `x` converted to type `U`.
-@_transparent
+@inlinable
public func numericCast<T : BinaryInteger, U : BinaryInteger>(_ x: T) -> U {
return U(x)
}
@@ -3669,7 +3644,6 @@
// At the same time, since they are obsolete in Swift 4, this will not cause
// `u8 << -1` to fail due to an overflow in an unsigned value.
extension FixedWidthInteger {
- @inlinable // FIXME(sil-serialize-all)
@available(swift, obsoleted: 4)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
@@ -3679,7 +3653,6 @@
return lhs
}
- @inlinable // FIXME(sil-serialize-all)
@available(swift, obsoleted: 4)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
@@ -3687,7 +3660,6 @@
_nonMaskingRightShiftGeneric(&lhs, rhs)
}
- @inlinable // FIXME(sil-serialize-all)
@available(swift, obsoleted: 4)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
@@ -3697,7 +3669,6 @@
return lhs
}
- @inlinable // FIXME(sil-serialize-all)
@available(swift, obsoleted: 4)
@_semantics("optimize.sil.specialize.generic.partial.never")
@_transparent
@@ -3707,9 +3678,8 @@
}
extension FixedWidthInteger {
- @inlinable // FIXME(sil-serialize-all)
@available(swift, obsoleted: 4, message: "Use addingReportingOverflow(_:) instead.")
- @_transparent
+ @inlinable
public static func addWithOverflow(
_ lhs: Self, _ rhs: Self
) -> (Self, overflow: Bool) {
@@ -3718,9 +3688,8 @@
return (partialValue, overflow: overflow)
}
- @inlinable // FIXME(sil-serialize-all)
@available(swift, obsoleted: 4, message: "Use subtractingReportingOverflow(_:) instead.")
- @_transparent
+ @inlinable
public static func subtractWithOverflow(
_ lhs: Self, _ rhs: Self
) -> (Self, overflow: Bool) {
@@ -3729,9 +3698,8 @@
return (partialValue, overflow: overflow)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 4, message: "Use multipliedReportingOverflow(by:) instead.")
- @_transparent
public static func multiplyWithOverflow(
_ lhs: Self, _ rhs: Self
) -> (Self, overflow: Bool) {
@@ -3740,9 +3708,8 @@
return (partialValue, overflow: overflow)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 4, message: "Use dividedReportingOverflow(by:) instead.")
- @_transparent
public static func divideWithOverflow(
_ lhs: Self, _ rhs: Self
) -> (Self, overflow: Bool) {
@@ -3751,9 +3718,8 @@
return (partialValue, overflow: overflow)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 4, message: "Use remainderReportingOverflow(dividingBy:) instead.")
- @_transparent
public static func remainderWithOverflow(
_ lhs: Self, _ rhs: Self
) -> (Self, overflow: Bool) {
@@ -3764,7 +3730,7 @@
}
extension BinaryInteger {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 3.2,
message: "Please use FixedWidthInteger protocol as a generic constraint and addingReportingOverflow(_:) method instead.")
public static func addWithOverflow(
@@ -3773,7 +3739,7 @@
fatalError("Unavailable")
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 3.2,
message: "Please use FixedWidthInteger protocol as a generic constraint and subtractingReportingOverflow(_:) method instead.")
public static func subtractWithOverflow(
@@ -3782,7 +3748,7 @@
fatalError("Unavailable")
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 3.2,
message: "Please use FixedWidthInteger protocol as a generic constraint and multipliedReportingOverflow(by:) method instead.")
public static func multiplyWithOverflow(
@@ -3791,7 +3757,7 @@
fatalError("Unavailable")
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 3.2,
message: "Please use FixedWidthInteger protocol as a generic constraint and dividedReportingOverflow(by:) method instead.")
public static func divideWithOverflow(
@@ -3800,7 +3766,7 @@
fatalError("Unavailable")
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
@available(swift, obsoleted: 3.2,
message: "Please use FixedWidthInteger protocol as a generic constraint and remainderReportingOverflow(dividingBy:) method instead.")
public static func remainderWithOverflow(
@@ -3820,24 +3786,24 @@
// var _ = (x &+ (y - 1)) < x
// ^
extension SignedInteger {
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
public static func _maskingAdd(_ lhs: Self, _ rhs: Self) -> Self {
fatalError("Should be overridden in a more specific type")
}
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
@available(swift, obsoleted: 4.0,
message: "Please use 'FixedWidthInteger' instead of 'SignedInteger' to get '&+' in generic code.")
public static func &+ (lhs: Self, rhs: Self) -> Self {
return _maskingAdd(lhs, rhs)
}
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
public static func _maskingSubtract(_ lhs: Self, _ rhs: Self) -> Self {
fatalError("Should be overridden in a more specific type")
}
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
@available(swift, obsoleted: 4.0,
message: "Please use 'FixedWidthInteger' instead of 'SignedInteger' to get '&-' in generic code.")
public static func &- (lhs: Self, rhs: Self) -> Self {
@@ -3848,7 +3814,7 @@
extension SignedInteger where Self : FixedWidthInteger {
// This overload is supposed to break the ambiguity between the
// implementations on SignedInteger and FixedWidthInteger
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
public static func &+ (lhs: Self, rhs: Self) -> Self {
return _maskingAdd(lhs, rhs)
}
@@ -3860,7 +3826,7 @@
// This overload is supposed to break the ambiguity between the
// implementations on SignedInteger and FixedWidthInteger
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
public static func &- (lhs: Self, rhs: Self) -> Self {
return _maskingSubtract(lhs, rhs)
}
diff --git a/stdlib/public/core/Join.swift b/stdlib/public/core/Join.swift
index 44e5399..f6001c0 100644
--- a/stdlib/public/core/Join.swift
+++ b/stdlib/public/core/Join.swift
@@ -17,16 +17,16 @@
public typealias Element = Base.Element.Element
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _separator: ContiguousArray<Element>
/// Creates an iterator that presents the elements of the sequences
/// traversed by `base`, concatenated using `separator`.
///
/// - Complexity: O(`separator.count`).
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public init<Separator : Sequence>(base: Base, separator: Separator)
where Separator.Element == Element {
self._base = base
diff --git a/stdlib/public/core/MigrationSupport.swift b/stdlib/public/core/MigrationSupport.swift
index f2cfa39..b11e7c4 100644
--- a/stdlib/public/core/MigrationSupport.swift
+++ b/stdlib/public/core/MigrationSupport.swift
@@ -330,6 +330,9 @@
}
}
+@available(swift, deprecated: 5.0, renamed: "KeyValuePairs")
+public typealias DictionaryLiteral<Key, Value> = KeyValuePairs<Key, Value>
+
extension LazySequenceProtocol {
/// Returns the non-`nil` results of mapping the given transformation over
/// this sequence.
diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift
index a3cd3db..6f5271d 100644
--- a/stdlib/public/core/Mirror.swift
+++ b/stdlib/public/core/Mirror.swift
@@ -524,7 +524,6 @@
/// let pairs = IntPairs([1: 2, 1: 1, 3: 4, 2: 1])
/// print(pairs.elements)
/// // Prints "[(1, 2), (1, 1), (3, 4), (2, 1)]"
-@_fixed_layout // FIXME(sil-serialize-all)
public struct KeyValuePairs<Key, Value> : ExpressibleByDictionaryLiteral {
/// Creates a new `KeyValuePairs` instance from the given dictionary
/// literal.
@@ -534,13 +533,9 @@
public init(dictionaryLiteral elements: (Key, Value)...) {
self._elements = elements
}
- @usableFromInline // FIXME(sil-serialize-all)
internal let _elements: [(Key, Value)]
}
-@available(swift, deprecated: 5.0, renamed: "KeyValuePairs")
-public typealias DictionaryLiteral<Key, Value> = KeyValuePairs<Key, Value>
-
/// `Collection` conformance that allows `KeyValuePairs` to
/// interoperate with the rest of the standard library.
extension KeyValuePairs : RandomAccessCollection {
@@ -550,7 +545,6 @@
///
/// If the `KeyValuePairs` instance is empty, `startIndex` is equal to
/// `endIndex`.
- @inlinable // FIXME(sil-serialize-all)
public var startIndex: Int { return 0 }
/// The collection's "past the end" position---that is, the position one
@@ -558,7 +552,6 @@
///
/// If the `KeyValuePairs` instance is empty, `endIndex` is equal to
/// `startIndex`.
- @inlinable // FIXME(sil-serialize-all)
public var endIndex: Int { return _elements.endIndex }
// FIXME(ABI)#174 (Type checker): a typealias is needed to prevent <rdar://20248032>
@@ -572,7 +565,6 @@
/// must be a valid index of the collection that is not equal to the
/// `endIndex` property.
/// - Returns: The key-value pair at position `position`.
- @inlinable // FIXME(sil-serialize-all)
public subscript(position: Int) -> Element {
return _elements[position]
}
@@ -618,7 +610,6 @@
///
/// print(String(describing: p))
/// // Prints "(21, 30)"
- @inlinable // FIXME(sil-serialize-all)
public init<Subject>(describing instance: Subject) {
self.init()
_print_unlocked(instance, &self)
@@ -668,7 +659,6 @@
///
/// print(String(reflecting: p))
/// // Prints "Point(x: 21, y: 30)"
- @inlinable // FIXME(sil-serialize-all)
public init<Subject>(reflecting subject: Subject) {
self.init()
_debugPrint_unlocked(subject, &self)
diff --git a/stdlib/public/core/OptionSet.swift b/stdlib/public/core/OptionSet.swift
index c551fce..f8c6b75 100644
--- a/stdlib/public/core/OptionSet.swift
+++ b/stdlib/public/core/OptionSet.swift
@@ -142,7 +142,7 @@
/// - Parameter other: An option set.
/// - Returns: A new option set made up of the elements contained in this
/// set, in `other`, or in both.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func union(_ other: Self) -> Self {
var r: Self = Self(rawValue: self.rawValue)
r.formUnion(other)
@@ -169,7 +169,7 @@
/// - Parameter other: An option set.
/// - Returns: A new option set with only the elements contained in both this
/// set and `other`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func intersection(_ other: Self) -> Self {
var r = Self(rawValue: self.rawValue)
r.formIntersection(other)
@@ -182,7 +182,7 @@
/// - Parameter other: An option set.
/// - Returns: A new option set with only the elements contained in either
/// this set or `other`, but not in both.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func symmetricDifference(_ other: Self) -> Self {
var r = Self(rawValue: self.rawValue)
r.formSymmetricDifference(other)
@@ -212,7 +212,7 @@
/// - Parameter member: The element to look for in the option set.
/// - Returns: `true` if the option set contains `member`; otherwise,
/// `false`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func contains(_ member: Self) -> Bool {
return self.isSuperset(of: member)
}
@@ -237,7 +237,7 @@
/// - Returns: `(true, newMember)` if `newMember` was not contained in
/// `self`. Otherwise, returns `(false, oldMember)`, where `oldMember` is
/// the member of the set equal to `newMember`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
@discardableResult
public mutating func insert(
_ newMember: Element
@@ -283,7 +283,7 @@
/// - Parameter member: The element of the set to remove.
/// - Returns: The intersection of `[member]` and the set, if the
/// intersection was nonempty; otherwise, `nil`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
@discardableResult
public mutating func remove(_ member: Element) -> Element? {
let r = isSuperset(of: member) ? Optional(member) : nil
@@ -303,7 +303,7 @@
///
/// - Returns: The intersection of `[newMember]` and the set if the
/// intersection was nonempty; otherwise, `nil`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
@discardableResult
public mutating func update(with newMember: Element) -> Element? {
let r = self.intersection(newMember)
@@ -330,7 +330,7 @@
/// Creates an empty option set.
///
/// This initializer creates an option set with a raw value of zero.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public init() {
self.init(rawValue: 0)
}
@@ -341,7 +341,7 @@
/// two sets' raw values.
///
/// - Parameter other: An option set.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func formUnion(_ other: Self) {
self = Self(rawValue: self.rawValue | other.rawValue)
}
@@ -353,7 +353,7 @@
/// two sets' raw values.
///
/// - Parameter other: An option set.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func formIntersection(_ other: Self) {
self = Self(rawValue: self.rawValue & other.rawValue)
}
@@ -365,7 +365,7 @@
/// sets' raw values.
///
/// - Parameter other: An option set.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func formSymmetricDifference(_ other: Self) {
self = Self(rawValue: self.rawValue ^ other.rawValue)
}
diff --git a/stdlib/public/core/OutputStream.swift b/stdlib/public/core/OutputStream.swift
index e6c33d3..346bd43 100644
--- a/stdlib/public/core/OutputStream.swift
+++ b/stdlib/public/core/OutputStream.swift
@@ -75,9 +75,7 @@
}
extension TextOutputStream {
- @inlinable // FIXME(sil-serialize-all)
public mutating func _lock() {}
- @inlinable // FIXME(sil-serialize-all)
public mutating func _unlock() {}
}
@@ -278,7 +276,6 @@
internal func _opaqueSummary(_ metadata: Any.Type) -> UnsafePointer<CChar>?
/// Do our best to print a value that cannot be printed directly.
-@inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.never")
internal func _adHocPrint_unlocked<T, TargetStream : TextOutputStream>(
_ value: T, _ mirror: Mirror, _ target: inout TargetStream,
@@ -460,7 +457,6 @@
_adHocPrint_unlocked(value, mirror, &target, isDebugPrint: true)
}
-@inlinable // FIXME(sil-serialize-all)
@_semantics("optimize.sil.specialize.generic.never")
internal func _dumpPrint_unlocked<T, TargetStream : TextOutputStream>(
_ value: T, _ mirror: Mirror, _ target: inout TargetStream
diff --git a/stdlib/public/core/PrefixWhile.swift b/stdlib/public/core/PrefixWhile.swift
index 4c80aac..3304c60 100644
--- a/stdlib/public/core/PrefixWhile.swift
+++ b/stdlib/public/core/PrefixWhile.swift
@@ -13,19 +13,19 @@
/// A sequence whose elements consist of the initial consecutive elements of
/// some base sequence that satisfy a given predicate.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // lazy-performance
public struct LazyPrefixWhileSequence<Base: Sequence> {
public typealias Element = Base.Element
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
self._base = _base
self._predicate = predicate
}
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Element) -> Bool
}
@@ -37,18 +37,18 @@
/// This is the associated iterator for the `LazyPrefixWhileSequence`,
/// `LazyPrefixWhileCollection`, and `LazyPrefixWhileBidirectionalCollection`
/// types.
- @_fixed_layout // FIXME(sil-serialize-all)
+ @_fixed_layout // lazy-performance
public struct Iterator {
public typealias Element = Base.Element
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _predicateHasFailed = false
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base.Iterator
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Element) -> Bool
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base.Iterator, predicate: @escaping (Element) -> Bool) {
self._base = _base
self._predicate = predicate
@@ -57,7 +57,7 @@
}
extension LazyPrefixWhileSequence.Iterator: IteratorProtocol, Sequence {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public mutating func next() -> Element? {
// Return elements from the base iterator until one fails the predicate.
if !_predicateHasFailed, let nextElement = _base.next() {
@@ -74,7 +74,7 @@
extension LazyPrefixWhileSequence: Sequence {
public typealias SubSequence = AnySequence<Element> // >:(
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func makeIterator() -> Iterator {
return Iterator(_base: _base.makeIterator(), predicate: _predicate)
}
@@ -92,7 +92,7 @@
/// its argument and returns `true` if the element should be included or
/// `false` otherwise. Once `predicate` returns `false` it will not be
/// called again.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func prefix(
while predicate: @escaping (Elements.Element) -> Bool
) -> LazyPrefixWhileSequence<Self.Elements> {
@@ -109,27 +109,27 @@
/// the usual performance given by the `Collection` protocol. Be aware,
/// therefore, that general operations on `${Self}` instances may not have
/// the documented complexity.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // lazy-performance
public struct LazyPrefixWhileCollection<Base: Collection> {
public typealias Element = Base.Element
public typealias SubSequence = Slice<LazyPrefixWhileCollection<Base>>
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
self._base = _base
self._predicate = predicate
}
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal var _base: Base
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _predicate: (Element) -> Bool
}
extension LazyPrefixWhileCollection: Sequence {
public typealias Iterator = LazyPrefixWhileSequence<Base>.Iterator
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func makeIterator() -> Iterator {
return Iterator(_base: _base.makeIterator(), predicate: _predicate)
}
@@ -138,7 +138,7 @@
extension LazyPrefixWhileCollection {
/// A position in the base collection of a `LazyPrefixWhileCollection` or the
/// end of that collection.
- @_frozen // FIXME(sil-serialize-all)
+ @_frozen // lazy-performance
@usableFromInline
internal enum _IndexRepresentation {
case index(Base.Index)
@@ -147,14 +147,14 @@
/// A position in a `LazyPrefixWhileCollection` or
/// `LazyPrefixWhileBidirectionalCollection` instance.
- @_fixed_layout // FIXME(sil-serialize-all)
+ @_fixed_layout // lazy-performance
public struct Index {
/// The position corresponding to `self` in the underlying collection.
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // lazy-performance
internal let _value: _IndexRepresentation
/// Creates a new index wrapper for `i`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(_ i: Base.Index) {
self._value = .index(i)
}
@@ -162,7 +162,7 @@
/// Creates a new index that can represent the `endIndex` of a
/// `LazyPrefixWhileCollection<Base>`. This is not the same as a wrapper
/// around `Base.endIndex`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
internal init(endOf: Base) {
self._value = .pastEnd
}
@@ -170,7 +170,7 @@
}
extension LazyPrefixWhileCollection.Index: Comparable {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public static func == (
lhs: LazyPrefixWhileCollection<Base>.Index,
rhs: LazyPrefixWhileCollection<Base>.Index
@@ -185,7 +185,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public static func < (
lhs: LazyPrefixWhileCollection<Base>.Index,
rhs: LazyPrefixWhileCollection<Base>.Index
@@ -219,12 +219,12 @@
}
extension LazyPrefixWhileCollection: Collection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public var startIndex: Index {
return Index(_base.startIndex)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public var endIndex: Index {
// If the first element of `_base` satisfies the predicate, there is at
// least one element in the lazy collection: Use the explicit `.pastEnd` index.
@@ -237,7 +237,7 @@
return startIndex
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func index(after i: Index) -> Index {
_precondition(i != endIndex, "Can't advance past endIndex")
guard case .index(let i) = i._value else {
@@ -250,7 +250,7 @@
return Index(nextIndex)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public subscript(position: Index) -> Element {
switch position._value {
case .index(let i):
@@ -263,7 +263,7 @@
extension LazyPrefixWhileCollection: BidirectionalCollection
where Base: BidirectionalCollection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func index(before i: Index) -> Index {
switch i._value {
case .index(let i):
@@ -303,7 +303,7 @@
/// as its argument and returns `true` if the element should be included
/// or `false` otherwise. Once `predicate` returns `false` it will not be
/// called again.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // lazy-performance
public func prefix(
while predicate: @escaping (Element) -> Bool
) -> LazyPrefixWhileCollection<Elements> {
diff --git a/stdlib/public/core/Range.swift b/stdlib/public/core/Range.swift
index 935b680..0643af6 100644
--- a/stdlib/public/core/Range.swift
+++ b/stdlib/public/core/Range.swift
@@ -762,7 +762,7 @@
/// let word2 = "grisly"
/// let changes = countLetterChanges(word1[...], word2[...])
/// // changes == 2
-@_frozen // FIXME(sil-serialize-all)
+@_frozen // namespace
public enum UnboundedRange_ {
// FIXME: replace this with a computed var named `...` when the language makes
// that possible.
@@ -771,7 +771,6 @@
///
/// The unbounded range operator (`...`) is valid only within a collection's
/// subscript.
- @inlinable // FIXME(sil-serialize-all)
public static postfix func ... (_: UnboundedRange_) -> () {
fatalError("uncallable")
}
@@ -844,7 +843,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable
public subscript(x: UnboundedRange) -> SubSequence {
get {
return self[startIndex...]
diff --git a/stdlib/public/core/SequenceWrapper.swift b/stdlib/public/core/SequenceWrapper.swift
index cb9bf68..85833b2 100644
--- a/stdlib/public/core/SequenceWrapper.swift
+++ b/stdlib/public/core/SequenceWrapper.swift
@@ -27,12 +27,12 @@
}
extension _SequenceWrapper {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public var underestimatedCount: Int {
return _base.underestimatedCount
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func _preprocessingPass<R>(
_ preprocess: () throws -> R
) rethrows -> R? {
@@ -41,12 +41,12 @@
}
extension _SequenceWrapper where Iterator == Base.Iterator {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func makeIterator() -> Iterator {
return self._base.makeIterator()
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
@discardableResult
public func _copyContents(
initializing buf: UnsafeMutableBufferPointer<Element>
@@ -56,33 +56,33 @@
}
extension _SequenceWrapper {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
return try _base.map(transform)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
return try _base.filter(isIncluded)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func forEach(_ body: (Element) throws -> Void) rethrows {
return try _base.forEach(body)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func _customContainsEquatableElement(
_ element: Element
) -> Bool? {
return _base._customContainsEquatableElement(element)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func _copyToContiguousArray()
-> ContiguousArray<Element> {
return _base._copyToContiguousArray()
@@ -90,38 +90,38 @@
}
extension _SequenceWrapper where SubSequence == Base.SubSequence {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func dropFirst(_ n: Int) -> SubSequence {
return _base.dropFirst(n)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func dropLast(_ n: Int) -> SubSequence {
return _base.dropLast(n)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func prefix(_ maxLength: Int) -> SubSequence {
return _base.prefix(maxLength)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func suffix(_ maxLength: Int) -> SubSequence {
return _base.suffix(maxLength)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func drop(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence {
return try _base.drop(while: predicate)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func prefix(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence {
return try _base.prefix(while: predicate)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func split(
maxSplits: Int, omittingEmptySubsequences: Bool,
whereSeparator isSeparator: (Element) throws -> Bool
diff --git a/stdlib/public/core/Slice.swift b/stdlib/public/core/Slice.swift
index 139a52b..01cf1d6 100644
--- a/stdlib/public/core/Slice.swift
+++ b/stdlib/public/core/Slice.swift
@@ -79,12 +79,12 @@
/// collection type, don't use `Slice` as its subsequence type. Instead,
/// define your own subsequence type that takes your index invalidation
/// requirements into account.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // generic-performance
public struct Slice<Base: Collection> {
public var _startIndex: Base.Index
public var _endIndex: Base.Index
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal var _base: Base
/// Creates a view into the given collection that allows access to elements
@@ -106,7 +106,7 @@
/// - Parameters:
/// - base: The collection to create a view into.
/// - bounds: The range of indices to allow access to in the new slice.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public init(base: Base, bounds: Range<Base.Index>) {
self._base = base
self._startIndex = bounds.lowerBound
@@ -131,7 +131,7 @@
/// // Prints "10"
/// print(singleDigits == singleNonZeroDigits.base)
/// // Prints "true"
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public var base: Base {
return _base
}
@@ -144,17 +144,17 @@
public typealias SubSequence = Slice<Base>
public typealias Iterator = IndexingIterator<Slice<Base>>
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public var startIndex: Index {
return _startIndex
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public var endIndex: Index {
return _endIndex
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public subscript(index: Index) -> Base.Element {
get {
_failEarlyRangeCheck(index, bounds: startIndex..<endIndex)
@@ -162,7 +162,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public subscript(bounds: Range<Index>) -> Slice<Base> {
get {
_failEarlyRangeCheck(bounds, bounds: startIndex..<endIndex)
@@ -174,25 +174,25 @@
return _base.indices[_startIndex..<_endIndex]
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func index(after i: Index) -> Index {
// FIXME: swift-3-indexing-model: range check.
return _base.index(after: i)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func formIndex(after i: inout Index) {
// FIXME: swift-3-indexing-model: range check.
_base.formIndex(after: &i)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func index(_ i: Index, offsetBy n: Int) -> Index {
// FIXME: swift-3-indexing-model: range check.
return _base.index(i, offsetBy: n)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func index(
_ i: Index, offsetBy n: Int, limitedBy limit: Index
) -> Index? {
@@ -200,31 +200,31 @@
return _base.index(i, offsetBy: n, limitedBy: limit)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func distance(from start: Index, to end: Index) -> Int {
// FIXME: swift-3-indexing-model: range check.
return _base.distance(from: start, to: end)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func _failEarlyRangeCheck(_ index: Index, bounds: Range<Index>) {
_base._failEarlyRangeCheck(index, bounds: bounds)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func _failEarlyRangeCheck(_ range: Range<Index>, bounds: Range<Index>) {
_base._failEarlyRangeCheck(range, bounds: bounds)
}
}
extension Slice: BidirectionalCollection where Base: BidirectionalCollection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func index(before i: Index) -> Index {
// FIXME: swift-3-indexing-model: range check.
return _base.index(before: i)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func formIndex(before i: inout Index) {
// FIXME: swift-3-indexing-model: range check.
_base.formIndex(before: &i)
@@ -233,7 +233,7 @@
extension Slice: MutableCollection where Base: MutableCollection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public subscript(index: Index) -> Base.Element {
get {
_failEarlyRangeCheck(index, bounds: startIndex..<endIndex)
@@ -248,7 +248,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public subscript(bounds: Range<Index>) -> Slice<Base> {
get {
_failEarlyRangeCheck(bounds, bounds: startIndex..<endIndex)
@@ -265,28 +265,28 @@
extension Slice: RangeReplaceableCollection
where Base: RangeReplaceableCollection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public init() {
self._base = Base()
self._startIndex = _base.startIndex
self._endIndex = _base.endIndex
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public init(repeating repeatedValue: Base.Element, count: Int) {
self._base = Base(repeating: repeatedValue, count: count)
self._startIndex = _base.startIndex
self._endIndex = _base.endIndex
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public init<S>(_ elements: S) where S: Sequence, S.Element == Base.Element {
self._base = Base(elements)
self._startIndex = _base.startIndex
self._endIndex = _base.endIndex
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func replaceSubrange<C>(
_ subRange: Range<Index>, with newElements: C
) where C : Collection, C.Element == Base.Element {
@@ -303,7 +303,7 @@
_endIndex = _base.index(_startIndex, offsetBy: newSliceCount)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func insert(_ newElement: Base.Element, at i: Index) {
// FIXME: swift-3-indexing-model: range check.
let sliceOffset = _base.distance(from: _base.startIndex, to: _startIndex)
@@ -313,7 +313,7 @@
_endIndex = _base.index(_startIndex, offsetBy: newSliceCount)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func insert<S>(contentsOf newElements: S, at i: Index)
where S: Collection, S.Element == Base.Element {
@@ -325,7 +325,7 @@
_endIndex = _base.index(_startIndex, offsetBy: newSliceCount)
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func remove(at i: Index) -> Base.Element {
// FIXME: swift-3-indexing-model: range check.
let sliceOffset = _base.distance(from: _base.startIndex, to: _startIndex)
@@ -336,7 +336,7 @@
return result
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func removeSubrange(_ bounds: Range<Index>) {
// FIXME: swift-3-indexing-model: range check.
let sliceOffset = _base.distance(from: _base.startIndex, to: _startIndex)
@@ -351,7 +351,7 @@
extension Slice
where Base: RangeReplaceableCollection, Base: BidirectionalCollection {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func replaceSubrange<C>(
_ subRange: Range<Index>, with newElements: C
) where C : Collection, C.Element == Base.Element {
@@ -378,7 +378,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func insert(_ newElement: Base.Element, at i: Index) {
// FIXME: swift-3-indexing-model: range check.
if i == _base.startIndex {
@@ -398,7 +398,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func insert<S>(contentsOf newElements: S, at i: Index)
where S : Collection, S.Element == Base.Element {
// FIXME: swift-3-indexing-model: range check.
@@ -421,7 +421,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func remove(at i: Index) -> Base.Element {
// FIXME: swift-3-indexing-model: range check.
if i == _base.startIndex {
@@ -443,7 +443,7 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func removeSubrange(_ bounds: Range<Index>) {
// FIXME: swift-3-indexing-model: range check.
if bounds.lowerBound == _base.startIndex {
diff --git a/stdlib/public/core/StaticString.swift b/stdlib/public/core/StaticString.swift
index b7d17c2..16c4402 100644
--- a/stdlib/public/core/StaticString.swift
+++ b/stdlib/public/core/StaticString.swift
@@ -130,7 +130,7 @@
/// `withUTF8Buffer(invoke:)` method. The pointer argument is valid only
/// for the duration of the method's execution.
/// - Returns: The return value, if any, of the `body` closure.
- @inlinable // FIXME(sil-serialize-all)
+ @_transparent
public func withUTF8Buffer<R>(
_ body: (UnsafeBufferPointer<UInt8>) -> R) -> R {
if hasPointerRepresentation {
@@ -187,7 +187,6 @@
: (0x1 as UInt8)._value
}
- @inlinable // FIXME(sil-serialize-all)
@_effects(readonly)
@_transparent
public init(_builtinUnicodeScalarLiteral value: Builtin.Int32) {
@@ -198,14 +197,12 @@
///
/// Do not call this initializer directly. It may be used by the compiler
/// when you initialize a static string with a Unicode scalar.
- @inlinable // FIXME(sil-serialize-all)
@_effects(readonly)
@_transparent
public init(unicodeScalarLiteral value: StaticString) {
self = value
}
- @inlinable // FIXME(sil-serialize-all)
@_effects(readonly)
@_transparent
public init(
@@ -225,14 +222,12 @@
///
/// Do not call this initializer directly. It may be used by the compiler
/// when you initialize a static string using an extended grapheme cluster.
- @inlinable // FIXME(sil-serialize-all)
@_effects(readonly)
@_transparent
public init(extendedGraphemeClusterLiteral value: StaticString) {
self = value
}
- @inlinable // FIXME(sil-serialize-all)
@_effects(readonly)
@_transparent
public init(
@@ -250,7 +245,6 @@
///
/// Do not call this initializer directly. It may be used by the compiler
/// when you initialize a static string using a string literal.
- @inlinable // FIXME(sil-serialize-all)
@_effects(readonly)
@_transparent
public init(stringLiteral value: StaticString) {
@@ -258,7 +252,6 @@
}
/// A string representation of the static string.
- @inlinable // FIXME(sil-serialize-all)
public var description: String {
return withUTF8Buffer { (buffer) in
if isASCII {
diff --git a/stdlib/public/core/StringProtocol.swift b/stdlib/public/core/StringProtocol.swift
index 8842115..09ef393 100644
--- a/stdlib/public/core/StringProtocol.swift
+++ b/stdlib/public/core/StringProtocol.swift
@@ -29,6 +29,8 @@
associatedtype UnicodeScalarView : BidirectionalCollection
where UnicodeScalarView.Element == Unicode.Scalar
+
+ associatedtype SubSequence = Substring
var utf8: UTF8View { get }
var utf16: UTF16View { get }
diff --git a/stdlib/public/core/UnfoldSequence.swift b/stdlib/public/core/UnfoldSequence.swift
index 9d9a8fe..bc4e82c 100644
--- a/stdlib/public/core/UnfoldSequence.swift
+++ b/stdlib/public/core/UnfoldSequence.swift
@@ -38,7 +38,7 @@
/// returns the next element.
/// - Returns: A sequence that starts with `first` and continues with every
/// value returned by passing the previous element to `next`.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable // generic-performance
public func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence<T> {
// The trivial implementation where the state is the next value to return
// has the downside of being unnecessarily eager (it evaluates `next` one
@@ -83,7 +83,7 @@
/// - Parameter next: A closure that accepts an `inout` state and returns the
/// next element of the sequence.
/// - Returns: A sequence that yields each successive value from `next`.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable // generic-performance
public func sequence<T, State>(state: State, next: @escaping (inout State) -> T?)
-> UnfoldSequence<T, State> {
return UnfoldSequence(_state: state, _next: next)
@@ -100,9 +100,9 @@
///
/// Instances of `UnfoldSequence` are created with the functions
/// `sequence(first:next:)` and `sequence(state:next:)`.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // generic-performance
public struct UnfoldSequence<Element, State> : Sequence, IteratorProtocol {
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func next() -> Element? {
guard !_done else { return nil }
if let elt = _next(&_state) {
@@ -113,16 +113,16 @@
}
}
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
internal init(_state: State, _next: @escaping (inout State) -> Element?) {
self._state = _state
self._next = _next
}
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal var _state: State
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal let _next: (inout State) -> Element?
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal var _done = false
}
diff --git a/stdlib/public/core/Unmanaged.swift b/stdlib/public/core/Unmanaged.swift
index 08e0b0e..24d97a5 100644
--- a/stdlib/public/core/Unmanaged.swift
+++ b/stdlib/public/core/Unmanaged.swift
@@ -89,7 +89,7 @@
/// and you know that you're not responsible for releasing the result.
///
/// - Returns: The object referenced by this `Unmanaged` instance.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // unsafe-performance
public func takeUnretainedValue() -> Instance {
return _value
}
@@ -101,7 +101,7 @@
/// and you know that you're responsible for releasing the result.
///
/// - Returns: The object referenced by this `Unmanaged` instance.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // unsafe-performance
public func takeRetainedValue() -> Instance {
let result = _value
release()
@@ -200,7 +200,7 @@
/// }
/// }
/// }
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // unsafe-performance
public func _withUnsafeGuaranteedRef<Result>(
_ body: (Instance) throws -> Result
) rethrows -> Result {
diff --git a/stdlib/public/core/Zip.swift b/stdlib/public/core/Zip.swift
index 5bb3dc5..b97fe84 100644
--- a/stdlib/public/core/Zip.swift
+++ b/stdlib/public/core/Zip.swift
@@ -41,7 +41,7 @@
/// - sequence2: The second sequence or collection to zip.
/// - Returns: A sequence of tuple pairs, where the elements of each pair are
/// corresponding elements of `sequence1` and `sequence2`.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable // generic-performance
public func zip<Sequence1, Sequence2>(
_ sequence1: Sequence1, _ sequence2: Sequence2
) -> Zip2Sequence<Sequence1, Sequence2> {
@@ -67,16 +67,16 @@
/// // Prints "two: 2
/// // Prints "three: 3"
/// // Prints "four: 4"
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout // generic-performance
public struct Zip2Sequence<Sequence1 : Sequence, Sequence2 : Sequence> {
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal let _sequence1: Sequence1
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal let _sequence2: Sequence2
/// Creates an instance that makes pairs of elements from `sequence1` and
/// `sequence2`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public // @testable
init(_sequence1 sequence1: Sequence1, _sequence2 sequence2: Sequence2) {
(_sequence1, _sequence2) = (sequence1, sequence2)
@@ -85,17 +85,17 @@
extension Zip2Sequence {
/// An iterator for `Zip2Sequence`.
- @_fixed_layout // FIXME(sil-serialize-all)
+ @_fixed_layout // generic-performance
public struct Iterator {
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal var _baseStream1: Sequence1.Iterator
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal var _baseStream2: Sequence2.Iterator
- @usableFromInline // FIXME(sil-serialize-all)
+ @usableFromInline // generic-performance
internal var _reachedEnd: Bool = false
/// Creates an instance around a pair of underlying iterators.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
internal init(
_ iterator1: Sequence1.Iterator,
_ iterator2: Sequence2.Iterator
@@ -113,7 +113,7 @@
/// exists.
///
/// Once `nil` has been returned, all subsequent calls return `nil`.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public mutating func next() -> Element? {
// The next() function needs to track if it has reached the end. If we
// didn't, and the first sequence is longer than the second, then when we
@@ -139,7 +139,7 @@
public typealias Element = (Sequence1.Element, Sequence2.Element)
/// Returns an iterator over the elements of this sequence.
- @inlinable // FIXME(sil-serialize-all)
+ @inlinable // generic-performance
public func makeIterator() -> Iterator {
return Iterator(
_sequence1.makeIterator(),
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 993c5d7..ecdffda 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -3620,11 +3620,13 @@
return false;
}
- // If we don't have resilient witnesses, the template must provide
- // everything.
- assert (genericTable->WitnessTableSizeInWords ==
+ // If we don't have the exact number of witnesses expected, we require
+ // instantiation.
+ if (genericTable->WitnessTableSizeInWords !=
(genericTable->Protocol->NumRequirements +
- WitnessTableFirstRequirementOffset));
+ WitnessTableFirstRequirementOffset)) {
+ return false;
+ }
// If we have an instantiation function or private data, we require
// instantiation.
@@ -3643,39 +3645,46 @@
auto protocol = genericTable->Protocol.get();
auto requirements = protocol->getRequirements();
- auto witnesses = genericTable->ResilientWitnesses->getWitnesses();
+ llvm::ArrayRef<TargetResilientWitness<InProcess>> witnesses;
+ if (auto resilientWitnesses = genericTable->ResilientWitnesses.get())
+ witnesses = resilientWitnesses->getWitnesses();
+ // Loop over the provided witnesses, filling in appropriate entry.
+ for (const auto &witness : witnesses) {
+ // Retrieve the requirement descriptor.
+ 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./
+ if (!reqDescriptor) continue;
+
+ // If the requirement descriptor doesn't land within the bounds of the
+ // requirements, abort.
+ if (reqDescriptor < requirements.begin() ||
+ reqDescriptor >= requirements.end()) {
+ fatalError(0, "generic witness table at %p contains out-of-bounds "
+ "requirement descriptor %p\n",
+ genericTable, reqDescriptor);
+ }
+
+ unsigned witnessIndex = (reqDescriptor - requirements.data()) +
+ WitnessTableFirstRequirementOffset;
+
+ table[witnessIndex] = witness.Witness.get();
+ }
+
+ // Loop over the requirements, filling in default implementations where
+ // needed.
for (size_t i = 0, e = protocol->NumRequirements; i < e; ++i) {
- auto &reqt = requirements[i];
-
- // Only certain requirements are filled in from the resilient witness table.
- switch (reqt.Flags.getKind()) {
- case ProtocolRequirementFlags::Kind::Method:
- case ProtocolRequirementFlags::Kind::Init:
- case ProtocolRequirementFlags::Kind::Getter:
- case ProtocolRequirementFlags::Kind::Setter:
- case ProtocolRequirementFlags::Kind::ReadCoroutine:
- case ProtocolRequirementFlags::Kind::ModifyCoroutine:
- case ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction:
- break;
- case ProtocolRequirementFlags::Kind::BaseProtocol:
- case ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction:
- continue;
- }
-
- void *impl = reqt.DefaultImplementation.get();
-
- // Find the witness if there is one, otherwise we use the default.
- for (auto &witness : witnesses) {
- if (witness.Requirement.get() == &reqt) {
- impl = witness.Witness.get();
- break;
- }
- }
-
- assert(impl != nullptr && "no implementation for witness");
-
unsigned witnessIndex = WitnessTableFirstRequirementOffset + i;
+
+ // 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;
}
}
@@ -3716,8 +3725,7 @@
}
// Fill in any default requirements.
- if (genericTable->ResilientWitnesses)
- initializeResilientWitnessTable(genericTable, table);
+ initializeResilientWitnessTable(genericTable, table);
auto castTable = reinterpret_cast<WitnessTable*>(table);
diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt
index 35fe8a3..57244a9 100644
--- a/test/Demangle/Inputs/manglings.txt
+++ b/test/Demangle/Inputs/manglings.txt
@@ -332,3 +332,4 @@
$S1T19protocol_resilience17ResilientProtocolPTl --> associated type descriptor for T
$S18resilient_protocol21ResilientBaseProtocolTL --> protocol requirements base descriptor for resilient_protocol.ResilientBaseProtocol
$S1t1PP10AssocType2_AA1QTn --> associated conformance descriptor for t.P.AssocType2: t.Q
+$S1t1PP10AssocType2_AA1QTN --> default associated conformance accessor for t.P.AssocType2: t.Q
diff --git a/test/IRGen/abi_v7k.swift b/test/IRGen/abi_v7k.swift
index 2bb0163..d4b1af0 100644
--- a/test/IRGen/abi_v7k.swift
+++ b/test/IRGen/abi_v7k.swift
@@ -270,10 +270,10 @@
// double in d0, i32 in r0, return in d0,...,d3
// V7K: vmov [[ID:s[0-9]+]], r0
// V7K: vcvt.f64.s32 [[ID2:d[0-9]+]], [[ID]]
-// V7K: vstr d0, [sp]
+// V7K: vstr d0, [sp, #8]
// V7K: vmov.f64 d0, [[ID2]]
// V7K: bl
-// V7K: vldr [[ID3:d[0-9]+]], [sp]
+// V7K: vldr [[ID3:d[0-9]+]], [sp, #8]
// V7K: vmov.f64 d2, [[ID3]]
func testRet2(w : Double, i : Int) -> MyRect {
var r = MyRect(x : Double(i), y : 2.0, w : 3.0, h : 4.0)
diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift
index 7dd512e..5f6c8ca 100644
--- a/test/IRGen/protocol_resilience_descriptors.swift
+++ b/test/IRGen/protocol_resilience_descriptors.swift
@@ -14,6 +14,7 @@
// Protocol descriptor
// CHECK-DEFINITION-LABEL: @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsMp" ={{( protected)?}} constant
+// CHECK-DEFINITION-SAME: @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0TN"
// CHECK-DEFINITION-SAME: $S2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPTM
// CHECK-DEFINITION-SAME: $S2T218resilient_protocol29ProtocolWithAssocTypeDefaultsPTM
@@ -25,6 +26,9 @@
// CHECK-DEFINITION: @"$S1T18resilient_protocol24ProtocolWithRequirementsPTl" ={{( dllexport)?}}{{( protected)?}} alias
// CHECK-DEFINITION: @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0Tn" ={{( dllexport)?}}{{( protected)?}} alias
+// Default associated conformance witnesses
+// CHECK-DEFINITION-LABEL: define internal swiftcc i8** @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0TN"
+
// Default associated type witnesses
// CHECK-DEFINITION-LABEL: define internal swiftcc %swift.metadata_response @"$S2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPTM"
@@ -32,6 +36,8 @@
// CHECK-DEFINITION: getelementptr inbounds i8*, i8** [[WTABLE:%.*]], i32 2
// CHECK-DEFINITION: call{{.*}}S18resilient_protocol7WrapperVMa
+// CHECK-DEFINITION-LABEL: define internal swiftcc %swift.metadata_response @"$S9AssocType18resilient_protocol20ResilientSelfDefaultPTM
+
import resilient_protocol
// ----------------------------------------------------------------------------
@@ -51,6 +57,12 @@
public struct ConditionallyConforms<Element> { }
public struct Y { }
+// CHECK-USAGE: @"$S31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAAWr" = internal
+// CHECK-USAGE-SAME: $S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0Tn
+// CHECK-USAGE-SAME: $S31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAA2T2_AD014OtherResilientI0PWT
+public struct ConformsWithAssocRequirements : ProtocolWithAssocTypeDefaults {
+}
+
// CHECK-USAGE: @"$Sx1T_MXA" =
// CHECK-USAGE-SAME: i32 0
// CHECK-USAGE-SAME: @"{{got.|__imp_}}$S18resilient_protocol24ProtocolWithRequirementsMp"
diff --git a/test/Inputs/resilient_protocol.swift b/test/Inputs/resilient_protocol.swift
index e6dfcb8..9a93674 100644
--- a/test/Inputs/resilient_protocol.swift
+++ b/test/Inputs/resilient_protocol.swift
@@ -34,3 +34,7 @@
associatedtype T1 = Self
associatedtype T2: OtherResilientProtocol = Wrapper<T1>
}
+
+public protocol ResilientSelfDefault : ResilientBaseProtocol {
+ associatedtype AssocType: ResilientBaseProtocol = Self
+}
diff --git a/test/ModuleInterface/final.swift b/test/ModuleInterface/final.swift
new file mode 100644
index 0000000..a3ff6b1
--- /dev/null
+++ b/test/ModuleInterface/final.swift
@@ -0,0 +1,41 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule -emit-interface-path %t/Test.swiftinterface -module-name Test %s
+// RUN: %FileCheck %s < %t/Test.swiftinterface
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-interface-path - -module-name Test | %FileCheck %s
+
+// CHECK: final public class FinalClass {
+public final class FinalClass {
+ // CHECK: @inlinable final public class var a: [[INT:(Swift.)?Int]] {
+ // CHECK-NEXT: return 3
+ // CHECK-NEXT: }
+ @inlinable
+ public final class var a: Int {
+ return 3
+ }
+
+ // CHECK: final public class var b: [[INT]] {
+ // CHECK-NEXT: {{^}} @inlinable get {
+ // CHECK-NEXT: return 3
+ // CHECK-NEXT: }
+ // CHECK-NEXT: set[[NEWVALUE:(\(newValue\))?]]{{$}}
+ // CHECK-NEXT: }
+ public final class var b: Int {
+ @inlinable get {
+ return 3
+ }
+ set {
+ print("x")
+ }
+ }
+
+ // CHECK: public static var c: [[INT]] {
+ // CHECK-NEXT: {{^}} get
+ // CHECK-NEXT: @inlinable set[[NEWVALUE]] {}
+ // CHECK-NEXT: }
+ public static var c: Int {
+ get {
+ return 0
+ }
+ @inlinable set {}
+ }
+}
diff --git a/test/SIL/Parser/default_witness_tables.sil b/test/SIL/Parser/default_witness_tables.sil
index bb1b8e9..8153e21 100644
--- a/test/SIL/Parser/default_witness_tables.sil
+++ b/test/SIL/Parser/default_witness_tables.sil
@@ -48,7 +48,7 @@
// CHECK-LABEL: sil_default_witness_table ResilientProtocol {
-// CHECK: no_default
+// CHECK: associated_type_protocol (T: Proto): Wrapper<Self>: specialize <Self> (<T> Wrapper<T>: Proto module witness_tables)
// CHECK: associated_type T: Wrapper<Self>
// CHECK: no_default
// CHECK: no_default
@@ -58,7 +58,7 @@
// CHECK: }
sil_default_witness_table ResilientProtocol {
- no_default
+ associated_type_protocol (T: Proto): Wrapper<Self>: specialize <Self> (<T> Wrapper<T>: Proto module witness_tables)
associated_type T: Wrapper<Self>
no_default
no_default
diff --git a/test/SILGen/protocol_resilience.swift b/test/SILGen/protocol_resilience.swift
index e930bfb..e75df7e 100644
--- a/test/SILGen/protocol_resilience.swift
+++ b/test/SILGen/protocol_resilience.swift
@@ -251,6 +251,13 @@
inoutFunc(&OtherConformingType.staticPropertyInExtension)
}
+// Protocol is public -- needs resilient witness table
+public struct ConformsToP: P { }
+
+public protocol ResilientAssocTypes {
+ associatedtype AssocType: P = ConformsToP
+}
+
// CHECK-LABEL: sil_default_witness_table P {
// CHECK-NEXT: }
@@ -312,3 +319,8 @@
// CHECK-NEXT: method #ReabstractSelfRefined.callback!setter.1: {{.*}} : @$S19protocol_resilience21ReabstractSelfRefinedP8callbackyxxcvs
// CHECK-NEXT: method #ReabstractSelfRefined.callback!modify.1: {{.*}} : @$S19protocol_resilience21ReabstractSelfRefinedP8callbackyxxcvM
// CHECK-NEXT: }
+
+// CHECK-LABEL: sil_default_witness_table ResilientAssocTypes {
+// CHECK-NEXT: associated_type_protocol (AssocType: P): ConformsToP: P module protocol_resilience
+// CHECK-NEXT: associated_type AssocType: ConformsToP
+// CHECK-NEXT: }
diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift
index 34e9637..5ae49f9 100644
--- a/test/api-digester/Inputs/cake.swift
+++ b/test/api-digester/Inputs/cake.swift
@@ -40,4 +40,11 @@
public extension Int {
public func foo() {}
-}
\ No newline at end of file
+}
+
+@_fixed_layout
+public struct fixedLayoutStruct {
+ public var a = 1
+ private var b = 2
+ var c = 3
+}
diff --git a/test/api-digester/Inputs/cake1.swift b/test/api-digester/Inputs/cake1.swift
index 7ec7e43..f0df08f 100644
--- a/test/api-digester/Inputs/cake1.swift
+++ b/test/api-digester/Inputs/cake1.swift
@@ -47,3 +47,21 @@
public extension P1 where Self: P2 {
func P1Constraint() {}
}
+
+@_fixed_layout
+public struct fixedLayoutStruct {
+ public var b = 2
+ public func foo() {}
+ public var a = 1
+}
+
+@_frozen
+public enum FrozenKind {
+ case Unchanged
+ case Fixed
+ case Rigid
+}
+
+public class C7 {
+ public func foo(_ a: Int = 1, _ b: Int = 2) {}
+}
\ No newline at end of file
diff --git a/test/api-digester/Inputs/cake2.swift b/test/api-digester/Inputs/cake2.swift
index 651ac79..921982f 100644
--- a/test/api-digester/Inputs/cake2.swift
+++ b/test/api-digester/Inputs/cake2.swift
@@ -47,3 +47,26 @@
public extension P1 {
func P1Constraint() {}
}
+
+@_fixed_layout
+public struct fixedLayoutStruct {
+ public var a = 1
+ public func OKChange() {}
+ private static let constant = 0
+ public var b = 2
+ public func foo() {}
+ private var c = 3
+ private lazy var lazy_d = 4
+}
+
+@_frozen
+public enum FrozenKind {
+ case Unchanged
+ case Rigid
+ case Fixed
+ case AddedCase
+}
+
+public class C7 {
+ public func foo(_ a: Int, _ b: Int) {}
+}
\ No newline at end of file
diff --git a/test/api-digester/Outputs/Cake-abi.txt b/test/api-digester/Outputs/Cake-abi.txt
index 093eff1..fb58af1 100644
--- a/test/api-digester/Outputs/Cake-abi.txt
+++ b/test/api-digester/Outputs/Cake-abi.txt
@@ -6,6 +6,7 @@
/* Removed Decls */
cake1: Constructor Somestruct2.init(_:) has been removed
+cake1: Constructor fixedLayoutStruct.init(b:a:) has been removed
cake1: Func C4.foo() has been removed
/* Moved Decls */
@@ -17,6 +18,8 @@
/* Type Changes */
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
+cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
+cake1: Func C7.foo(_:_:) has removed default argument from parameter 1
cake1: Func Somestruct2.foo1(_:) has parameter 0 type change from C3 to C1
/* Decl Attribute changes */
@@ -29,3 +32,12 @@
cake1: Struct C6 is now with @_fixed_layout
cake1: Var C1.CIIns1 changes from weak to strong
cake1: Var C1.CIIns2 changes from strong to weak
+
+/* Fixed-layout Type changes */
+cake1: EnumElement FrozenKind.Fixed in a non-resilient type changes position from 1 to 2
+cake1: EnumElement FrozenKind.Rigid in a non-resilient type changes position from 2 to 1
+cake1: Var fixedLayoutStruct.a in a non-resilient type changes position from 1 to 0
+cake1: Var fixedLayoutStruct.b in a non-resilient type changes position from 0 to 1
+cake2: EnumElement FrozenKind.AddedCase is added to a non-resilient type
+cake2: Var fixedLayoutStruct.c is added to a non-resilient type
+cake2: Var fixedLayoutStruct.lazy_d.storage is added to a non-resilient type
\ No newline at end of file
diff --git a/test/api-digester/Outputs/Cake.txt b/test/api-digester/Outputs/Cake.txt
index e46efe9..0727459 100644
--- a/test/api-digester/Outputs/Cake.txt
+++ b/test/api-digester/Outputs/Cake.txt
@@ -6,6 +6,7 @@
/* Removed Decls */
cake1: Constructor Somestruct2.init(_:) has been removed
+cake1: Constructor fixedLayoutStruct.init(b:a:) has been removed
cake1: Func C4.foo() has been removed
/* Moved Decls */
@@ -17,6 +18,8 @@
/* Type Changes */
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
+cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
+cake1: Func C7.foo(_:_:) has removed default argument from parameter 1
/* Decl Attribute changes */
cake1: Func C1.foo1() is now not static
diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/cake-abi.json
index 3a068eb..b980795 100644
--- a/test/api-digester/Outputs/cake-abi.json
+++ b/test/api-digester/Outputs/cake-abi.json
@@ -95,6 +95,7 @@
"usr": "s:4cake2S1VACycfc",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -125,6 +126,7 @@
"location": "",
"moduleName": "cake",
"genericSig": "<τ_0_0, τ_0_1, τ_0_2>",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -241,6 +243,7 @@
"usr": "s:4cake2C1C3InsACSgXwvg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -269,6 +272,7 @@
"usr": "s:4cake2C1C3InsACSgXwvs",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -323,6 +327,7 @@
"usr": "s:4cake2C1C4Ins2ACXovg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -343,6 +348,7 @@
"usr": "s:4cake2C1C4Ins2ACXovs",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -370,6 +376,7 @@
"usr": "s:4cake2C1CACycfc",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -462,6 +469,7 @@
"usr": "s:4cake6NumberO3oneyA2CmF",
"location": "",
"moduleName": "cake",
+ "fixedbinaryorder": 0,
"children": [
{
"kind": "TypeFunc",
@@ -499,6 +507,7 @@
"usr": "s:4cake6NumberO8RawValuea",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -516,6 +525,7 @@
"usr": "s:4cake6NumberO9hashValueSivp",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -531,6 +541,7 @@
"usr": "s:4cake6NumberO9hashValueSivg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -550,6 +561,7 @@
"usr": "s:4cake6NumberO4hash4intoys6HasherVz_tF",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -572,6 +584,7 @@
"usr": "s:4cake6NumberO8rawValueACSgSi_tcfc",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Inlinable"
],
@@ -606,6 +619,7 @@
"usr": "s:4cake6NumberO8rawValueSivp",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -621,6 +635,7 @@
"usr": "s:4cake6NumberO8rawValueSivg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Inlinable"
],
@@ -675,6 +690,281 @@
},
{
"kind": "TypeDecl",
+ "name": "fixedLayoutStruct",
+ "printedName": "fixedLayoutStruct",
+ "declKind": "Struct",
+ "usr": "s:4cake17fixedLayoutStructV",
+ "location": "",
+ "moduleName": "cake",
+ "declAttributes": [
+ "FixedLayout"
+ ],
+ "children": [
+ {
+ "kind": "Var",
+ "name": "a",
+ "printedName": "a",
+ "declKind": "Var",
+ "usr": "s:4cake17fixedLayoutStructV1aSivp",
+ "location": "",
+ "moduleName": "cake",
+ "fixedbinaryorder": 0,
+ "declAttributes": [
+ "HasInitialValue"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1aSivg",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1aSivs",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "mutating": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "Var",
+ "name": "b",
+ "printedName": "b",
+ "declKind": "Var",
+ "usr": "s:4cake17fixedLayoutStructV1b33_3D8926C30F7417F2EF9A277D0C73FBDBLLSivp",
+ "location": "",
+ "moduleName": "cake",
+ "fixedbinaryorder": 1,
+ "declAttributes": [
+ "HasInitialValue"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1b33_3D8926C30F7417F2EF9A277D0C73FBDBLLSivg",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1b33_3D8926C30F7417F2EF9A277D0C73FBDBLLSivs",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "mutating": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "Var",
+ "name": "c",
+ "printedName": "c",
+ "declKind": "Var",
+ "usr": "s:4cake17fixedLayoutStructV1cSivp",
+ "location": "",
+ "moduleName": "cake",
+ "fixedbinaryorder": 2,
+ "declAttributes": [
+ "HasInitialValue"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1cSivg",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1cSivs",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "mutating": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "Constructor",
+ "name": "init",
+ "printedName": "init(a:b:c:)",
+ "declKind": "Constructor",
+ "usr": "s:4cake17fixedLayoutStructV1a1b1cACSi_S2itc33_3D8926C30F7417F2EF9A277D0C73FBDBLlfc",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "fixedLayoutStruct",
+ "printedName": "fixedLayoutStruct",
+ "usr": "s:4cake17fixedLayoutStructV"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ },
+ {
+ "kind": "Constructor",
+ "name": "init",
+ "printedName": "init()",
+ "declKind": "Constructor",
+ "usr": "s:4cake17fixedLayoutStructVACycfc",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "fixedLayoutStruct",
+ "printedName": "fixedLayoutStruct",
+ "usr": "s:4cake17fixedLayoutStructV"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "TypeDecl",
"name": "Int",
"printedName": "Int",
"declKind": "Struct",
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index 56af1b7..994ab4e 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -102,6 +102,7 @@
"usr": "s:4cake2S1VACycfc",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -132,6 +133,7 @@
"location": "",
"moduleName": "cake",
"genericSig": "<T1, T2, T3>",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -248,6 +250,7 @@
"usr": "s:4cake2C1C3InsACSgXwvg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -276,6 +279,7 @@
"usr": "s:4cake2C1C3InsACSgXwvs",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -330,6 +334,7 @@
"usr": "s:4cake2C1C4Ins2ACXovg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -350,6 +355,7 @@
"usr": "s:4cake2C1C4Ins2ACXovs",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Transparent"
],
@@ -377,6 +383,7 @@
"usr": "s:4cake2C1CACycfc",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -469,6 +476,7 @@
"usr": "s:4cake6NumberO3oneyA2CmF",
"location": "",
"moduleName": "cake",
+ "fixedbinaryorder": 0,
"children": [
{
"kind": "TypeFunc",
@@ -513,6 +521,7 @@
"usr": "s:4cake6NumberO8RawValuea",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -530,6 +539,7 @@
"usr": "s:4cake6NumberO9hashValueSivp",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -545,6 +555,7 @@
"usr": "s:4cake6NumberO9hashValueSivg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -564,6 +575,7 @@
"usr": "s:4cake6NumberO4hash4intoys6HasherVz_tF",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -586,6 +598,7 @@
"usr": "s:4cake6NumberO8rawValueACSgSi_tcfc",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Inlinable"
],
@@ -620,6 +633,7 @@
"usr": "s:4cake6NumberO8rawValueSivp",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"children": [
{
"kind": "TypeNominal",
@@ -635,6 +649,7 @@
"usr": "s:4cake6NumberO8rawValueSivg",
"location": "",
"moduleName": "cake",
+ "implicit": true,
"declAttributes": [
"Inlinable"
],
@@ -689,6 +704,143 @@
},
{
"kind": "TypeDecl",
+ "name": "fixedLayoutStruct",
+ "printedName": "fixedLayoutStruct",
+ "declKind": "Struct",
+ "usr": "s:4cake17fixedLayoutStructV",
+ "location": "",
+ "moduleName": "cake",
+ "declAttributes": [
+ "FixedLayout"
+ ],
+ "children": [
+ {
+ "kind": "Var",
+ "name": "a",
+ "printedName": "a",
+ "declKind": "Var",
+ "usr": "s:4cake17fixedLayoutStructV1aSivp",
+ "location": "",
+ "moduleName": "cake",
+ "fixedbinaryorder": 0,
+ "declAttributes": [
+ "HasInitialValue"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1aSivg",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Accessor",
+ "usr": "s:4cake17fixedLayoutStructV1aSivs",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "mutating": true,
+ "declAttributes": [
+ "Transparent"
+ ],
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "Constructor",
+ "name": "init",
+ "printedName": "init(a:b:c:)",
+ "declKind": "Constructor",
+ "usr": "s:4cake17fixedLayoutStructV1a1b1cACSi_S2itc33_3D8926C30F7417F2EF9A277D0C73FBDBLlfc",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "fixedLayoutStruct",
+ "printedName": "fixedLayoutStruct",
+ "usr": "s:4cake17fixedLayoutStructV"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Int",
+ "printedName": "Int",
+ "usr": "s:Si"
+ }
+ ]
+ },
+ {
+ "kind": "Constructor",
+ "name": "init",
+ "printedName": "init()",
+ "declKind": "Constructor",
+ "usr": "s:4cake17fixedLayoutStructVACycfc",
+ "location": "",
+ "moduleName": "cake",
+ "implicit": true,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "fixedLayoutStruct",
+ "printedName": "fixedLayoutStruct",
+ "usr": "s:4cake17fixedLayoutStructV"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "TypeDecl",
"name": "Int",
"printedName": "Int",
"declKind": "Struct",
diff --git a/test/api-digester/Outputs/clang-module-dump.txt b/test/api-digester/Outputs/clang-module-dump.txt
index c26a73a..46c293e 100644
--- a/test/api-digester/Outputs/clang-module-dump.txt
+++ b/test/api-digester/Outputs/clang-module-dump.txt
@@ -54,6 +54,7 @@
"usr": "c:objc(cs)NSObject(im)init",
"location": "",
"moduleName": "Foo",
+ "implicit": true,
"declAttributes": [
"Override",
"ObjC"
diff --git a/test/api-digester/apinotes-diags.swift b/test/api-digester/apinotes-diags.swift
index 4e64c05..6a7b06d 100644
--- a/test/api-digester/apinotes-diags.swift
+++ b/test/api-digester/apinotes-diags.swift
@@ -6,6 +6,12 @@
// RUN: %api-digester %clang-importer-sdk-nosource -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -swift-version 3 -I %S/Inputs/APINotesRight
// RUN: %api-digester %clang-importer-sdk-nosource -dump-sdk -module APINotesTest -o %t.dump3.json -module-cache-path %t.module-cache -swift-version 4 -I %S/Inputs/APINotesRight
// RUN: %api-digester -diagnose-sdk -print-module -input-paths %t.dump1.json -input-paths %t.dump3.json > %t.result
-// RUN: diff -u %S/Outputs/apinotes-diags.txt %t.result
+
+// RUN: %clang -E -P -x c %S/Outputs/apinotes-diags.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
+
// RUN: %api-digester -diagnose-sdk -print-module -input-paths %t.dump2.json -input-paths %t.dump3.json > %t.result
-// RUN: diff -u %S/Outputs/apinotes-diags-3-4.txt %t.result
+// RUN: %clang -E -P -x c %S/Outputs/apinotes-diags-3-4.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
diff --git a/test/api-digester/compare-dump.swift b/test/api-digester/compare-dump.swift
index 3a8b92a..e70f166 100644
--- a/test/api-digester/compare-dump.swift
+++ b/test/api-digester/compare-dump.swift
@@ -6,9 +6,15 @@
// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesLeft
// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesRight
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json > %t.result
-// RUN: diff -u %S/Outputs/Cake.txt %t.result
+
+// RUN: %clang -E -P -x c %S/Outputs/Cake.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesLeft -abi
// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesRight -abi
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -abi > %t.result
-// RUN: diff -u %S/Outputs/Cake-abi.txt %t.result
+
+// RUN: %clang -E -P -x c %S/Outputs/Cake-abi.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
diff --git a/test/attr/attr_dynamic_infer.swift b/test/attr/attr_dynamic_infer.swift
index e4686df..dd95065 100644
--- a/test/attr/attr_dynamic_infer.swift
+++ b/test/attr/attr_dynamic_infer.swift
@@ -65,17 +65,17 @@
// CHECK: @objc final var prop: Super
@objc final var prop: Super {
- // CHECK: final get
+ // CHECK: get
get { return Super() }
- // CHECK: final set
+ // CHECK: set
set { }
}
// CHECK: @objc final subscript(sup: Super) -> Super
@objc final subscript(sup: Super) -> Super {
- // CHECK: final get
+ // CHECK: get
get { return sup }
- // CHECK: final set
+ // CHECK: set
set { }
}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 09ac36a..11bef3f 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -841,17 +841,17 @@
var observingAccessorsVar1: Int {
// CHECK: @objc var observingAccessorsVar1: Int {
willSet {}
- // CHECK-NEXT: {{^}} final willSet {}
+ // CHECK-NEXT: {{^}} willSet {}
didSet {}
- // CHECK-NEXT: {{^}} final didSet {}
+ // CHECK-NEXT: {{^}} didSet {}
}
@objc var observingAccessorsVar1_: Int {
// CHECK: {{^}} @objc var observingAccessorsVar1_: Int {
willSet {}
- // CHECK-NEXT: {{^}} final willSet {}
+ // CHECK-NEXT: {{^}} willSet {}
didSet {}
- // CHECK-NEXT: {{^}} final didSet {}
+ // CHECK-NEXT: {{^}} didSet {}
}
diff --git a/test/decl/protocol/resilient_defaults.swift b/test/decl/protocol/resilient_defaults.swift
new file mode 100644
index 0000000..b959241
--- /dev/null
+++ b/test/decl/protocol/resilient_defaults.swift
@@ -0,0 +1,18 @@
+// RUN: %target-typecheck-verify-swift -enable-resilience
+
+public struct Wrapper<T: P>: P { }
+extension Wrapper: Q where T: Q { }
+
+public protocol PBase {
+ associatedtype AssocType
+}
+
+public protocol P: PBase {
+ override associatedtype AssocType: P = Wrapper<Self>
+ // expected-note@-1{{associated type 'AssocType' has default type 'Wrapper<Self>' written here}}
+}
+
+public protocol Q: P where Self.AssocType: Q { }
+
+public protocol R: Q where Self.AssocType: R { }
+// expected-warning@-1{{default type 'Wrapper<Self>' for associated type 'AssocType' does not satisfy constraint 'Self.AssocType': 'R'}}
diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
index 396f6bd..08b5f5b 100644
--- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
+++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
@@ -42,11 +42,13 @@
StringRef USR;
StringRef Location;
StringRef ModuleName;
+ bool IsImplicit = false;
bool IsThrowing = false;
bool IsMutating = false;
bool IsStatic = false;
bool IsDeprecated = false;
Optional<uint8_t> SelfIndex;
+ Optional<unsigned> FixedBinaryOrder;
ReferenceOwnership ReferenceOwnership = ReferenceOwnership::Strong;
std::vector<DeclAttrKind> DeclAttrs;
std::vector<TypeAttrKind> TypeAttrs;
@@ -81,8 +83,8 @@
SDKNodeDecl::SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind)
: SDKNode(Info, Kind), DKind(Info.DKind), Usr(Info.USR),
Location(Info.Location), ModuleName(Info.ModuleName),
- DeclAttributes(Info.DeclAttrs), IsStatic(Info.IsStatic),
- IsDeprecated(Info.IsDeprecated),
+ DeclAttributes(Info.DeclAttrs), IsImplicit(Info.IsImplicit),
+ IsStatic(Info.IsStatic), IsDeprecated(Info.IsDeprecated),
ReferenceOwnership(uint8_t(Info.ReferenceOwnership)),
GenericSig(Info.GenericSig) {}
@@ -108,7 +110,8 @@
SDKNodeDecl(Info, SDKNodeKind::DeclTypeAlias) {}
SDKNodeDeclVar::SDKNodeDeclVar(SDKNodeInitInfo Info):
- SDKNodeDecl(Info, SDKNodeKind::DeclVar) {}
+ SDKNodeDecl(Info, SDKNodeKind::DeclVar),
+ FixedBinaryOrder(Info.FixedBinaryOrder) {}
SDKNodeDeclAbstractFunc::SDKNodeDeclAbstractFunc(SDKNodeInitInfo Info,
SDKNodeKind Kind): SDKNodeDecl(Info, Kind), IsThrowing(Info.IsThrowing),
@@ -153,8 +156,10 @@
}
}
-unsigned SDKNode::getChildIndex(NodePtr Child) const {
- return std::find(Children.begin(), Children.end(), Child) - Children.begin();
+unsigned SDKNode::getChildIndex(const SDKNode* Child) const {
+ auto It = std::find(Children.begin(), Children.end(), Child);
+ assert(It != Children.end() && "cannot find the child");
+ return It - Children.begin();
}
SDKNode* SDKNode::getOnlyChild() const {
@@ -503,6 +508,9 @@
case KeyKind::KK_selfIndex:
Info.SelfIndex = getAsInt(Pair.getValue());
break;
+ case KeyKind::KK_fixedbinaryorder:
+ Info.FixedBinaryOrder = getAsInt(Pair.getValue());
+ break;
case KeyKind::KK_usr:
Info.USR = GetScalarString(Pair.getValue());
break;
@@ -555,6 +563,9 @@
case KeyKind::KK_deprecated:
Info.IsDeprecated = true;
break;
+ case KeyKind::KK_implicit:
+ Info.IsImplicit = true;
+ break;
case KeyKind::KK_ownership:
Info.ReferenceOwnership =
swift::ReferenceOwnership(getAsInt(Pair.getValue()));
@@ -653,6 +664,8 @@
auto Right = (&Other)->getAs<SDKNodeType>();
if (!Left->getTypeAttributes().equals(Right->getTypeAttributes()))
return false;
+ if (Left->hasDefaultArgument() != Right->hasDefaultArgument())
+ return false;
if (Left->getPrintedName() == Right->getPrintedName())
return true;
return Left->getName() == Right->getName() &&
@@ -671,8 +684,24 @@
return false;
LLVM_FALLTHROUGH;
}
+
+ case SDKNodeKind::DeclVar: {
+ if (getSDKContext().checkingABI()) {
+ // If we're checking ABI, the definition order matters.
+ // If they're both members for fixed layout types, we never consider
+ // them equal because we need to check definition orders.
+ if (auto *LV = dyn_cast<SDKNodeDeclVar>(this)) {
+ if (auto *RV = dyn_cast<SDKNodeDeclVar>(&Other)) {
+ if (LV->hasFixedBinaryOrder() && RV->hasFixedBinaryOrder()) {
+ if (LV->getFixedBinaryOrder() != RV->getFixedBinaryOrder())
+ return false;
+ }
+ }
+ }
+ }
+ LLVM_FALLTHROUGH;
+ }
case SDKNodeKind::DeclType:
- case SDKNodeKind::DeclVar:
case SDKNodeKind::DeclTypeAlias: {
auto Left = this->getAs<SDKNodeDecl>();
auto Right = (&Other)->getAs<SDKNodeDecl>();
@@ -684,6 +713,7 @@
return false;
if (Left->getGenericSignature() != Right->getGenericSignature())
return false;
+
LLVM_FALLTHROUGH;
}
case SDKNodeKind::Root: {
@@ -902,6 +932,39 @@
return StringRef();
}
+static Optional<unsigned> getFixedBinaryOrder(ValueDecl *VD) {
+ auto D = VD->getDeclContext()->getAsDecl();
+ if (!D)
+ return None;
+
+ if (auto *ED = dyn_cast<EnumDecl>(D)) {
+ auto Check = [](Decl *M) {
+ return isa<EnumElementDecl>(M);
+ };
+ if (!ED->isResilient() && Check(VD)) {
+ auto Members = ED->getMembers();
+ auto End = std::find(Members.begin(), Members.end(), VD);
+ assert(End != Members.end());
+ return std::count_if(Members.begin(), End, Check);
+ }
+ }
+ if (auto *SD = dyn_cast<StructDecl>(D)) {
+ auto Check = [](Decl *M) {
+ if (auto *STD = dyn_cast<AbstractStorageDecl>(M)) {
+ return STD->hasStorage() && !STD->isStatic();
+ }
+ return false;
+ };
+ if (!SD->isResilient() && Check(VD)) {
+ auto Members = SD->getMembers();
+ auto End = std::find(Members.begin(), Members.end(), VD);
+ assert(End != Members.end());
+ return std::count_if(Members.begin(), End, Check);
+ }
+ }
+ return llvm::None;
+}
+
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
TypeInitInfo TypeInfo) :
Ctx(Ctx), Name(getTypeName(Ctx, Ty, TypeInfo.IsImplicitlyUnwrappedOptional)),
@@ -921,10 +984,12 @@
PrintedName(getPrintedName(Ctx, VD)), DKind(VD->getKind()),
USR(calculateUsr(Ctx, VD)), Location(calculateLocation(Ctx, VD)),
ModuleName(VD->getModuleContext()->getName().str()),
+ IsImplicit(VD->isImplicit()),
IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
IsStatic(VD->isStatic()),
IsDeprecated(VD->getAttrs().getDeprecated(VD->getASTContext())),
- SelfIndex(getSelfIndex(VD)), ReferenceOwnership(getReferenceOwnership(VD)),
+ SelfIndex(getSelfIndex(VD)), FixedBinaryOrder(getFixedBinaryOrder(VD)),
+ ReferenceOwnership(getReferenceOwnership(VD)),
GenericSig(printGenericSignature(Ctx, VD)) {
// Calculate usr for its super class.
@@ -1054,7 +1119,7 @@
return Func;
}
-static bool shouldIgnore(Decl *D, const Decl* Parent) {
+static bool shouldIgnore(Decl *D, const Decl* Parent, SDKContext &Ctx) {
if (D->isPrivateStdlibDecl(false))
return true;
if (AvailableAttr::isUnavailable(D))
@@ -1072,6 +1137,10 @@
case AccessLevel::Internal:
case AccessLevel::Private:
case AccessLevel::FilePrivate:
+ // Private vars with fixed binary orders can have ABI-impact, so we should
+ // whitelist them if we're checking ABI.
+ if (Ctx.checkingABI() && getFixedBinaryOrder(VD).hasValue())
+ break;
return true;
case AccessLevel::Public:
case AccessLevel::Open:
@@ -1153,7 +1222,7 @@
IterableDeclContext *Context,
std::set<ExtensionDecl*> &HandledExts) {
for (auto *Member : Context->getMembers()) {
- if (shouldIgnore(Member, Context->getDecl()))
+ if (shouldIgnore(Member, Context->getDecl(), Ctx))
continue;
if (auto Func = dyn_cast<FuncDecl>(Member)) {
Root->addChild(constructFunctionNode(Ctx, Func, SDKNodeKind::DeclFunction));
@@ -1182,7 +1251,7 @@
llvm::SmallVector<Decl*, 512> Decls;
M->getDisplayDecls(Decls);
for (auto D : Decls) {
- if (shouldIgnore(D, nullptr))
+ if (shouldIgnore(D, nullptr, Ctx))
continue;
if (KnownDecls.count(D))
continue;
@@ -1300,6 +1369,16 @@
if (bool isDeprecated = D->isDeprecated())
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_deprecated).data(),
isDeprecated);
+ if (bool isImplicit = D->isImplicit())
+ out.mapRequired(getKeyContent(Ctx, KeyKind::KK_implicit).data(),
+ isImplicit);
+ if (auto V = dyn_cast<SDKNodeDeclVar>(value)) {
+ if (V->hasFixedBinaryOrder()) {
+ auto Order = V->getFixedBinaryOrder();
+ out.mapRequired(getKeyContent(Ctx, KeyKind::KK_fixedbinaryorder).data(),
+ Order);
+ }
+ }
if (auto F = dyn_cast<SDKNodeDeclAbstractFunc>(value)) {
if (bool isThrowing = F->isThrowing())
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_throwing).data(),
diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.h b/tools/swift-api-digester/ModuleAnalyzerNodes.h
index 11eac7f..660af51 100644
--- a/tools/swift-api-digester/ModuleAnalyzerNodes.h
+++ b/tools/swift-api-digester/ModuleAnalyzerNodes.h
@@ -220,7 +220,6 @@
std::set<NodeAnnotation> Annotations;
std::map<NodeAnnotation, StringRef> AnnotateComments;
NodePtr Parent = nullptr;
-
protected:
SDKNode(SDKNodeInitInfo Info, SDKNodeKind Kind);
@@ -253,7 +252,7 @@
void addChild(SDKNode *Child);
ArrayRef<SDKNode*> getChildren() const;
bool hasSameChildren(const SDKNode &Other) const;
- unsigned getChildIndex(NodePtr Child) const;
+ unsigned getChildIndex(const SDKNode *Child) const;
SDKNode* getOnlyChild() const;
SDKContext &getSDKContext() const { return Ctx; }
SDKNodeRoot *getRootNode() const;
@@ -275,6 +274,7 @@
StringRef Location;
StringRef ModuleName;
std::vector<DeclAttrKind> DeclAttributes;
+ bool IsImplicit;
bool IsStatic;
bool IsDeprecated;
uint8_t ReferenceOwnership;
@@ -301,6 +301,7 @@
bool isSDKPrivate() const;
bool isDeprecated() const { return IsDeprecated; };
bool hasDeclAttribute(DeclAttrKind DAKind) const;
+ bool isImplicit() const { return IsImplicit; };
bool isStatic() const { return IsStatic; };
StringRef getGenericSignature() const { return GenericSig; }
StringRef getScreenInfo() const;
@@ -440,9 +441,12 @@
};
class SDKNodeDeclVar : public SDKNodeDecl {
+ Optional<unsigned> FixedBinaryOrder;
public:
SDKNodeDeclVar(SDKNodeInitInfo Info);
static bool classof(const SDKNode *N);
+ bool hasFixedBinaryOrder() const { return FixedBinaryOrder.hasValue(); }
+ unsigned getFixedBinaryOrder() const { return *FixedBinaryOrder; }
};
class SDKNodeDeclAbstractFunc : public SDKNodeDecl {
@@ -538,6 +542,7 @@
CheckerOptions Opts);
int findDeclUsr(StringRef dumpPath, CheckerOptions Opts);
+
} // end of abi namespace
} // end of ide namespace
} // end of Swift namespace
diff --git a/tools/swift-api-digester/ModuleDiagsConsumer.cpp b/tools/swift-api-digester/ModuleDiagsConsumer.cpp
index c00bad3..8454c31 100644
--- a/tools/swift-api-digester/ModuleDiagsConsumer.cpp
+++ b/tools/swift-api-digester/ModuleDiagsConsumer.cpp
@@ -41,12 +41,16 @@
case LocalDiagID::decl_attr_change:
case LocalDiagID::decl_new_attr:
return "/* Decl Attribute changes */";
+ case LocalDiagID::default_arg_removed:
case LocalDiagID::decl_type_change:
return "/* Type Changes */";
case LocalDiagID::raw_type_change:
return "/* RawRepresentable Changes */";
case LocalDiagID::generic_sig_change:
return "/* Generic Signature Changes */";
+ case LocalDiagID::decl_added:
+ case LocalDiagID::decl_reorder:
+ return "/* Fixed-layout Type Changes */";
default:
return StringRef();
}
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index bc3c9e4..ade1857 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -709,6 +709,17 @@
Desc);
}
}
+ // Detect re-ordering if they're from structs with a fixed layout.
+ auto *LV = dyn_cast<SDKNodeDeclVar>(L);
+ auto *RV = dyn_cast<SDKNodeDeclVar>(R);
+ if (LV && RV &&
+ LV->hasFixedBinaryOrder() && RV->hasFixedBinaryOrder() &&
+ LV->getFixedBinaryOrder() != RV->getFixedBinaryOrder()) {
+ Ctx.getDiags().diagnose(SourceLoc(), diag::decl_reorder,
+ LV->getScreenInfo(),
+ LV->getFixedBinaryOrder(),
+ RV->getFixedBinaryOrder());
+ }
}
// Diagnose generic signature change
@@ -720,6 +731,21 @@
}
}
+static void diagnoseTypeChange(SDKNode* L, SDKNode* R) {
+ auto &Ctx = L->getSDKContext();
+ auto &Diags = Ctx.getDiags();
+ auto *LT = dyn_cast<SDKNodeType>(L);
+ auto *RT = dyn_cast<SDKNodeType>(R);
+ if (!LT || !RT)
+ return;
+ if (LT->hasDefaultArgument() && !RT->hasDefaultArgument()) {
+ auto *Func = cast<SDKNodeDeclAbstractFunc>(LT->getClosestParentDecl());
+ Diags.diagnose(SourceLoc(), diag::default_arg_removed, Func->getScreenInfo(),
+ Func->getTypeRoleDescription(Ctx, Func->getChildIndex(LT)));
+ }
+}
+
+
// This is first pass on two given SDKNode trees. This pass removes the common part
// of two versions of SDK, leaving only the changed part.
class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
@@ -751,6 +777,14 @@
case NodeMatchReason::Added:
assert(!Left);
Right->annotate(NodeAnnotation::Added);
+ if (Ctx.checkingABI()) {
+ if (auto *VAD = dyn_cast<SDKNodeDeclVar>(Right)) {
+ if (VAD->hasFixedBinaryOrder()) {
+ Ctx.getDiags().diagnose(SourceLoc(), diag::decl_added,
+ VAD->getScreenInfo());
+ }
+ }
+ }
return;
case NodeMatchReason::Removed:
assert(!Right);
@@ -773,6 +807,7 @@
// Push the updated node to the map for future reference.
UpdateMap.insert(Left, Right);
+ diagnoseTypeChange(Left, Right);
if (Left->getKind() != Right->getKind()) {
assert(isa<SDKNodeType>(Left) && isa<SDKNodeType>(Right) &&
"only type nodes can match across kinds.");
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 25e9ea2..f412f72 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -2665,21 +2665,21 @@
set -x
pushd "${PLAYGROUNDSUPPORT_SOURCE_DIR}"
if [[ $(not ${SKIP_BUILD_OSX}) ]]; then
- "xcodebuild" -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-macOS -sdk macosx -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
+ call "xcodebuild" -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-macOS -sdk macosx -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
if [[ $(not ${SKIP_TEST_PLAYGROUNDSUPPORT}) ]]; then
# If we're going to end up testing PlaygroundLogger/PlaygroundSupport, then we need to build the tests too.
# Note that this *always* needs to run in Debug configuration.
- "xcodebuild" build-for-testing -configuration Debug -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-Test-PlaygroundLogger-macOS -sdk macosx -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
+ call "xcodebuild" build-for-testing -configuration Debug -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-Test-PlaygroundLogger-macOS -sdk macosx -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
fi
fi
if [[ $(not ${SKIP_BUILD_IOS_SIMULATOR}) ]]; then
- "xcodebuild" -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-iOS -sdk iphonesimulator -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
+ call "xcodebuild" -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-iOS -sdk iphonesimulator -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
fi
if [[ $(not ${SKIP_BUILD_TVOS_SIMULATOR}) ]]; then
- "xcodebuild" -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-tvOS -sdk appletvsimulator -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
+ call "xcodebuild" -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-tvOS -sdk appletvsimulator -arch x86_64 -derivedDataPath "${build_dir}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
fi
popd
{ set +x; } 2>/dev/null
@@ -2879,7 +2879,7 @@
# Watchpoint testing is currently disabled: see rdar://38566150.
if [[ "$(true_false ${LLDB_TEST_SWIFT_ONLY})" == "TRUE" ]]; then
LLDB_TEST_SUBDIR_CLAUSE="--test-subdir lang/swift"
- LLDB_TEST_CATEGORIES="--skip-category=watchpoint --skip-category=dwo --skip-category=dwarf"
+ LLDB_TEST_CATEGORIES="--skip-category=watchpoint --skip-category=dwo"
else
LLDB_TEST_SUBDIR_CLAUSE=""
LLDB_TEST_CATEGORIES="--skip-category=watchpoint"
@@ -3102,7 +3102,7 @@
set -x
with_pushd "${PLAYGROUNDSUPPORT_SOURCE_DIR}" \
- "xcodebuild" test-without-building -configuration Debug -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-Test-PlaygroundLogger-macOS -sdk macosx -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
+ call "xcodebuild" test-without-building -configuration Debug -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-Test-PlaygroundLogger-macOS -sdk macosx -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO
{ set +x; } 2>/dev/null
continue
;;
@@ -3423,15 +3423,15 @@
Darwin)
pushd "${PLAYGROUNDSUPPORT_SOURCE_DIR}"
if [[ $(not ${SKIP_BUILD_OSX}) ]]; then
- "xcodebuild" install -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-macOS -sdk macosx -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO DSTROOT="$(get_host_install_destdir ${host})" TOOLCHAIN_INSTALL_DIR="${TOOLCHAIN_PREFIX}" BUILD_PLAYGROUNDLOGGER_TESTS=NO
+ call "xcodebuild" install -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-macOS -sdk macosx -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO DSTROOT="$(get_host_install_destdir ${host})" TOOLCHAIN_INSTALL_DIR="${TOOLCHAIN_PREFIX}" BUILD_PLAYGROUNDLOGGER_TESTS=NO
fi
if [[ $(not ${SKIP_BUILD_IOS_SIMULATOR}) ]]; then
- "xcodebuild" install -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-iOS -sdk iphonesimulator -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO DSTROOT="$(get_host_install_destdir ${host})" TOOLCHAIN_INSTALL_DIR="${TOOLCHAIN_PREFIX}" BUILD_PLAYGROUNDLOGGER_TESTS=NO
+ call "xcodebuild" install -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-iOS -sdk iphonesimulator -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO DSTROOT="$(get_host_install_destdir ${host})" TOOLCHAIN_INSTALL_DIR="${TOOLCHAIN_PREFIX}" BUILD_PLAYGROUNDLOGGER_TESTS=NO
fi
if [[ $(not ${SKIP_BUILD_TVOS_SIMULATOR}) ]]; then
- "xcodebuild" install -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-tvOS -sdk appletvsimulator -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO DSTROOT="$(get_host_install_destdir ${host})" TOOLCHAIN_INSTALL_DIR="${TOOLCHAIN_PREFIX}" BUILD_PLAYGROUNDLOGGER_TESTS=NO
+ call "xcodebuild" install -configuration "${PLAYGROUNDSUPPORT_BUILD_TYPE}" -workspace swift-xcode-playground-support.xcworkspace -scheme BuildScript-tvOS -sdk appletvsimulator -arch x86_64 -derivedDataPath "${PLAYGROUNDSUPPORT_BUILD_DIR}"/DerivedData SWIFT_EXEC="${SWIFTC_BIN}" SWIFT_LIBRARY_PATH="${SWIFT_LIB_DIR}/\$(PLATFORM_NAME)" ONLY_ACTIVE_ARCH=NO DSTROOT="$(get_host_install_destdir ${host})" TOOLCHAIN_INSTALL_DIR="${TOOLCHAIN_PREFIX}" BUILD_PLAYGROUNDLOGGER_TESTS=NO
fi
popd
continue
diff --git a/validation-test/Evolution/Inputs/protocol_add_requirements.swift b/validation-test/Evolution/Inputs/protocol_add_requirements.swift
index 6e2eb34..ba05853 100644
--- a/validation-test/Evolution/Inputs/protocol_add_requirements.swift
+++ b/validation-test/Evolution/Inputs/protocol_add_requirements.swift
@@ -176,24 +176,23 @@
#endif
}
-public struct Wrapper<T> { }
+public protocol SimpleProtocol {
+ static func getString() -> String
+}
+
+public struct Wrapper<T>: SimpleProtocol {
+ public static func getString() -> String {
+ return "I am a wrapper for \(T.self)"
+ }
+}
public protocol AddAssocTypesProtocol {
- // FIXME: The presence of a single method requirement causes us to
- // create a resilient witness table, avoiding a runtime assertion.
- func dummy()
-
#if AFTER
associatedtype AssocType = Self
- associatedtype AssocType2 = Wrapper<AssocType>
+ associatedtype AssocType2: SimpleProtocol = Wrapper<AssocType>
#endif
}
-extension AddAssocTypesProtocol {
- public func dummy() { }
-}
-
-
public func doSomethingWithAssocTypes<T: AddAssocTypesProtocol>(_ value: T)
-> String {
#if AFTER
@@ -202,3 +201,17 @@
return "there are no associated types yet"
#endif
}
+
+public func doSomethingWithAssocConformances<T: AddAssocTypesProtocol>(_ value: T)
+ -> String {
+#if AFTER
+ let at2: Any.Type = T.AssocType2.self
+ if let simpleType = at2 as? SimpleProtocol.Type {
+ return simpleType.getString()
+ }
+
+ return "missing associated conformance"
+#else
+ return "there are no associated conformances yet"
+#endif
+}
diff --git a/validation-test/Evolution/test_protocol_add_requirements.swift b/validation-test/Evolution/test_protocol_add_requirements.swift
index 046b6ee..2acfb7e 100644
--- a/validation-test/Evolution/test_protocol_add_requirements.swift
+++ b/validation-test/Evolution/test_protocol_add_requirements.swift
@@ -154,5 +154,16 @@
}
}
+ProtocolAddRequirementsTest.test("AddAssociatedConformanceRequirements") {
+ let addString = AddAssociatedType<String>()
+ let stringResult = doSomethingWithAssocConformances(addString)
+
+ if getVersion() == 0 {
+ expectEqual("there are no associated conformances yet", stringResult)
+ } else {
+ expectEqual("I am a wrapper for AddAssociatedType<String>", stringResult)
+ }
+}
+
runAllTests()