Merge pull request #10169 from CodaFi/sweeps
[NFC] Run clang format on the space engine
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 427564d..56b45e9 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -359,9 +359,10 @@
endif()
elseif("${LFLAGS_SDK}" STREQUAL "ANDROID")
list(APPEND result
- "-ldl"
+ "-ldl" "-llog" "-latomic" "-licudata" "-licui18n" "-licuuc"
"${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so")
list(APPEND library_search_directories
+ "${SWIFT_ANDROID_PREBUILT_PATH}/arm-linux-androideabi/lib/armv7-a"
"${SWIFT_ANDROID_PREBUILT_PATH}/lib/gcc/arm-linux-androideabi/${SWIFT_ANDROID_NDK_GCC_VERSION}.x")
else()
# If lto is enabled, we need to add the object path flag so that the LTO code
@@ -1500,6 +1501,12 @@
if("${lib}" STREQUAL "ICU_UC")
list(APPEND swiftlib_private_link_libraries_targets
"${SWIFT_${sdk}_ICU_UC}")
+ # temporary fix for atomic needing to be
+ # after object files for libswiftCore.so
+ if("${sdk}" STREQUAL "ANDROID")
+ list(APPEND swiftlib_private_link_libraries_targets
+ "-latomic")
+ endif()
elseif("${lib}" STREQUAL "ICU_I18N")
list(APPEND swiftlib_private_link_libraries_targets
"${SWIFT_${sdk}_ICU_I18N}")
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index 22b0dbb..a7b4f7f 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -273,18 +273,15 @@
| NotSerialized | UserInaccessible,
/* Not serialized */ 67)
-DECL_ATTR(NSKeyedArchiverClassName, NSKeyedArchiverClassName,
- OnClass | NotSerialized | LongAttribute,
+DECL_ATTR(_objcRuntimeName, ObjCRuntimeName,
+ OnClass | NotSerialized | UserInaccessible | RejectByParser,
/*Not serialized */ 68)
SIMPLE_DECL_ATTR(_staticInitializeObjCMetadata, StaticInitializeObjCMetadata,
OnClass | NotSerialized | LongAttribute | RejectByParser,
/*Not serialized */ 69)
-SIMPLE_DECL_ATTR(NSKeyedArchiverEncodeNonGenericSubclassesOnly,
- NSKeyedArchiverEncodeNonGenericSubclassesOnly,
- OnClass | NotSerialized | LongAttribute,
- /*Not serialized */ 70)
+// 70 is available; it was not a serialized attribute.
// HACK: Attribute needed to preserve source compatibility by downgrading errors
// due to an SDK change in Dispatch
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index dcaa8f9..04ffd62 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -1161,21 +1161,26 @@
}
};
-/// Defines the @NSKeyedArchiverClassNameAttr attribute.
-class NSKeyedArchiverClassNameAttr : public DeclAttribute {
+/// A limited variant of \c @objc that's used for classes with generic ancestry.
+class ObjCRuntimeNameAttr : public DeclAttribute {
+ static StringRef getSimpleName(const ObjCAttr &Original) {
+ assert(Original.hasName());
+ return Original.getName()->getSimpleName().str();
+ }
public:
- NSKeyedArchiverClassNameAttr(StringRef Name, SourceLoc AtLoc, SourceRange Range, bool Implicit)
- : DeclAttribute(DAK_NSKeyedArchiverClassName, AtLoc, Range, Implicit),
+ ObjCRuntimeNameAttr(StringRef Name, SourceLoc AtLoc, SourceRange Range,
+ bool Implicit)
+ : DeclAttribute(DAK_ObjCRuntimeName, AtLoc, Range, Implicit),
Name(Name) {}
- NSKeyedArchiverClassNameAttr(StringRef Name, bool Implicit)
- : NSKeyedArchiverClassNameAttr(Name, SourceLoc(), SourceRange(), /*Implicit=*/true) {}
+ explicit ObjCRuntimeNameAttr(const ObjCAttr &Original)
+ : ObjCRuntimeNameAttr(getSimpleName(Original), Original.AtLoc,
+ Original.Range, Original.isImplicit()) {}
- /// The legacy mangled name.
const StringRef Name;
static bool classof(const DeclAttribute *DA) {
- return DA->getKind() == DAK_NSKeyedArchiverClassName;
+ return DA->getKind() == DAK_ObjCRuntimeName;
}
};
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 9416e6d..f202dc2 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -2201,7 +2201,10 @@
///
/// This is the access used when making optimization and code generation
/// decisions. It should not be used at the AST or semantic level.
- Accessibility getEffectiveAccess() const;
+ ///
+ /// If \p forLinkage is false, we ignore -enable-testing; only @_versioned
+ /// can increase visibility.
+ Accessibility getEffectiveAccess(bool forLinkage = true) const;
void setAccessibility(Accessibility access) {
assert(!hasAccessibility() && "accessibility already set");
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index f68a37a..0b02cf9 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -1317,6 +1317,11 @@
"expected ')' after name for @objc", ())
ERROR(attr_objc_empty_name,none,
"expected name within parentheses of @objc attribute", ())
+ERROR(attr_nskeyedarchiverclassname_removed, none,
+ "@NSKeyedArchiverClassName has been removed; use @objc instead", ())
+ERROR(attr_nskeyedarchiverencodenongenericsubclassesonly_removed, none,
+ "@NSKeyedArchiverEncodeNonGenericSubclassesOnly is no longer necessary",
+ ())
// opened
ERROR(opened_attribute_expected_lparen,none,
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 028f618..84972bc 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1228,27 +1228,19 @@
(unsigned))
ERROR(nscoding_unstable_mangled_name,none,
- "%select{private|fileprivate|nested|local|generic}0 class %1 has an "
+ "%select{private|fileprivate|nested|local}0 class %1 has an "
"unstable name when archiving via 'NSCoding'",
(unsigned, Type))
WARNING(nscoding_unstable_mangled_name_warn,none,
- "%select{private|fileprivate|nested|local|generic}0 class %1 has an "
+ "%select{private|fileprivate|nested|local}0 class %1 has an "
"unstable name when archiving via 'NSCoding'",
(unsigned, Type))
-NOTE(unstable_mangled_name_add_objc,none,
- "for new classes, add '@objc' to specify a unique, prefixed Objective-C "
+NOTE(unstable_mangled_name_add_objc_new,none,
+ "for new classes, use '@objc' to specify a unique, prefixed Objective-C "
"runtime name", ())
-NOTE(unstable_mangled_name_add_NSKeyedArchiverClassName,none,
- "for compatibility with existing archives, use '@NSKeyedArchiverClassName' "
- "to record the Swift 3 mangled name", ())
-NOTE(add_NSKeyedArchiverEncodeNonGenericSubclassesOnly_attr,none,
- "generic class %0 should not be archived directly; "
- "add @NSKeyedArchiverEncodeNonGenericSubclassesOnly "
- "and only archive specific subclasses of this class", (Type))
-
-ERROR(attr_NSKeyedArchiverClassName_generic,none,
- "'@NSKeyedArchiverClassName' cannot be applied to generic class %0",
- (Type))
+NOTE(unstable_mangled_name_add_objc,none,
+ "for compatibility with existing archives, use '@objc' "
+ "to record the Swift 3 runtime name", ())
// Generic types
ERROR(unsupported_type_nested_in_generic_function,none,
diff --git a/include/swift/AST/Identifier.h b/include/swift/AST/Identifier.h
index bf9c5cd..9e85dcf 100644
--- a/include/swift/AST/Identifier.h
+++ b/include/swift/AST/Identifier.h
@@ -582,6 +582,12 @@
return Storage.getArgumentNames();
}
+ /// Asserts that this is a nullary selector and returns the single identifier.
+ Identifier getSimpleName() const {
+ assert(Storage.isSimpleName() && "not a nullary selector");
+ return Storage.getBaseIdentifier();
+ }
+
/// Get a string representation of the selector.
///
/// \param scratch Scratch space to use.
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index ffec8f8..5a64126 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -229,7 +229,7 @@
Swift3ObjCInferenceWarnings::None;
/// Diagnose uses of NSCoding with classes that have unstable mangled names.
- bool EnableNSKeyedArchiverDiagnostics = false;
+ bool EnableNSKeyedArchiverDiagnostics = true;
/// Enable keypath components that aren't fully implemented.
bool EnableExperimentalKeyPathComponents = false;
diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h
index 1b0fb79..3d04d03 100644
--- a/include/swift/IDE/Utils.h
+++ b/include/swift/IDE/Utils.h
@@ -327,6 +327,7 @@
class DeclNameViewer {
StringRef BaseName;
SmallVector<StringRef, 4> Labels;
+ bool IsValid;
bool HasParen;
public:
DeclNameViewer(StringRef Text);
@@ -337,6 +338,7 @@
unsigned argSize() const { return Labels.size(); }
unsigned partsCount() const { return 1 + Labels.size(); }
unsigned commonPartsCount(DeclNameViewer &Other) const;
+ bool isValid() const { return IsValid; }
bool isFunction() const { return HasParen; }
};
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 81ce16f..75c885b 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -1217,14 +1217,6 @@
ARGS(Int8PtrTy, Int8PtrTy),
ATTRS(NoUnwind))
-// func _registerClassNameForArchiving(_ nameOrNull: UnsafePointer<CChar>?,
-// _ c: AnyClass)
-FUNCTION(RegisterClassNameForArchiving, swift_registerClassNameForArchiving,
- SwiftCC,
- RETURNS(VoidTy),
- ARGS(Int8PtrTy, TypeMetadataPtrTy),
- ATTRS(NoUnwind))
-
#if SWIFT_OBJC_INTEROP || !defined(SWIFT_RUNTIME_GENERATE_GLOBAL_SYMBOLS)
// Put here all definitions of runtime functions which are:
diff --git a/include/swift/SIL/SILBasicBlock.h b/include/swift/SIL/SILBasicBlock.h
index 1cdab0e..6dfb875 100644
--- a/include/swift/SIL/SILBasicBlock.h
+++ b/include/swift/SIL/SILBasicBlock.h
@@ -425,11 +425,8 @@
public:
static void deleteNode(SILBasicBlock *BB) { BB->~SILBasicBlock(); }
- void addNodeToList(SILBasicBlock *BB) {}
-
void transferNodesFromList(ilist_traits<SILBasicBlock> &SrcTraits,
block_iterator First, block_iterator Last);
-
private:
static void createNode(const SILBasicBlock &);
};
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 9c1dba7..b7b3de0 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -150,16 +150,13 @@
/// is already set in when creating an instruction.
void setDebugLocation(SILDebugLocation Loc) { Location = Loc; }
- /// removeFromParent - This method unlinks 'self' from the containing basic
- /// block, but does not delete it.
- ///
- void removeFromParent();
-
- /// eraseFromParent - This method unlinks 'self' from the containing basic
- /// block and deletes it.
- ///
+ /// This method unlinks 'self' from the containing basic block and deletes it.
void eraseFromParent();
+ /// Unlink this instruction from its current basic block and insert the
+ /// instruction such that it is the first instruction of \p Block.
+ void moveFront(SILBasicBlock *Block);
+
/// Unlink this instruction from its current basic block and insert it into
/// the basic block that Later lives in, right before Later.
void moveBefore(SILInstruction *Later);
@@ -171,13 +168,6 @@
/// \brief Drops all uses that belong to this instruction.
void dropAllReferences();
- /// \brief Replace all uses of this instruction with Undef.
- ///
- /// TODO: This should be on ValueBase, but ValueBase currently does not have
- /// access to a SILModule. If that ever changes, this method should move to
- /// ValueBase.
- void replaceAllUsesWithUndef();
-
/// Return the array of operands for this instruction.
ArrayRef<Operand> getAllOperands() const;
diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h
index 3d82399..37c05d5 100644
--- a/include/swift/SIL/SILValue.h
+++ b/include/swift/SIL/SILValue.h
@@ -163,11 +163,16 @@
}
/// Replace every use of a result of this instruction with the corresponding
- /// result from RHS. The method assumes that both instructions have the same
- /// number of results. To replace just one result use
- /// SILValue::replaceAllUsesWith.
+ /// result from RHS.
+ ///
+ /// The method assumes that both instructions have the same number of
+ /// results. To replace just one result use SILValue::replaceAllUsesWith.
void replaceAllUsesWith(ValueBase *RHS);
+ /// \brief Replace all uses of this instruction with an undef value of the
+ /// same type as the result of this instruction.
+ void replaceAllUsesWithUndef();
+
/// Returns true if this value has no uses.
/// To ignore debug-info instructions use swift::onlyHaveDebugUses instead
/// (see comment in DebugUtils.h).
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index f1b9132..a876a2b 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -1321,8 +1321,8 @@
using SynthesizedProtocolDeclAttrLayout
= BCRecordLayout<SynthesizedProtocol_DECL_ATTR>;
using ImplementsDeclAttrLayout = BCRecordLayout<Implements_DECL_ATTR>;
- using NSKeyedArchiverClassNameDeclAttrLayout
- = BCRecordLayout<NSKeyedArchiverClassName_DECL_ATTR>;
+ using ObjCRuntimeNameDeclAttrLayout
+ = BCRecordLayout<ObjCRuntimeName_DECL_ATTR>;
using InlineDeclAttrLayout = BCRecordLayout<
Inline_DECL_ATTR,
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index b939da5..4a898f2 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -642,8 +642,10 @@
void printAbstractTypeParamCommon(AbstractTypeParamDecl *decl,
const char *name) {
printCommon(decl, name);
- if (auto superclassTy = decl->getSuperclass()) {
- OS << " superclass='" << superclassTy->getString() << "'";
+ if (decl->getDeclContext()->getGenericEnvironmentOfContext()) {
+ if (auto superclassTy = decl->getSuperclass()) {
+ OS << " superclass='" << superclassTy->getString() << "'";
+ }
}
}
@@ -734,6 +736,8 @@
OS << " final";
if (VD->isObjC())
OS << " @objc";
+ if (VD->isDynamic())
+ OS << " dynamic";
}
void printCommon(NominalTypeDecl *NTD, const char *Name,
diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp
index bb065bb..64f5314 100644
--- a/lib/AST/Attr.cpp
+++ b/lib/AST/Attr.cpp
@@ -493,10 +493,10 @@
break;
}
- case DAK_NSKeyedArchiverClassName: {
- Printer.printAttrName("@NSKeyedArchiverClassName");
+ case DAK_ObjCRuntimeName: {
+ Printer.printAttrName("@objc");
Printer << "(";
- auto *attr = cast<NSKeyedArchiverClassNameAttr>(this);
+ auto *attr = cast<ObjCRuntimeNameAttr>(this);
Printer << "\"" << attr->Name << "\"";
Printer << ")";
break;
@@ -571,6 +571,7 @@
case DAK_AutoClosure:
return "autoclosure";
case DAK_ObjC:
+ case DAK_ObjCRuntimeName:
return "objc";
case DAK_Inline: {
switch (cast<InlineAttr>(this)->getKind()) {
@@ -626,8 +627,6 @@
return "_specialize";
case DAK_Implements:
return "_implements";
- case DAK_NSKeyedArchiverClassName:
- return "NSKeyedArchiverClassName";
}
llvm_unreachable("bad DeclAttrKind");
}
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index e3014bc..9974a64 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1359,7 +1359,7 @@
// Private and (unversioned) internal variables always have a
// fixed layout.
- if (getEffectiveAccess() < Accessibility::Public)
+ if (getEffectiveAccess(/*forLinkage=*/false) < Accessibility::Public)
return true;
// Check for an explicit @_fixed_layout attribute.
@@ -1952,19 +1952,19 @@
return Accessibility::Public;
}
-Accessibility ValueDecl::getEffectiveAccess() const {
+Accessibility ValueDecl::getEffectiveAccess(bool forLinkage) const {
Accessibility effectiveAccess = getFormalAccess();
// Handle @testable.
switch (effectiveAccess) {
case Accessibility::Public:
- if (getModuleContext()->isTestingEnabled())
+ if (forLinkage && getModuleContext()->isTestingEnabled())
effectiveAccess = getTestableAccess(this);
break;
case Accessibility::Open:
break;
case Accessibility::Internal:
- if (getModuleContext()->isTestingEnabled())
+ if (forLinkage && getModuleContext()->isTestingEnabled())
effectiveAccess = getTestableAccess(this);
else if (isVersionedInternalDecl(this))
effectiveAccess = Accessibility::Public;
@@ -1978,7 +1978,7 @@
if (auto enclosingNominal = dyn_cast<NominalTypeDecl>(getDeclContext())) {
effectiveAccess = std::min(effectiveAccess,
- enclosingNominal->getEffectiveAccess());
+ enclosingNominal->getEffectiveAccess(forLinkage));
} else if (auto enclosingExt = dyn_cast<ExtensionDecl>(getDeclContext())) {
// Just check the base type. If it's a constrained extension, Sema should
@@ -1986,7 +1986,7 @@
if (auto extendedTy = enclosingExt->getExtendedType()) {
if (auto nominal = extendedTy->getAnyNominal()) {
effectiveAccess = std::min(effectiveAccess,
- nominal->getEffectiveAccess());
+ nominal->getEffectiveAccess(forLinkage));
}
}
@@ -2117,7 +2117,7 @@
bool NominalTypeDecl::hasFixedLayout() const {
// Private and (unversioned) internal types always have a
// fixed layout.
- if (getEffectiveAccess() < Accessibility::Public)
+ if (getEffectiveAccess(/*forLinkage=*/false) < Accessibility::Public)
return true;
// Check for an explicit @_fixed_layout attribute.
@@ -2759,6 +2759,8 @@
return objcClass->getObjCRuntimeNameAsString();
// If there is an 'objc' attribute with a name, use that name.
+ if (auto attr = getAttrs().getAttribute<ObjCRuntimeNameAttr>())
+ return attr->Name;
if (auto objc = getAttrs().getAttribute<ObjCAttr>()) {
if (auto name = objc->getName())
return name->getString(buffer);
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 4d5bfdb..1cd1274 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -445,6 +445,12 @@
// outer types.
return getModuleScopeContext();
}
+ if (isa<NominalTypeDecl>(this)) {
+ // If we are inside a nominal type that is inside a protocol,
+ // skip the protocol.
+ if (isa<ProtocolDecl>(getParent()))
+ return getModuleScopeContext();
+ }
return getParent();
}
@@ -544,7 +550,7 @@
// If the function is not externally visible, we will not be serializing
// its body.
- if (AFD->getEffectiveAccess() < Accessibility::Public)
+ if (AFD->getEffectiveAccess(/*forLinkage=*/false) < Accessibility::Public)
break;
// Bodies of public transparent and always-inline functions are
diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp
index 3068351..c32a9ea 100644
--- a/lib/AST/DiagnosticEngine.cpp
+++ b/lib/AST/DiagnosticEngine.cpp
@@ -429,9 +429,9 @@
break;
case DiagnosticArgumentKind::ValueDecl:
- Out << '\'';
+ Out << FormatOpts.OpeningQuotationMark;
Arg.getAsValueDecl()->getFullName().printPretty(Out);
- Out << '\'';
+ Out << FormatOpts.ClosingQuotationMark;
break;
case DiagnosticArgumentKind::Type: {
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 283779a..7894429 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -1662,8 +1662,12 @@
assocType = dyn_cast<AssociatedTypeDecl>(member);
// FIXME: Filter out type declarations that aren't in the protocol itself?
- if (!concreteDecl && !isa<AssociatedTypeDecl>(member))
- concreteDecl = dyn_cast<TypeDecl>(member);
+ if (!concreteDecl && !isa<AssociatedTypeDecl>(member)) {
+ if (!member->hasInterfaceType())
+ builder.getLazyResolver()->resolveDeclSignature(member);
+ if (member->hasInterfaceType())
+ concreteDecl = dyn_cast<TypeDecl>(member);
+ }
}
if (assocType &&
@@ -1781,8 +1785,12 @@
assocType = dyn_cast<AssociatedTypeDecl>(member);
// FIXME: Filter out concrete types that aren't in the protocol itself?
- if (!concreteDecl && !isa<AssociatedTypeDecl>(member))
- concreteDecl = dyn_cast<TypeDecl>(member);
+ if (!concreteDecl && !isa<AssociatedTypeDecl>(member)) {
+ if (!member->hasInterfaceType())
+ proto->getASTContext().getLazyResolver()->resolveDeclSignature(member);
+ if (member->hasInterfaceType())
+ concreteDecl = dyn_cast<TypeDecl>(member);
+ }
}
// There is no associated type or concrete type with this name in this
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 5075686..09ed0e2 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -599,6 +599,10 @@
// existential's list of conformances and the existential conforms to
// itself.
if (type->isExistentialType()) {
+ // FIXME: Recursion break.
+ if (!protocol->hasValidSignature())
+ return None;
+
// If the existential type cannot be represented or the protocol does not
// conform to itself, there's no point in looking further.
if (!protocol->existentialConformsToSelf() ||
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 9cebd69..67c9596 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -642,9 +642,12 @@
DC = DC->getParent();
- BaseDecl = selfParam;
ExtendedType = DC->getSelfTypeInContext();
MetaBaseDecl = DC->getAsNominalTypeOrNominalTypeExtensionContext();
+ if (Ctx.isSwiftVersion3())
+ BaseDecl = MetaBaseDecl;
+ else
+ BaseDecl = selfParam;
isTypeLookup = PBD->isStatic();
}
@@ -705,7 +708,7 @@
// might be type checking a default argument expression and
// performing name lookup from there), the base declaration
// is the nominal type, not 'self'.
- if (!AFD->isImplicit() &&
+ if ((Ctx.isSwiftVersion3() || !AFD->isImplicit()) &&
Loc.isValid() &&
AFD->getBodySourceRange().isValid() &&
!SM.rangeContainsTokenLoc(AFD->getBodySourceRange(), Loc)) {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 860ff42..3adea8c 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -3906,24 +3906,25 @@
case TypeKind::ProtocolComposition: {
auto pc = cast<ProtocolCompositionType>(base);
- SmallVector<Type, 4> members;
+ SmallVector<Type, 4> substMembers;
+ auto members = pc->getMembers();
bool anyChanged = false;
unsigned index = 0;
- for (auto member : pc->getMembers()) {
+ for (auto member : members) {
auto substMember = member.transformRec(fn);
if (!substMember)
return Type();
if (anyChanged) {
- members.push_back(substMember);
+ substMembers.push_back(substMember);
++index;
continue;
}
if (substMember.getPointer() != member.getPointer()) {
anyChanged = true;
- members.append(members.begin(), members.begin() + index);
- members.push_back(substMember);
+ substMembers.append(members.begin(), members.begin() + index);
+ substMembers.push_back(substMember);
}
++index;
@@ -3932,7 +3933,8 @@
if (!anyChanged)
return *this;
- return ProtocolCompositionType::get(Ptr->getASTContext(), members,
+ return ProtocolCompositionType::get(Ptr->getASTContext(),
+ substMembers,
pc->hasExplicitAnyObject());
}
}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 2aa0962..b4da911 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -35,6 +35,7 @@
#include "swift/Option/SanitizerOptions.h"
#include "swift/Parse/Lexer.h"
#include "swift/Config.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
@@ -1844,7 +1845,8 @@
static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
types::ID outputType, const OutputInfo &OI,
- const TypeToPathMap *outputMap) {
+ const TypeToPathMap *outputMap,
+ StringRef outputPath = StringRef()) {
StringRef outputMapPath;
if (outputMap) {
auto iter = outputMap->find(outputType);
@@ -1855,6 +1857,8 @@
if (!outputMapPath.empty()) {
// Prefer a path from the OutputMap.
output.setAdditionalOutputForType(outputType, outputMapPath);
+ } else if (!outputPath.empty()) {
+ output.setAdditionalOutputForType(outputType, outputPath);
} else {
// Put the auxiliary output file next to the primary output file.
llvm::SmallString<128> path;
@@ -1874,6 +1878,58 @@
}
}
+static void addDiagFileOutputForPersistentPCHAction(Compilation &C,
+ const GeneratePCHJobAction *JA,
+ CommandOutput &output,
+ const OutputInfo &OI,
+ const TypeToPathMap *outputMap,
+ DiagnosticEngine &diags) {
+ assert(JA->isPersistentPCH());
+
+ // For a persistent PCH we don't use an output, the frontend determines
+ // the filename to use for the PCH. For the diagnostics file, try to
+ // determine an invocation-specific path inside the directory where the
+ // PCH is going to be written, and fallback to a temporary file if we
+ // cannot determine such a path.
+
+ StringRef pchOutDir = JA->getPersistentPCHDir();
+ StringRef headerPath = output.getBaseInput(JA->getInputIndex());
+ StringRef stem = llvm::sys::path::stem(headerPath);
+ StringRef suffix = types::getTypeTempSuffix(types::TY_SerializedDiagnostics);
+ SmallString<256> outPathBuf;
+
+ if (const Arg *A = C.getArgs().getLastArg(options::OPT_emit_module_path)) {
+ // The module file path is unique for a specific module and architecture
+ // (it won't be concurrently written to) so we can use the path as hash
+ // for determining the filename to use for the diagnostic file.
+ StringRef ModuleOutPath = A->getValue();
+ outPathBuf = pchOutDir;
+ llvm::sys::path::append(outPathBuf, stem);
+ outPathBuf += '-';
+ auto code = llvm::hash_value(ModuleOutPath);
+ outPathBuf += llvm::APInt(64, code).toString(36, /*Signed=*/false);
+ llvm::sys::path::replace_extension(outPathBuf, suffix);
+ }
+
+ if (outPathBuf.empty()) {
+ // Fallback to creating a temporary file.
+ std::error_code EC =
+ llvm::sys::fs::createTemporaryFile(stem, suffix, outPathBuf);
+ if (EC) {
+ diags.diagnose(SourceLoc(),
+ diag::error_unable_to_make_temporary_file,
+ EC.message());
+ return;
+ }
+ C.addTemporaryFile(outPathBuf.str());
+ }
+
+ if (!outPathBuf.empty()) {
+ addAuxiliaryOutput(C, output, types::TY_SerializedDiagnostics, OI,
+ outputMap, outPathBuf.str());
+ }
+}
+
/// If the file at \p input has not been modified since the last build (i.e. its
/// mtime has not changed), adjust the Job's condition accordingly.
static void
@@ -2108,8 +2164,14 @@
if (isa<CompileJobAction>(JA) || isa<GeneratePCHJobAction>(JA)) {
// Choose the serialized diagnostics output path.
if (C.getArgs().hasArg(options::OPT_serialize_diagnostics)) {
- addAuxiliaryOutput(C, *Output, types::TY_SerializedDiagnostics, OI,
- OutputMap);
+ auto pchJA = dyn_cast<GeneratePCHJobAction>(JA);
+ if (pchJA && pchJA->isPersistentPCH()) {
+ addDiagFileOutputForPersistentPCHAction(C, pchJA, *Output, OI,
+ OutputMap, Diags);
+ } else {
+ addAuxiliaryOutput(C, *Output, types::TY_SerializedDiagnostics, OI,
+ OutputMap);
+ }
// Remove any existing diagnostics files so that clients can detect their
// presence to determine if a command was run.
diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp
index 792d2bb..900d9fa 100644
--- a/lib/IDE/Utils.cpp
+++ b/lib/IDE/Utils.cpp
@@ -781,8 +781,7 @@
}
}
-
-DeclNameViewer::DeclNameViewer(StringRef Text): HasParen(false) {
+DeclNameViewer::DeclNameViewer(StringRef Text): IsValid(true), HasParen(false) {
auto ArgStart = Text.find_first_of('(');
if (ArgStart == StringRef::npos) {
BaseName = Text;
@@ -791,17 +790,21 @@
HasParen = true;
BaseName = Text.substr(0, ArgStart);
auto ArgEnd = Text.find_last_of(')');
- assert(ArgEnd != StringRef::npos);
+ if (ArgEnd == StringRef::npos) {
+ IsValid = false;
+ return;
+ }
StringRef AllArgs = Text.substr(ArgStart + 1, ArgEnd - ArgStart - 1);
AllArgs.split(Labels, ":");
if (Labels.empty())
return;
- assert(Labels.back().empty());
- Labels.pop_back();
- std::transform(Labels.begin(), Labels.end(), Labels.begin(),
- [](StringRef Label) {
- return Label == "_" ? StringRef() : Label;
- });
+ if ((IsValid = Labels.back().empty())) {
+ Labels.pop_back();
+ std::transform(Labels.begin(), Labels.end(), Labels.begin(),
+ [](StringRef Label) {
+ return Label == "_" ? StringRef() : Label;
+ });
+ }
}
unsigned DeclNameViewer::commonPartsCount(DeclNameViewer &Other) const {
diff --git a/lib/IRGen/AllocStackHoisting.cpp b/lib/IRGen/AllocStackHoisting.cpp
index 90f6c43..5c47e78 100644
--- a/lib/IRGen/AllocStackHoisting.cpp
+++ b/lib/IRGen/AllocStackHoisting.cpp
@@ -111,8 +111,7 @@
/// Hack to workaround a clang LTO bug.
LLVM_ATTRIBUTE_NOINLINE
void moveAllocStackToBeginningOfBlock(AllocStackInst* AS, SILBasicBlock *BB) {
- AS->removeFromParent();
- BB->push_front(AS);
+ AS->moveFront(BB);
}
/// Assign a single alloc_stack instruction to all the alloc_stacks in the
@@ -388,8 +387,7 @@
auto *EntryBB = F->getEntryBlock();
for (auto *AllocStack : AllocStackToHoist) {
// Insert at the beginning of the entry block.
- AllocStack->removeFromParent();
- EntryBB->push_front(AllocStack);
+ AllocStack->moveFront(EntryBB);
// Delete dealloc_stacks.
eraseDeallocStacks(AllocStack);
}
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 60ef4a4..c30f6dd 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -971,7 +971,7 @@
classTI.getLayout(*this, selfType),
classTI.getClassLayout(*this, selfType));
- IRGen.addClassForArchiveNameRegistration(D);
+ IRGen.addClassForEagerInitialization(D);
emitNestedTypeDecls(D->getMembers());
emitFieldMetadataRecord(D);
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index b036575..8a22e3e 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -948,8 +948,8 @@
}
}
-void IRGenerator::emitNSArchiveClassNameRegistration() {
- if (ClassesForArchiveNameRegistration.empty())
+void IRGenerator::emitEagerClassInitialization() {
+ if (ClassesForEagerInitialization.empty())
return;
// Emit the register function in the primary module.
@@ -957,37 +957,28 @@
llvm::Function *RegisterFn = llvm::Function::Create(
llvm::FunctionType::get(IGM->VoidTy, false),
- llvm::GlobalValue::InternalLinkage,
- "_swift_register_class_names_for_archives");
+ llvm::GlobalValue::PrivateLinkage,
+ "_swift_eager_class_initialization");
IRGenFunction RegisterIGF(*IGM, RegisterFn);
RegisterFn->setAttributes(IGM->constructInitialAttributes());
IGM->Module.getFunctionList().push_back(RegisterFn);
RegisterFn->setCallingConv(IGM->DefaultCC);
- for (ClassDecl *CD : ClassesForArchiveNameRegistration) {
+ for (ClassDecl *CD : ClassesForEagerInitialization) {
Type Ty = CD->getDeclaredType();
llvm::Value *MetaData = RegisterIGF.emitTypeMetadataRef(getAsCanType(Ty));
- if (auto *LegacyAttr = CD->getAttrs().
- getAttribute<NSKeyedArchiverClassNameAttr>()) {
- // Register the name for the class in the NSKeyed(Un)Archiver.
- llvm::Value *NameStr = IGM->getAddrOfGlobalString(LegacyAttr->Name);
- RegisterIGF.Builder.CreateCall(IGM->getRegisterClassNameForArchivingFn(),
- {NameStr, MetaData});
- } else {
- assert(CD->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>());
+ assert(CD->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>());
- // In this case we don't add a name mapping, but just get the metadata
- // to make sure that the class is registered. But: we need to add a use
- // (empty inline asm instruction) for the metadata. Otherwise
- // llvm would optimize the metadata accessor call away because it's
- // defined as "readnone".
- llvm::FunctionType *asmFnTy =
- llvm::FunctionType::get(IGM->VoidTy, {MetaData->getType()},
- false /* = isVarArg */);
- llvm::InlineAsm *inlineAsm =
- llvm::InlineAsm::get(asmFnTy, "", "r", true /* = SideEffects */);
- RegisterIGF.Builder.CreateCall(inlineAsm, MetaData);
- }
+ // Get the metadata to make sure that the class is registered. We need to
+ // add a use (empty inline asm instruction) for the metadata. Otherwise
+ // llvm would optimize the metadata accessor call away because it's
+ // defined as "readnone".
+ llvm::FunctionType *asmFnTy =
+ llvm::FunctionType::get(IGM->VoidTy, {MetaData->getType()},
+ false /* = isVarArg */);
+ llvm::InlineAsm *inlineAsm =
+ llvm::InlineAsm::get(asmFnTy, "", "r", true /* = SideEffects */);
+ RegisterIGF.Builder.CreateCall(inlineAsm, MetaData);
}
RegisterIGF.Builder.CreateRetVoid();
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index 388b938..c68229d 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -731,7 +731,7 @@
IGM.emitTypeMetadataRecords();
IGM.emitBuiltinReflectionMetadata();
IGM.emitReflectionMetadataVersion();
- irgen.emitNSArchiveClassNameRegistration();
+ irgen.emitEagerClassInitialization();
}
// Emit symbols for eliminated dead methods.
@@ -910,7 +910,7 @@
irgen.emitReflectionMetadataVersion();
- irgen.emitNSArchiveClassNameRegistration();
+ irgen.emitEagerClassInitialization();
// Emit reflection metadata for builtin and imported types.
irgen.emitBuiltinReflectionMetadata();
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index b5d3fd4..a073dce 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -758,11 +758,8 @@
}
}
-void IRGenerator::addClassForArchiveNameRegistration(ClassDecl *ClassDecl) {
-
- // Those two attributes are interesting to us
- if (!ClassDecl->getAttrs().hasAttribute<NSKeyedArchiverClassNameAttr>() &&
- !ClassDecl->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>())
+void IRGenerator::addClassForEagerInitialization(ClassDecl *ClassDecl) {
+ if (!ClassDecl->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>())
return;
// Exclude some classes where those attributes make no sense but could be set
@@ -775,7 +772,7 @@
if (ClassDecl->hasClangNode())
return;
- ClassesForArchiveNameRegistration.push_back(ClassDecl);
+ ClassesForEagerInitialization.push_back(ClassDecl);
}
llvm::AttributeSet IRGenModule::getAllocAttrs() {
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 9c8f743..d8bd0d8 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -222,7 +222,7 @@
/// The queue of lazy witness tables to emit.
llvm::SmallVector<SILWitnessTable *, 4> LazyWitnessTables;
- llvm::SmallVector<ClassDecl *, 4> ClassesForArchiveNameRegistration;
+ llvm::SmallVector<ClassDecl *, 4> ClassesForEagerInitialization;
/// The order in which all the SIL function definitions should
/// appear in the translation unit.
@@ -298,7 +298,7 @@
/// Emit a symbol identifying the reflection metadata version.
void emitReflectionMetadataVersion();
- void emitNSArchiveClassNameRegistration();
+ void emitEagerClassInitialization();
/// Checks if the metadata of \p Nominal can be emitted lazily.
///
@@ -338,7 +338,7 @@
fn, IGM});
}
- void addClassForArchiveNameRegistration(ClassDecl *ClassDecl);
+ void addClassForEagerInitialization(ClassDecl *ClassDecl);
unsigned getFunctionOrder(SILFunction *F) {
auto it = FunctionOrder.find(F);
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5bab4bf..158f3ed 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -569,6 +569,7 @@
case DAK_RawDocComment:
case DAK_ObjCBridged:
+ case DAK_ObjCRuntimeName:
case DAK_SynthesizedProtocol:
llvm_unreachable("virtual attributes should not be parsed "
"by attribute parsing code");
@@ -743,8 +744,7 @@
}
case DAK_CDecl:
- case DAK_SILGenName:
- case DAK_NSKeyedArchiverClassName: {
+ case DAK_SILGenName: {
if (!consumeIf(tok::l_paren)) {
diagnose(Loc, diag::attr_expected_lparen, AttrName,
DeclAttribute::isDeclModifier(DK));
@@ -787,10 +787,6 @@
else if (DK == DAK_CDecl)
Attributes.add(new (Context) CDeclAttr(AsmName.getValue(), AtLoc,
AttrRange, /*Implicit=*/false));
- else if (DK == DAK_NSKeyedArchiverClassName)
- Attributes.add(new (Context) NSKeyedArchiverClassNameAttr(
- AsmName.getValue(), AtLoc,
- AttrRange, /*Implicit=*/false));
else
llvm_unreachable("out of sync with switch");
}
@@ -1485,6 +1481,38 @@
return false;
}
+ // FIXME: Remove this after Swift 4.
+ if (DK == DAK_Count && Tok.getText() == "NSKeyedArchiverClassName") {
+ auto activeDiag = diagnose(Tok,diag::attr_nskeyedarchiverclassname_removed);
+ activeDiag.fixItReplace(Tok.getLoc(), "objc");
+ consumeToken();
+ SourceLoc lParenLoc;
+ if (consumeIf(tok::l_paren, lParenLoc)) {
+ if (Tok.is(tok::string_literal)) {
+ activeDiag.fixItRemoveChars(Tok.getLoc(),
+ Tok.getLoc().getAdvancedLoc(1));
+ SourceLoc endLoc = Tok.getLoc().getAdvancedLoc(Tok.getLength());
+ activeDiag.fixItRemoveChars(endLoc.getAdvancedLoc(-1), endLoc);
+ }
+ skipUntil(tok::r_paren);
+ SourceLoc rParenLoc;
+ parseMatchingToken(tok::r_paren, rParenLoc,
+ diag::attr_warn_unused_result_expected_rparen,
+ lParenLoc);
+ }
+ return false;
+ }
+
+ // FIXME: Remove this after Swift 4.
+ if (DK == DAK_Count &&
+ Tok.getText() == "NSKeyedArchiverEncodeNonGenericSubclassesOnly") {
+ diagnose(Tok,
+ diag::attr_nskeyedarchiverencodenongenericsubclassesonly_removed)
+ .fixItRemove(SourceRange(AtLoc, Tok.getLoc()));
+ consumeToken();
+ return false;
+ }
+
if (DK != DAK_Count && !DeclAttribute::shouldBeRejectedByParser(DK))
return parseNewDeclAttribute(Attributes, AtLoc, DK);
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index 21986ec..499e852 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -364,7 +364,7 @@
if (metatypeInst->use_empty() &&
metatypeInst->getParent() == getInsertionBB()) {
auto origLoc = metatypeInst->getLoc();
- metatypeInst->removeFromParent();
+ metatypeInst->eraseFromParent();
return createMetatype(origLoc, Ty);
}
}
@@ -382,7 +382,7 @@
if (metatypeInst->use_empty() &&
metatypeInst->getParent() == getInsertionBB()) {
auto origLoc = metatypeInst->getLoc();
- metatypeInst->removeFromParent();
+ metatypeInst->eraseFromParent();
return createMetatype(origLoc, Ty);
}
}
diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp
index 8b07449..b672650 100644
--- a/lib/SIL/SILInstruction.cpp
+++ b/lib/SIL/SILInstruction.cpp
@@ -109,13 +109,6 @@
return getFunction()->getModule();
}
-/// removeFromParent - This method unlinks 'self' from the containing basic
-/// block, but does not delete it.
-///
-void SILInstruction::removeFromParent() {
- getParent()->remove(this);
-}
-
/// eraseFromParent - This method unlinks 'self' from the containing basic
/// block and deletes it.
///
@@ -124,6 +117,11 @@
getParent()->erase(this);
}
+void SILInstruction::moveFront(SILBasicBlock *Block) {
+ getParent()->remove(this);
+ Block->push_front(this);
+}
+
/// Unlink this instruction from its current basic block and insert it into
/// the basic block that Later lives in, right before Later.
void SILInstruction::moveBefore(SILInstruction *Later) {
@@ -170,18 +168,12 @@
}
}
-void SILInstruction::replaceAllUsesWithUndef() {
- SILModule &Mod = getModule();
- while (!use_empty()) {
- Operand *Op = *use_begin();
- Op->set(SILUndef::get(Op->get()->getType(), Mod));
- }
-}
-
namespace {
- class InstructionDestroyer : public SILVisitor<InstructionDestroyer> {
- public:
-#define VALUE(CLASS, PARENT) void visit##CLASS(CLASS *I) { I->~CLASS(); }
+class InstructionDestroyer
+ : public SILInstructionVisitor<InstructionDestroyer> {
+public:
+#define INST(CLASS, PARENT, TEXTUALNAME, MEMBEHAVIOR, MAYRELEASE) \
+ void visit##CLASS(CLASS *I) { I->~CLASS(); }
#include "swift/SIL/SILNodes.def"
};
} // end anonymous namespace
diff --git a/lib/SIL/SILValue.cpp b/lib/SIL/SILValue.cpp
index 96febcc..bce6e85 100644
--- a/lib/SIL/SILValue.cpp
+++ b/lib/SIL/SILValue.cpp
@@ -45,6 +45,18 @@
}
}
+void ValueBase::replaceAllUsesWithUndef() {
+ SILModule *Mod = getModule();
+ if (!Mod) {
+ llvm_unreachable("replaceAllUsesWithUndef can only be used on ValueBase "
+ "that have access to the parent module.");
+ }
+ while (!use_empty()) {
+ Operand *Op = *use_begin();
+ Op->set(SILUndef::get(Op->get()->getType(), Mod));
+ }
+}
+
SILBasicBlock *ValueBase::getParentBlock() const {
auto *NonConstThis = const_cast<ValueBase *>(this);
if (auto *Inst = dyn_cast<SILInstruction>(NonConstThis))
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index e34d8e2..8715fc1 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -895,8 +895,12 @@
//
// We need this to make sure that we insert a release in the appropriate
// locations to balance the +1 from the creation of the partial apply.
+ //
+ // However, thin_to_thick_function closures don't have a context and
+ // don't need to be released.
llvm::TinyPtrVector<SILBasicBlock *> NonFailureExitBBs;
if (ClosureParamInfo.isGuaranteed() &&
+ !isa<ThinToThickFunctionInst>(&II) &&
!findAllNonFailureExitBBs(ApplyCallee, NonFailureExitBBs)) {
continue;
}
diff --git a/lib/SILOptimizer/IPO/EagerSpecializer.cpp b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
index bee7361..c549b0e 100644
--- a/lib/SILOptimizer/IPO/EagerSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
@@ -102,8 +102,7 @@
// expects.
auto *TupleI = cast<SILInstruction>(RetInst->getOperand(0));
if (TupleI->hasOneUse()) {
- TupleI->removeFromParent();
- RetBB->insert(RetInst, TupleI);
+ TupleI->moveBefore(RetInst);
} else {
TupleI = TupleI->clone(RetInst);
RetInst->setOperand(0, TupleI);
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index f2fb550..6a93b38 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -2237,8 +2237,7 @@
}
case DIKind::Yes:
// super.init() already called, just release the value.
- Release->removeFromParent();
- B.getInsertionBB()->insert(B.getInsertionPoint(), Release);
+ Release->moveBefore(&*B.getInsertionPoint());
continue;
}
}
diff --git a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
index bf5f9f3..860d0a3 100644
--- a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
+++ b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
@@ -608,6 +608,10 @@
if (!Callee)
return false;
+ if (Callee->hasSemanticsAttr("self_no_escaping_closure") ||
+ Callee->hasSemanticsAttr("pair_no_escaping_closure"))
+ return true;
+
// Add here the checks for any specific @_effects attributes that need
// to be skipped during the early inlining pass.
if (Callee->hasEffectsKind())
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index c26267f..4488af5 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -1351,7 +1351,7 @@
base = cs.coerceToRValue(base);
} else if (keyPathBGT->getDecl() ==
cs.getASTContext().getWritableKeyPathDecl()) {
- resultIsLValue = base->getType()->isLValueType();
+ resultIsLValue = cs.getType(base)->isLValueType();
} else if (keyPathBGT->getDecl() ==
cs.getASTContext().getReferenceWritableKeyPathDecl()) {
resultIsLValue = true;
@@ -4032,7 +4032,7 @@
simplifyExprType(E);
- if (E->getType()->hasError())
+ if (cs.getType(E)->hasError())
return E;
// If a component is already resolved, then all of them should be
@@ -7085,12 +7085,6 @@
auto metaTy = cs.getType(fn)->castTo<AnyMetatypeType>();
auto ty = metaTy->getInstanceType();
- // If this is an UnresolvedType in the system, preserve it.
- if (ty->is<UnresolvedType>()) {
- cs.setType(apply, ty);
- return apply;
- }
-
if (!cs.isTypeReference(fn)) {
bool isExistentialType = false;
// If this is an attempt to initialize existential type.
@@ -7117,12 +7111,18 @@
// We're constructing a value of nominal type. Look for the constructor or
// enum element to use.
- assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
- ty->isExistentialType() || ty->is<ArchetypeType>());
auto ctorLocator = cs.getConstraintLocator(
locator.withPathElement(ConstraintLocator::ApplyFunction)
.withPathElement(ConstraintLocator::ConstructorMember));
auto selected = getOverloadChoiceIfAvailable(ctorLocator);
+ if (!selected) {
+ assert(ty->hasError() || ty->hasUnresolvedType());
+ cs.setType(apply, ty);
+ return apply;
+ }
+
+ assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
+ ty->isExistentialType() || ty->is<ArchetypeType>());
// We have the constructor.
auto choice = selected->choice;
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 43c212b..6b599bf 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -6240,7 +6240,7 @@
diag.highlight(rhsExpr->getSourceRange());
if (auto optUnwrappedType = rhsType->getOptionalObjectType()) {
if (lhsType->isEqual(optUnwrappedType)) {
- diag.fixItInsert(lhsExpr->getEndLoc(), "?");
+ diag.fixItInsertAfter(lhsExpr->getEndLoc(), "?");
}
}
return true;
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 88277eb..ce1cd3f 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -70,22 +70,14 @@
case SK_ValueToOptional:
log << "value to optional";
break;
-
- case SK_ArrayPointerConversion:
- log << "array-to-pointer conversion";
- break;
- case SK_ScalarPointerConversion:
- log << "scalar-to-pointer conversion";
- break;
case SK_EmptyExistentialConversion:
log << "empty-existential conversion";
break;
case SK_KeyPathSubscript:
log << "key path subscript";
break;
-
- case SK_StringToPointerConversion:
- log << "string-to-pointer conversion";
+ case SK_ValueToPointerConversion:
+ log << "value-to-pointer conversion";
break;
}
log << ")\n";
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 041895a..008fe07 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -2080,7 +2080,7 @@
// Favor an UnsafeMutablePointer-to-UnsafeMutablePointer
// conversion.
if (type1PointerKind != pointerKind)
- increaseScore(ScoreKind::SK_ScalarPointerConversion);
+ increaseScore(ScoreKind::SK_ValueToPointerConversion);
conversionsOrFixes.push_back(
ConversionRestrictionKind::PointerToPointer);
}
@@ -2088,7 +2088,7 @@
else if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
pointerKind == PTK_UnsafeRawPointer) {
if (type1PointerKind != pointerKind)
- increaseScore(ScoreKind::SK_ScalarPointerConversion);
+ increaseScore(ScoreKind::SK_ValueToPointerConversion);
conversionsOrFixes.push_back(
ConversionRestrictionKind::PointerToPointer);
}
@@ -2980,8 +2980,8 @@
}
}
}
-
- // If the invocation's argument expression has a favored constraint,
+
+ // If the invocation's argument expression has a favored type,
// use that information to determine whether a specific overload for
// the initializer should be favored.
if (favoredType && result.FavoredChoice == ~0U) {
@@ -2996,7 +2996,8 @@
argType = ctor.Decl->getInnermostDeclContext()
->mapTypeIntoContext(argType);
if (argType->isEqual(favoredType))
- result.FavoredChoice = result.ViableCandidates.size();
+ if (!ctor->getAttrs().isUnavailable(getASTContext()))
+ result.FavoredChoice = result.ViableCandidates.size();
}
}
}
@@ -4378,6 +4379,7 @@
auto baseType1 = getFixedTypeRecursive(*isArrayType(obj1), false, false);
auto baseType2 = getBaseTypeForPointer(*this, t2);
+ increaseScore(ScoreKind::SK_ValueToPointerConversion);
return matchTypes(baseType1, baseType2,
ConstraintKind::BindToPointerType,
subflags, locator);
@@ -4397,7 +4399,7 @@
// If we haven't resolved the element type, generate constraints.
if (baseType2->isTypeVariableOrMember()) {
if (flags.contains(TMF_GenerateConstraints)) {
- increaseScore(SK_StringToPointerConversion);
+ increaseScore(ScoreKind::SK_ValueToPointerConversion);
auto int8Con = Constraint::create(*this, ConstraintKind::Bind,
baseType2, TC.getInt8Type(DC),
@@ -4421,7 +4423,7 @@
return SolutionKind::Error;
}
- increaseScore(SK_StringToPointerConversion);
+ increaseScore(ScoreKind::SK_ValueToPointerConversion);
return SolutionKind::Solved;
}
@@ -4436,6 +4438,7 @@
// Set up the disjunction for the array or scalar cases.
+ increaseScore(ScoreKind::SK_ValueToPointerConversion);
return matchTypes(baseType1, baseType2,
ConstraintKind::BindToPointerType,
subflags, locator);
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 2171fe2..fd34b8d 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -2338,11 +2338,21 @@
/// Whether we should short-circuit a disjunction that already has a
/// solution when we encounter the given constraint.
static bool shortCircuitDisjunctionAt(Constraint *constraint,
- Constraint *successfulConstraint) {
-
+ Constraint *successfulConstraint,
+ ASTContext &ctx) {
+
// If the successfully applied constraint is favored, we'll consider that to
// be the "best".
if (successfulConstraint->isFavored() && !constraint->isFavored()) {
+#if !defined(NDEBUG)
+ if (successfulConstraint->getKind() == ConstraintKind::BindOverload) {
+ auto overloadChoice = successfulConstraint->getOverloadChoice();
+ assert((!overloadChoice.isDecl() ||
+ !overloadChoice.getDecl()->getAttrs().isUnavailable(ctx)) &&
+ "Unavailable decl should not be favored!");
+ }
+#endif
+
return true;
}
@@ -2533,7 +2543,8 @@
// short-circuit the disjunction.
if (lastSolvedChoice) {
auto *lastChoice = lastSolvedChoice->getConstraint();
- if (shortCircuitDisjunctionAt(¤tChoice, lastChoice))
+ if (shortCircuitDisjunctionAt(¤tChoice, lastChoice,
+ getASTContext()))
break;
}
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 4158953..9fb20e1 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -186,10 +186,6 @@
if (storage->isGetterMutating())
getter->setMutating();
- // If the var is marked final, then so is the getter.
- if (storage->isFinal())
- makeFinal(TC.Context, getter);
-
if (storage->isStatic())
getter->setStatic();
@@ -239,10 +235,6 @@
if (isStatic)
setter->setStatic();
- // If the var is marked final, then so is the getter.
- if (storage->isFinal())
- makeFinal(TC.Context, setter);
-
return setter;
}
@@ -824,17 +816,10 @@
// Okay, we have both the getter and setter. Set them in VD.
storage->addTrivialAccessors(getter, setter, nullptr);
- bool isDynamic = (storage->isDynamic() && storage->isObjC());
- if (isDynamic)
- makeDynamic(TC.Context, getter);
-
// Synthesize the body of the getter.
synthesizeTrivialGetter(getter, storage, TC);
if (setter) {
- if (isDynamic)
- makeDynamic(TC.Context, setter);
-
// Synthesize the body of the setter.
synthesizeTrivialSetter(setter, storage, setterValueParam, TC);
}
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index 17c4ad2..4b39709 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -379,7 +379,7 @@
if (parentTy) {
auto subs = parentTy->getContextSubstitutions(
- parentTy->getAnyNominal());
+ unboundDecl->getDeclContext());
for (auto pair : subs) {
auto found = replacements.find(
cast<GenericTypeParamType>(pair.first));
@@ -1314,7 +1314,11 @@
*favoredChoice,
useDC,
locator);
-
+
+ assert((!favoredChoice->isDecl() ||
+ !favoredChoice->getDecl()->getAttrs().isUnavailable(
+ getASTContext())) &&
+ "Cannot make unavailable decl favored!");
bindOverloadConstraint->setFavored();
overloads.push_back(bindOverloadConstraint);
@@ -1700,17 +1704,17 @@
lookupBaseType = objectType;
}
- if (!lookupBaseType->mayHaveMembers()) return type;
-
- auto subs = lookupBaseType->getContextSubstitutionMap(
+ if (lookupBaseType->mayHaveMembers()) {
+ auto subs = lookupBaseType->getContextSubstitutionMap(
cs.DC->getParentModule(),
- assocType->getDeclContext());
- auto result = assocType->getDeclaredInterfaceType().subst(subs);
+ assocType->getDeclContext());
+ auto result = assocType->getDeclaredInterfaceType().subst(subs);
- if (result)
- return result;
+ if (result)
+ return result;
+ }
- return DependentMemberType::get(ErrorType::get(newBase), assocType);
+ return DependentMemberType::get(lookupBaseType, assocType);
}
return type;
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 169bb83..c96f56a 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -408,18 +408,14 @@
SK_CollectionUpcastConversion,
/// A value-to-optional conversion.
SK_ValueToOptional,
- /// A conversion from an inout to a pointer of matching element type.
- SK_ScalarPointerConversion,
- /// A conversion from an array to a pointer of matching element type.
- SK_ArrayPointerConversion,
/// A conversion to an empty existential type ('Any' or '{}').
SK_EmptyExistentialConversion,
/// A key path application subscript.
SK_KeyPathSubscript,
- // A conversion from a string to a pointer.
- SK_StringToPointerConversion,
+ /// A conversion from a string, array, or inout to a pointer.
+ SK_ValueToPointerConversion,
- SK_LastScoreKind = SK_StringToPointerConversion,
+ SK_LastScoreKind = SK_ValueToPointerConversion,
};
/// The number of score kinds.
diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp
index 4602340..4cbf1c1 100644
--- a/lib/Sema/ITCDecl.cpp
+++ b/lib/Sema/ITCDecl.cpp
@@ -342,8 +342,6 @@
if (auto typeAliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
if (typeAliasDecl->getDeclContext()->isModuleScopeContext() &&
typeAliasDecl->getGenericParams() == nullptr) {
- typeAliasDecl->setValidationStarted();
-
TypeResolutionOptions options = TR_TypeAliasUnderlyingType;
if (typeAliasDecl->getFormalAccess() <= Accessibility::FilePrivate)
options |= TR_KnownNonCascadingDependency;
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index 9fd2894..a4fcb4f 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -91,7 +91,7 @@
return false;
// Public declarations are OK.
- if (D->getEffectiveAccess() >= Accessibility::Public)
+ if (D->getEffectiveAccess(/*forLinkage=*/false) >= Accessibility::Public)
return false;
// Enum cases are handled as part of their containing enum.
@@ -110,7 +110,8 @@
diagnose(loc, diag::resilience_decl_unavailable,
D->getDescriptiveKind(), D->getFullName(),
- D->getFormalAccess(), getFragileFunctionKind(DC));
+ D->getFormalAccessScope().accessibilityForDiagnostics(),
+ getFragileFunctionKind(DC));
diagnose(D, diag::resilience_decl_declared_here,
D->getDescriptiveKind(), D->getFullName());
return true;
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 72ab751..46a952e 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -86,6 +86,7 @@
IGNORED_ATTR(ObjC)
IGNORED_ATTR(ObjCBridged)
IGNORED_ATTR(ObjCNonLazyRealization)
+ IGNORED_ATTR(ObjCRuntimeName)
IGNORED_ATTR(Optional)
IGNORED_ATTR(Postfix)
IGNORED_ATTR(Prefix)
@@ -104,9 +105,7 @@
IGNORED_ATTR(ShowInInterface)
IGNORED_ATTR(DiscardableResult)
IGNORED_ATTR(Implements)
- IGNORED_ATTR(NSKeyedArchiverClassName)
IGNORED_ATTR(StaticInitializeObjCMetadata)
- IGNORED_ATTR(NSKeyedArchiverEncodeNonGenericSubclassesOnly)
IGNORED_ATTR(DowngradeExhaustivityCheck)
#undef IGNORED_ATTR
@@ -769,6 +768,7 @@
IGNORED_ATTR(ObjC)
IGNORED_ATTR(ObjCBridged)
IGNORED_ATTR(ObjCNonLazyRealization)
+ IGNORED_ATTR(ObjCRuntimeName)
IGNORED_ATTR(Optional)
IGNORED_ATTR(Ownership)
IGNORED_ATTR(Override)
@@ -784,7 +784,6 @@
IGNORED_ATTR(ShowInInterface)
IGNORED_ATTR(ObjCMembers)
IGNORED_ATTR(StaticInitializeObjCMetadata)
- IGNORED_ATTR(NSKeyedArchiverEncodeNonGenericSubclassesOnly)
IGNORED_ATTR(DowngradeExhaustivityCheck)
#undef IGNORED_ATTR
@@ -827,7 +826,6 @@
void visitDiscardableResultAttr(DiscardableResultAttr *attr);
void visitImplementsAttr(ImplementsAttr *attr);
- void visitNSKeyedArchiverClassNameAttr(NSKeyedArchiverClassNameAttr *attr);
};
} // end anonymous namespace
@@ -1826,19 +1824,14 @@
/*allowConcreteGenericParams=*/true);
}
-static Accessibility getAccessForDiagnostics(const ValueDecl *D) {
- return std::min(D->getFormalAccess(),
- D->getEffectiveAccess());
-}
-
void AttributeChecker::visitFixedLayoutAttr(FixedLayoutAttr *attr) {
auto *VD = cast<ValueDecl>(D);
- if (VD->getEffectiveAccess() < Accessibility::Public) {
+ if (VD->getEffectiveAccess(/*forLinkage=*/false) < Accessibility::Public) {
TC.diagnose(attr->getLocation(),
diag::fixed_layout_attr_on_internal_type,
VD->getBaseName(),
- getAccessForDiagnostics(VD))
+ VD->getFormalAccessScope().accessibilityForDiagnostics())
.fixItRemove(attr->getRangeWithAt());
attr->setInvalid();
}
@@ -1888,13 +1881,11 @@
// @_inlineable can only be applied to public or @_versioned
// declarations.
- if (VD->getFormalAccess() < Accessibility::Internal ||
- (!VD->getAttrs().hasAttribute<VersionedAttr>() &&
- VD->getFormalAccess() < Accessibility::Public)) {
+ if (VD->getEffectiveAccess(/*forLinkage=*/false) < Accessibility::Public) {
TC.diagnose(attr->getLocation(),
diag::inlineable_decl_not_public,
VD->getBaseName(),
- getAccessForDiagnostics(VD))
+ VD->getFormalAccessScope().accessibilityForDiagnostics())
.fixItRemove(attr->getRangeWithAt());
attr->setInvalid();
return;
@@ -1961,18 +1952,6 @@
}
}
-void AttributeChecker::visitNSKeyedArchiverClassNameAttr(
- NSKeyedArchiverClassNameAttr *attr) {
- auto classDecl = dyn_cast<ClassDecl>(D);
- if (!classDecl) return;
-
- // Generic classes can't use @NSKeyedArchiverClassName.
- if (classDecl->getGenericSignatureOfContext()) {
- diagnoseAndRemoveAttr(attr, diag::attr_NSKeyedArchiverClassName_generic,
- classDecl->getDeclaredInterfaceType());
- }
-}
-
void TypeChecker::checkDeclAttributes(Decl *D) {
AttributeChecker Checker(*this, D);
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index b32208e..6755693 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3830,11 +3830,8 @@
if (ASD->hasAccessorFunctions())
maybeAddMaterializeForSet(ASD, TC);
- if (ASD->isFinal()) {
- makeFinal(TC.Context, ASD->getGetter());
- makeFinal(TC.Context, ASD->getSetter());
+ if (ASD->isFinal())
makeFinal(TC.Context, ASD->getMaterializeForSetFunc());
- }
if (auto getter = ASD->getGetter())
TC.validateDecl(getter);
@@ -5170,9 +5167,14 @@
}
}
- // If the storage is dynamic, propagate to this accessor.
- if (isObjC && storage->isDynamic() && !FD->isDynamic())
- FD->getAttrs().add(new (TC.Context) DynamicAttr(/*implicit*/ true));
+ // If the storage is dynamic or final, propagate to this accessor.
+ if (isObjC &&
+ storage->isDynamic() &&
+ !storage->isFinal())
+ makeDynamic(TC.Context, FD);
+
+ if (storage->isFinal())
+ makeFinal(TC.Context, FD);
}
Optional<ForeignErrorConvention> errorConvention;
@@ -6138,10 +6140,9 @@
UNINTERESTING_ATTR(DiscardableResult)
UNINTERESTING_ATTR(ObjCMembers)
+ UNINTERESTING_ATTR(ObjCRuntimeName)
UNINTERESTING_ATTR(Implements)
- UNINTERESTING_ATTR(NSKeyedArchiverClassName)
UNINTERESTING_ATTR(StaticInitializeObjCMetadata)
- UNINTERESTING_ATTR(NSKeyedArchiverEncodeNonGenericSubclassesOnly)
UNINTERESTING_ATTR(DowngradeExhaustivityCheck)
#undef UNINTERESTING_ATTR
@@ -6191,10 +6192,7 @@
}
void visitDynamicAttr(DynamicAttr *attr) {
- if (!Override->isDynamic())
- // Dynamic is inherited.
- Override->getAttrs().add(
- new (TC.Context) DynamicAttr(/*implicit*/true));
+ makeDynamic(TC.Context, Override);
}
void visitObjCAttr(ObjCAttr *attr) {
@@ -7022,6 +7020,13 @@
if (auto attr = CD->getAttrs().getAttribute<ObjCAttr>()) {
if (kind == ObjCClassKind::ObjCMembers) {
+ if (attr->hasName() && !CD->isGenericContext()) {
+ // @objc with a name on a non-generic subclass of a generic class is
+ // just controlling the runtime name. Don't diagnose this case.
+ CD->getAttrs().add(new (TC.Context) ObjCRuntimeNameAttr(*attr));
+ return None;
+ }
+
TC.diagnose(attr->getLocation(), diag::objc_for_generic_class)
.fixItRemove(attr->getRangeWithAt());
}
@@ -7403,12 +7408,6 @@
// Make sure the getter and setter have valid types, since they will be
// used by SILGen for any accesses to this variable.
validateAbstractStorageDecl(VD, *this);
-
- if (VD->isDynamic()) {
- makeDynamic(Context, VD->getGetter());
- makeDynamic(Context, VD->getSetter());
- // Skip materializeForSet -- it won't be used with a dynamic property.
- }
}
break;
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index 8471028..d0190a4 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -16,6 +16,7 @@
//
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
+#include "swift/AST/Initializer.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/Basic/TopCollection.h"
@@ -192,7 +193,10 @@
auto baseDC = baseParam->getDeclContext();
if (isa<AbstractFunctionDecl>(baseDC))
baseDC = baseDC->getParent();
+ if (isa<PatternBindingInitializer>(baseDC))
+ baseDC = baseDC->getParent();
foundInType = baseDC->getDeclaredTypeInContext();
+ assert(foundInType && "bogus base declaration?");
} else {
auto baseNominal = cast<NominalTypeDecl>(found.getBaseDecl());
for (auto currentDC = dc; currentDC; currentDC = currentDC->getParent()) {
@@ -410,6 +414,14 @@
continue;
}
}
+
+ // Nominal type members of protocols cannot be accessed with an
+ // archetype base, because we have no way to recover the correct
+ // substitutions.
+ if (type->is<ArchetypeType>() &&
+ isa<NominalTypeDecl>(typeDecl)) {
+ continue;
+ }
}
// Substitute the base into the member's type.
@@ -447,6 +459,13 @@
// Use the type witness.
auto concrete = conformance->getConcrete();
Type memberType = concrete->getTypeWitness(assocType, this);
+
+ // This is the only case where NormalProtocolConformance::
+ // getTypeWitnessAndDecl() returns a null type.
+ if (concrete->getState() ==
+ ProtocolConformanceState::CheckingTypeWitnesses)
+ continue;
+
assert(memberType && "Missing type witness?");
// If we haven't seen this type result yet, add it to the result set.
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 570bdda..5f4f916 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -869,6 +869,12 @@
case PatternKind::Typed: {
TypedPattern *TP = cast<TypedPattern>(P);
bool hadError = validateTypedPattern(*this, dc, TP, options, &resolver);
+
+ // If we have unbound generic types, don't apply them below; instead,
+ // the caller will call typeCheckBinding() later.
+ if (P->getType()->hasUnboundGenericType())
+ return hadError;
+
Pattern *subPattern = TP->getSubPattern();
if (coercePatternToType(subPattern, dc, P->getType(),
options|TR_FromNonInferredPattern, &resolver,
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 7a06dbd..b869e99 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -3286,15 +3286,21 @@
///
/// \returns an empty result on success, or a description of the error.
static CheckTypeWitnessResult checkTypeWitness(TypeChecker &tc, DeclContext *dc,
+ ProtocolDecl *proto,
AssociatedTypeDecl *assocType,
Type type) {
- if (auto superclass = assocType->getSuperclass()) {
+ auto *moduleDecl = dc->getParentModule();
+ auto *reqtSig = assocType->getProtocol()->getRequirementSignature();
+ auto *depTy = DependentMemberType::get(proto->getSelfInterfaceType(),
+ assocType);
+
+ if (auto superclass = reqtSig->getSuperclassBound(depTy, *moduleDecl)) {
if (!superclass->isExactSuperclassOf(type))
return superclass->getAnyNominal();
}
// Check protocol conformances.
- for (auto reqProto : assocType->getConformingProtocols()) {
+ for (auto reqProto : reqtSig->getConformsTo(depTy, *moduleDecl)) {
if (!tc.conformsToProtocol(type, reqProto, dc, None))
return reqProto;
@@ -3323,6 +3329,11 @@
/// Attempt to resolve a type witness via member name lookup.
ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
AssociatedTypeDecl *assocType) {
+ if (!Proto->isRequirementSignatureComputed()) {
+ Conformance->setInvalid();
+ return ResolveWitnessResult::Missing;
+ }
+
// Look for a member type with the same name as the associated type.
auto candidates = TC.lookupMemberType(DC, Adoptee, assocType->getName(),
NameLookupFlags::ProtocolMembers);
@@ -3342,7 +3353,7 @@
continue;
// Check this type against the protocol requirements.
- if (auto checkResult = checkTypeWitness(TC, DC, assocType,
+ if (auto checkResult = checkTypeWitness(TC, DC, Proto, assocType,
candidate.second)) {
auto reqProto = checkResult.getProtocolOrClass();
nonViable.push_back({candidate.first, reqProto});
@@ -3603,7 +3614,7 @@
if (!canInferFromOtherAssociatedType) {
// Check that the type witness meets the
// requirements on the associated type.
- if (auto failed = checkTypeWitness(TC, DC, result.first,
+ if (auto failed = checkTypeWitness(TC, DC, Proto, result.first,
result.second)) {
witnessResult.NonViable.push_back(
std::make_tuple(result.first,result.second,failed));
@@ -4189,14 +4200,20 @@
}
TC.validateDecl(assocType);
- Type defaultType = assocType->getDefaultDefinitionLoc().getType().subst(
+ Type defaultType = assocType->getDefaultDefinitionLoc().getType();
+
+ // FIXME: Circularity
+ if (!defaultType)
+ return Type();
+
+ defaultType = defaultType.subst(
QueryTypeSubstitutionMap{substitutions},
LookUpConformanceInModule(DC->getParentModule()));
if (!defaultType)
return Type();
- if (auto failed = checkTypeWitness(TC, DC, assocType, defaultType)) {
+ if (auto failed = checkTypeWitness(TC, DC, Proto, assocType, defaultType)) {
// Record the failure, if we haven't seen one already.
if (!failedDefaultedAssocType) {
failedDefaultedAssocType = assocType;
@@ -4231,7 +4248,7 @@
return Type();
// Make sure that the derived type is sane.
- if (checkTypeWitness(TC, DC, assocType, derivedType)) {
+ if (checkTypeWitness(TC, DC, Proto, assocType, derivedType)) {
diagnoseOrDefer(assocType, true,
[derivedType](NormalProtocolConformance *conformance) {
// FIXME: give more detail here?
@@ -6019,6 +6036,9 @@
/// Whether the given class has an explicit '@objc' name.
static bool hasExplicitObjCName(ClassDecl *classDecl) {
+ if (classDecl->getAttrs().hasAttribute<ObjCRuntimeNameAttr>())
+ return true;
+
auto objcAttr = classDecl->getAttrs().getAttribute<ObjCAttr>();
if (!objcAttr) return false;
@@ -6040,26 +6060,17 @@
/// Infer the attribute tostatic-initialize the Objective-C metadata for the
/// given class, if needed.
-static void inferStaticInitializeObjCMetadata(ClassDecl *classDecl,
- bool requiresNSCodingAttr) {
+static void inferStaticInitializeObjCMetadata(ClassDecl *classDecl) {
// If we already have the attribute, there's nothing to do.
if (classDecl->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>())
return;
- // A class with the @NSKeyedArchiverClassNameAttr will end up getting registered
- // with the Objective-C runtime anyway.
- if (classDecl->getAttrs().hasAttribute<NSKeyedArchiverClassNameAttr>())
- return;
-
- // A class with @NSKeyedArchiverEncodeNonGenericSubclassesOnly promises not to be archived,
- // so don't static-initialize its Objective-C metadata.
- if (classDecl->getAttrs().hasAttribute<NSKeyedArchiverEncodeNonGenericSubclassesOnlyAttr>())
- return;
-
// If we know that the Objective-C metadata will be statically registered,
// there's nothing to do.
- if (!requiresNSCodingAttr && !hasGenericAncestry(classDecl))
+ if (!hasGenericAncestry(classDecl) &&
+ classDecl->getDeclContext()->isModuleScopeContext()) {
return;
+ }
// Infer @_staticInitializeObjCMetadata.
ASTContext &ctx = classDecl->getASTContext();
@@ -6118,27 +6129,30 @@
// have unstable archival names.
if (auto classDecl = dc->getAsClassOrClassExtensionContext()) {
if (Context.LangOpts.EnableObjCInterop &&
- isNSCoding(conformance->getProtocol())) {
+ isNSCoding(conformance->getProtocol()) &&
+ !classDecl->isGenericContext()) {
// Note: these 'kind' values are synchronized with
// diag::nscoding_unstable_mangled_name.
- Optional<unsigned> kind;
- bool isFixable = true;
- if (classDecl->getGenericSignature()) {
- kind = 4;
- isFixable = false;
- } else if (!classDecl->getDeclContext()->isModuleScopeContext()) {
+ enum class UnstableNameKind : unsigned {
+ Private = 0,
+ FilePrivate,
+ Nested,
+ Local,
+ };
+ Optional<UnstableNameKind> kind;
+ if (!classDecl->getDeclContext()->isModuleScopeContext()) {
if (classDecl->getDeclContext()->isTypeContext())
- kind = 2;
+ kind = UnstableNameKind::Nested;
else
- kind = 3;
+ kind = UnstableNameKind::Local;
} else {
switch (classDecl->getFormalAccess()) {
case Accessibility::FilePrivate:
- kind = 1;
+ kind = UnstableNameKind::FilePrivate;
break;
case Accessibility::Private:
- kind = 0;
+ kind = UnstableNameKind::Private;
break;
case Accessibility::Internal:
@@ -6149,46 +6163,33 @@
}
if (kind && getLangOpts().EnableNSKeyedArchiverDiagnostics &&
- !hasExplicitObjCName(classDecl) &&
- !classDecl->getAttrs().hasAttribute<NSKeyedArchiverClassNameAttr>() &&
- !classDecl->getAttrs()
- .hasAttribute<NSKeyedArchiverEncodeNonGenericSubclassesOnlyAttr>()) {
- SourceLoc loc;
- if (auto normal = dyn_cast<NormalProtocolConformance>(conformance))
- loc = normal->getLoc();
- if (loc.isInvalid())
- loc = currentDecl->getLoc();
-
+ isa<NormalProtocolConformance>(conformance) &&
+ !hasExplicitObjCName(classDecl)) {
bool emitWarning = Context.LangOpts.isSwiftVersion3();
- diagnose(loc,
+ diagnose(cast<NormalProtocolConformance>(conformance)->getLoc(),
emitWarning ? diag::nscoding_unstable_mangled_name_warn
: diag::nscoding_unstable_mangled_name,
- *kind, classDecl->TypeDecl::getDeclaredInterfaceType());
+ static_cast<unsigned>(kind.getValue()),
+ classDecl->getDeclaredInterfaceType());
auto insertionLoc =
classDecl->getAttributeInsertionLoc(/*forModifier=*/false);
- if (isFixable) {
- // Note: this is intentionally using the Swift 3 mangling,
- // to provide compatibility with archives created in the Swift 3
- // time frame.
- Mangle::ASTMangler mangler;
- diagnose(classDecl, diag::unstable_mangled_name_add_objc)
- .fixItInsert(insertionLoc,
- "@objc(<#Objective-C class name#>)");
- diagnose(classDecl,
- diag::unstable_mangled_name_add_NSKeyedArchiverClassName)
- .fixItInsert(insertionLoc,
- "@NSKeyedArchiverClassName(\"" +
- mangler.mangleObjCRuntimeName(classDecl) +
- "\")");
- } else {
- diagnose(classDecl, diag::add_NSKeyedArchiverEncodeNonGenericSubclassesOnly_attr,
- classDecl->getDeclaredInterfaceType())
- .fixItInsert(insertionLoc, "@NSKeyedArchiverEncodeNonGenericSubclassesOnly");
- }
+ // Note: this is intentionally using the Swift 3 mangling,
+ // to provide compatibility with archives created in the Swift 3
+ // time frame.
+ Mangle::ASTMangler mangler;
+ std::string mangledName = mangler.mangleObjCRuntimeName(classDecl);
+ assert(Lexer::isIdentifier(mangledName) &&
+ "mangled name is not an identifier; can't use @objc");
+ diagnose(classDecl, diag::unstable_mangled_name_add_objc)
+ .fixItInsert(insertionLoc,
+ "@objc(" + mangledName + ")");
+ diagnose(classDecl, diag::unstable_mangled_name_add_objc_new)
+ .fixItInsert(insertionLoc,
+ "@objc(<#prefixed Objective-C class name#>)");
}
// Infer @_staticInitializeObjCMetadata if needed.
- inferStaticInitializeObjCMetadata(classDecl, kind.hasValue());
+ inferStaticInitializeObjCMetadata(classDecl);
}
}
}
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 0cd11a2..dd1dcca 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -1321,7 +1321,7 @@
// caller.
auto expansion = func->getResilienceExpansion();
if (!tc.Context.isSwiftVersion3() &&
- func->getEffectiveAccess() == Accessibility::Public)
+ func->getEffectiveAccess(/*forLinkage=*/false) == Accessibility::Public)
expansion = ResilienceExpansion::Minimal;
for (auto ¶m : *params) {
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 9bb5c7f..1af95ec 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -456,14 +456,11 @@
->castTo<GenericTypeParamType>());
}
- bool hasDependentType = typeDecl->getDeclaredInterfaceType()
- ->hasTypeParameter();
-
// Simple case -- the type is not nested inside of another type.
// However, it might be nested inside another generic context, so
// we do want to write the type in terms of interface types or
// context archetypes, depending on the resolver given to us.
- if (!selfType || !hasDependentType) {
+ if (!selfType) {
if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
// For a generic typealias, return the unbound generic form of the type.
if (aliasDecl->getGenericParams())
@@ -478,7 +475,7 @@
if (auto *nominalDecl = dyn_cast<NominalTypeDecl>(typeDecl))
return nominalDecl->getDeclaredType();
- assert(!hasDependentType);
+ assert(isa<ModuleDecl>(typeDecl));
return typeDecl->getDeclaredInterfaceType();
}
@@ -662,12 +659,21 @@
// generic arguments.
auto resultType = decl->getDeclaredInterfaceType();
+ bool hasTypeParameterOrVariable = false;
+
// Get the substitutions for outer generic parameters from the parent
- // type, but skip the step if the result type does not contain any
- // substitutable type parameters.
- if (resultType->hasTypeParameter())
- if (auto parentType = unboundType->getParent())
- subs = parentType->getContextSubstitutions(decl->getDeclContext());
+ // type.
+ if (auto parentType = unboundType->getParent()) {
+ if (parentType->hasUnboundGenericType()) {
+ assert(!resultType->hasTypeParameter());
+ return resultType;
+ }
+
+ subs = parentType->getContextSubstitutions(decl->getDeclContext());
+
+ hasTypeParameterOrVariable |=
+ (parentType->hasTypeParameter() || parentType->hasTypeVariable());
+ }
SourceLoc noteLoc = decl->getLoc();
if (noteLoc.isInvalid())
@@ -675,7 +681,6 @@
// Realize the types of the generic arguments and add them to the
// substitution map.
- bool hasTypeParameterOrVariable = false;
for (unsigned i = 0, e = genericArgs.size(); i < e; i++) {
auto &genericArg = genericArgs[i];
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 38e55bb..d144ea9 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -1955,11 +1955,12 @@
case DAK_SetterAccessibility:
case DAK_ObjCBridged:
case DAK_SynthesizedProtocol:
- case DAK_Count:
case DAK_Implements:
- case DAK_NSKeyedArchiverClassName:
+ case DAK_ObjCRuntimeName:
llvm_unreachable("cannot serialize attribute");
- return;
+
+ case DAK_Count:
+ llvm_unreachable("not a real attribute");
#define SIMPLE_DECL_ATTR(_, CLASS, ...)\
case DAK_##CLASS: { \
diff --git a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
index 47f8627..abafde2 100644
--- a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
+++ b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
@@ -375,6 +375,12 @@
from: fromEdge)
return (slice, remainder)
}
+
+ @available(*, unavailable, renamed: "minX")
+ public var x: CGFloat { return minX }
+
+ @available(*, unavailable, renamed: "minY")
+ public var y: CGFloat { return minY }
}
extension CGRect : CustomReflectable, CustomPlaygroundQuickLookable {
diff --git a/stdlib/public/SDK/Foundation/Foundation.swift b/stdlib/public/SDK/Foundation/Foundation.swift
index 13edba1..67605af 100644
--- a/stdlib/public/SDK/Foundation/Foundation.swift
+++ b/stdlib/public/SDK/Foundation/Foundation.swift
@@ -95,20 +95,3 @@
return _encodeBitsAsWords(object)
}
}
-
-//===----------------------------------------------------------------------===//
-// Runtime support for NSKeyedArchives
-//===----------------------------------------------------------------------===//
-
-@_silgen_name("swift_registerClassNameForArchiving")
-public func _registerClassNameForArchiving(_ nameForClass: UnsafePointer<CChar>,
- _ classType: AnyClass) {
- // If it's not possible to create a String from the name, it should abort
- // and not fail silently.
- let nameStr = String(utf8String: nameForClass)!
-
- // Register the class name mapping for archiving and unarchiving.
- NSKeyedArchiver.setClassName(nameStr, for: classType)
- NSKeyedUnarchiver.setClass(classType, forClassName: nameStr)
-}
-
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 0db9769..4e8683b 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -47,6 +47,7 @@
CString.swift
CTypes.swift
DebuggerSupport.swift
+ DoubleWidth.swift.gyb
DropWhile.swift.gyb
Dump.swift
EmptyCollection.swift
diff --git a/stdlib/public/core/Codable.swift b/stdlib/public/core/Codable.swift
index 008462d..0403cef 100644
--- a/stdlib/public/core/Codable.swift
+++ b/stdlib/public/core/Codable.swift
@@ -3574,213 +3574,138 @@
// Default implementations for decode(_:forKey:) in terms of decodeIfPresent(_:forKey:)
public extension KeyedDecodingContainerProtocol {
- public func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool {
- if let value = try decodeIfPresent(Bool.self, forKey: key) {
- return value
- } else if contains(key) {
+ @_semantics("optimize.sil.specialize.generic.never")
+ @_semantics("optimize.sil.specialize.generic.partial.never")
+ @inline(never)
+ internal func _errorInDecoding<T: Decodable>(_ type: T.Type, forKey key: Key) -> DecodingError {
+ if contains(key) {
var path = codingPath
path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
+ return DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
var path = codingPath
path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ return DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ }
+ }
+
+ public func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool {
+ if let value = try decodeIfPresent(Bool.self, forKey: key) {
+ return value
+ } else {
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Int.Type, forKey key: Key) throws -> Int {
if let value = try decodeIfPresent(Int.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 {
if let value = try decodeIfPresent(Int8.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 {
if let value = try decodeIfPresent(Int16.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 {
if let value = try decodeIfPresent(Int32.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 {
if let value = try decodeIfPresent(Int64.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt {
if let value = try decodeIfPresent(UInt.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 {
if let value = try decodeIfPresent(UInt8.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 {
if let value = try decodeIfPresent(UInt16.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 {
if let value = try decodeIfPresent(UInt32.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 {
if let value = try decodeIfPresent(UInt64.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Float.Type, forKey key: Key) throws -> Float {
if let value = try decodeIfPresent(Float.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: Double.Type, forKey key: Key) throws -> Double {
if let value = try decodeIfPresent(Double.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode(_ type: String.Type, forKey key: Key) throws -> String {
if let value = try decodeIfPresent(String.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
public func decode<T : Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
if let value = try decodeIfPresent(T.self, forKey: key) {
return value
- } else if contains(key) {
- var path = codingPath
- path.append(key)
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: path, debugDescription: "Found null value when expecting non-optional type \(type) for coding key \"\(key)\""))
} else {
- var path = codingPath
- path.append(key)
- throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: path, debugDescription: "Key not found when expecting non-optional type \(type) for coding key \"\(key)\""))
+ throw _errorInDecoding(type, forKey: key)
}
}
}
@@ -3884,153 +3809,134 @@
// Default implementations for decode(_:) in terms of decodeIfPresent(_:)
public extension UnkeyedDecodingContainer {
+ @_semantics("optimize.sil.specialize.generic.never")
+ @_semantics("optimize.sil.specialize.generic.partial.never")
+ @inline(never)
+ internal func _errorInDecoding<T: Decodable>(_ type: T.Type) -> DecodingError {
+ if !isAtEnd {
+ return DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
+ } else {
+ return DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ }
+ }
+
mutating func decode(_ type: Bool.Type) throws -> Bool {
if let value = try decodeIfPresent(Bool.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Int.Type) throws -> Int {
if let value = try decodeIfPresent(Int.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Int8.Type) throws -> Int8 {
if let value = try decodeIfPresent(Int8.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Int16.Type) throws -> Int16 {
if let value = try decodeIfPresent(Int16.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Int32.Type) throws -> Int32 {
if let value = try decodeIfPresent(Int32.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Int64.Type) throws -> Int64 {
if let value = try decodeIfPresent(Int64.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: UInt.Type) throws -> UInt {
if let value = try decodeIfPresent(UInt.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: UInt8.Type) throws -> UInt8 {
if let value = try decodeIfPresent(UInt8.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: UInt16.Type) throws -> UInt16 {
if let value = try decodeIfPresent(UInt16.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: UInt32.Type) throws -> UInt32 {
if let value = try decodeIfPresent(UInt32.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: UInt64.Type) throws -> UInt64 {
if let value = try decodeIfPresent(UInt64.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Float.Type) throws -> Float {
if let value = try decodeIfPresent(Float.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: Double.Type) throws -> Double {
if let value = try decodeIfPresent(Double.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode(_ type: String.Type) throws -> String {
if let value = try decodeIfPresent(String.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
mutating func decode<T : Decodable>(_ type: T.Type) throws -> T {
if let value = try decodeIfPresent(T.self) {
return value
- } else if !isAtEnd {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Found null value when expecting non-optional type \(type)"))
} else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "No remaining elements when expecting non-optional type \(type)"))
+ throw _errorInDecoding(type)
}
}
}
diff --git a/stdlib/public/core/DoubleWidth.swift.gyb b/stdlib/public/core/DoubleWidth.swift.gyb
new file mode 100644
index 0000000..2fa5f8a
--- /dev/null
+++ b/stdlib/public/core/DoubleWidth.swift.gyb
@@ -0,0 +1,557 @@
+//===--- DoubleWidth.swift.gyb --------------------------------*- swift -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+/// A fixed-width integer that is twice the size of its base type.
+public struct DoubleWidth<Base : FixedWidthInteger> :
+ FixedWidthInteger, _ExpressibleByBuiltinIntegerLiteral {
+
+ public typealias High = Base
+ public typealias Low = Base.Magnitude
+
+ internal var _storage: (high: Base, low: Base.Magnitude)
+
+ public // @testable
+ init(_ _value: (High, Low)) {
+ self._storage = (high: _value.0, low: _value.1)
+ }
+
+ public var high: High {
+ return _storage.high
+ }
+
+ public var low: Low {
+ return _storage.low
+ }
+
+ // Numeric
+ //
+ public init() {
+ self.init((0, 0))
+ }
+
+ // BinaryInteger
+ //
+ public var magnitude: DoubleWidth<Low> {
+ if Base.isSigned && _storage.high < (0 as High) {
+ return self == .min
+ ? DoubleWidth.max.magnitude &+ 1
+ : (0 - self).magnitude
+ }
+ return DoubleWidth<Low>((
+ _storage.high.magnitude, _storage.low.magnitude))
+ }
+
+ internal init(_ _magnitude: Magnitude) {
+ self.init((High(_magnitude._storage.high), _magnitude._storage.low))
+ }
+
+ public static func ==(lhs: DoubleWidth, rhs: DoubleWidth) -> Bool {
+ return (lhs._storage.high == rhs._storage.high) &&
+ (lhs._storage.low == rhs._storage.low)
+ }
+
+ public static func <(lhs: DoubleWidth, rhs: DoubleWidth) -> Bool {
+ if lhs._storage.high < rhs._storage.high {
+ return true
+ }
+ if lhs._storage.high > rhs._storage.high {
+ return false
+ }
+ return lhs._storage.low < rhs._storage.low
+ }
+
+ public init<T : BinaryInteger>(_ source: T) {
+ self.init(exactly: source)!
+ }
+
+ public init?<T : BinaryInteger>(exactly source: T) {
+ // Can't represent a negative 'source' if Base is unsigned
+ guard source >= 0 || DoubleWidth.isSigned else { return nil }
+
+ // Is 'source' is entirely representable in Low?
+ if let low = Low(exactly: source.magnitude) {
+ if source < (0 as T) {
+ self.init((~0, ~low + 1))
+ } else {
+ self.init((0, low))
+ }
+ } else {
+ // At this point we know source's bitWidth > Base.bitWidth, or else
+ // we would've taken the first branch.
+ let lowInT = source & T(~0 as Low)
+ let highInT = source &>> numericCast(High.bitWidth)
+
+ let low = Low(lowInT.magnitude)
+ guard let high = High(exactly: highInT) else { return nil }
+ self.init((high, low))
+ }
+ }
+
+ public init<T : FloatingPoint>(_ source: T) {
+ fatalError()
+ }
+
+ public init?<T : FloatingPoint>(exactly source: T) {
+ fatalError()
+ }
+
+ public init<T : BinaryFloatingPoint>(_ source: T)
+ where T.RawSignificand : FixedWidthInteger
+ {
+ _precondition(source.isFinite, "Can't create a DoubleWidth from a non-finite value")
+ self.init(exactly: source.rounded(.towardZero))!
+ }
+
+ public init?<T : BinaryFloatingPoint>(exactly source: T)
+ where T.RawSignificand : FixedWidthInteger
+ {
+ // Need a finite value
+ guard source.isFinite else { return nil }
+
+ // Don't need to go further with zero.
+ if source.isZero {
+ self.init(0)
+ return
+ }
+
+ // Need a value with a non-negative exponent
+ guard source.exponent >= 0 else { return nil }
+
+ typealias Raw = T.RawSignificand
+ let bitPattern = source.significandBitPattern |
+ ((1 as Raw) &<< Raw(T.significandBitCount))
+ let offset = T.significandBitCount - Int(source.exponent)
+
+ // FIXME: spurious compile error when 'where' clause above is removed:
+ // error: non-nominal type 'T.RawSignificand' does not support explicit initialization
+ let fractionPart: Raw = bitPattern &<< Raw(Raw.bitWidth - offset)
+ guard fractionPart == (0 as Raw) else {
+ return nil
+ }
+
+ let integerPart: Raw = bitPattern &>> Raw(offset)
+
+ // Should have caught any actual zero values above
+ _sanityCheck(integerPart > (0 as Raw))
+
+ if source.sign == .minus {
+ if !DoubleWidth.isSigned || integerPart &- 1 > DoubleWidth.max {
+ return nil
+ }
+ // Have to juggle, or else the intermediate step of creating a value
+ // with Self.min's magnitude will overflow. It's okay to use wrapping
+ // subtraction because integerPart > 0.
+ self.init(integerPart &- 1)
+ self = 0 &- self &- 1
+ } else {
+ self.init(exactly: integerPart)
+ }
+ }
+
+ public func _word(at n: Int) -> UInt {
+ if Base.bitWidth < UInt.bitWidth {
+ if UInt.bitWidth % Base.bitWidth != 0 {
+ fatalError("word(at:) is not supported on this type")
+ }
+ if n > 0 {
+ // Since `Base` is narrower than word, any non-zero word will give us
+ // the correct value here (0 or ~0).
+ return _storage.high._word(at: n)
+ }
+ return _storage.low._word(at: 0) |
+ (_storage.high._word(at: 0) << numericCast(Base.bitWidth))
+ } else {
+ // multiples of word-size only
+ if Base.bitWidth % UInt.bitWidth != 0 {
+ fatalError("word(at:) is not supported on this type")
+ }
+
+ // TODO: move to Int128 just like init(_builtinIntegerLiteral:) ?
+ return (n < _storage.low.countRepresentedWords) ?
+ _storage.low._word(at: n) :
+ _storage.high._word(at: n - _storage.low.countRepresentedWords)
+ }
+ }
+
+ public static var isSigned: Bool {
+ return Base.isSigned
+ }
+
+ // fixed width
+ //
+ public static var max: DoubleWidth {
+ return self.init((High.max, Low.max))
+ }
+
+ public static var min: DoubleWidth {
+ return self.init((High.min, Low.min))
+ }
+
+ public static var bitWidth: Int {
+ return 2 * Base.bitWidth
+ }
+
+% for (operator, name) in [('+', 'adding'), ('-', 'subtracting')]:
+% highAffectedByLowOverflow = 'Base.max' if operator == '+' else 'Base.min'
+ public func ${name}ReportingOverflow(_ rhs: DoubleWidth)
+ -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+ let (low, lowOverflow) =
+ _storage.low.${name}ReportingOverflow(rhs._storage.low)
+ let (high, highOverflow) =
+ _storage.high.${name}ReportingOverflow(rhs._storage.high)
+ let isLowOverflow = lowOverflow == .overflow
+ let result = (high &${operator} (isLowOverflow ? 1 : 0), low)
+ let overflow = ArithmeticOverflow(
+ highOverflow == .overflow ||
+ high == ${highAffectedByLowOverflow} && isLowOverflow
+ )
+ return (partialValue: DoubleWidth(result),
+ overflow: overflow)
+ }
+% end
+
+ public func multipliedReportingOverflow(
+ by rhs: DoubleWidth
+ ) -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+ let (carry, product) = multipliedFullWidth(by: rhs)
+ let result = DoubleWidth(extendingOrTruncating: product)
+
+ let isNegative = (self < (0 as DoubleWidth)) != (rhs < (0 as DoubleWidth))
+ let didCarry = isNegative
+ ? carry != ~(0 as DoubleWidth)
+ : carry != (0 as DoubleWidth)
+ let hadPositiveOverflow = !isNegative &&
+ DoubleWidth.isSigned && product.leadingZeroBitCount == 0
+
+ return (result, ArithmeticOverflow(didCarry || hadPositiveOverflow))
+ }
+
+ public func quotientAndRemainder(dividingBy other: DoubleWidth)
+ -> (quotient: DoubleWidth, remainder: DoubleWidth) {
+ let isNegative = (self < (0 as DoubleWidth)) != (other < (0 as DoubleWidth))
+
+ let rhs = other.magnitude
+ var q = self.magnitude
+
+ // Bail if |other| > |self|
+ if rhs.leadingZeroBitCount < q.leadingZeroBitCount {
+ return (0, self)
+ }
+
+ // Calculate the number of bits before q and rhs line up,
+ // we can skip that many bits of iteration.
+ let initialOffset = q.leadingZeroBitCount +
+ (DoubleWidth.bitWidth - rhs.leadingZeroBitCount) - 1
+
+ // TODO(performance): Use &>> instead here?
+ // Start with remainder capturing the high bits of q.
+ var r = q >> Magnitude(DoubleWidth.bitWidth - initialOffset)
+ q <<= Magnitude(initialOffset)
+
+ let highBit = ~(~0 >> 1) as Magnitude
+ for _ in initialOffset..<DoubleWidth.bitWidth {
+ r <<= 1
+ if q & highBit != (0 as Magnitude) {
+ r += 1 as Magnitude
+ }
+ q <<= 1
+
+ if r >= rhs {
+ q |= 1
+ r -= rhs
+ }
+ }
+
+ // Sign of remainder matches dividend
+ let remainder = self < (0 as DoubleWidth)
+ ? 0 - DoubleWidth(r)
+ : DoubleWidth(r)
+
+ if isNegative {
+ return (0 - DoubleWidth(q), remainder)
+ } else {
+ return (DoubleWidth(q), remainder)
+ }
+ }
+
+ public func dividedReportingOverflow(by other: DoubleWidth)
+ -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+ if other == (0 as DoubleWidth) ||
+ (DoubleWidth.isSigned && other == (-1 as Int) && self == .min)
+ {
+ return (self, .overflow)
+ }
+
+ return (quotientAndRemainder(dividingBy: other).quotient, .none)
+ }
+
+ public func remainderReportingOverflow(dividingBy other: DoubleWidth)
+ -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+ if other == 0 ||
+ (DoubleWidth.isSigned && other == -1 && self == .min)
+ {
+ return (self, .overflow)
+ }
+
+ return (quotientAndRemainder(dividingBy: other).remainder, .none)
+ }
+
+ public func multipliedFullWidth(by other: DoubleWidth)
+ -> (high: DoubleWidth, low: DoubleWidth.Magnitude) {
+ let isNegative = DoubleWidth.isSigned &&
+ (self < (0 as DoubleWidth)) != (other < (0 as DoubleWidth))
+
+ func mul(_ x: Low, _ y: Low) -> (partial: Low, carry: Low) {
+ let (high, low) = x.multipliedFullWidth(by: y)
+ return (low, high)
+ }
+
+ func sum(_ x: Low, _ y: Low, _ z: Low) -> (partial: Low, carry: Low) {
+ let (sum1, overflow1) = x.addingReportingOverflow(y)
+ let (sum2, overflow2) = sum1.addingReportingOverflow(z)
+ let carry: Low = (overflow1 == .overflow ? 1 : 0) +
+ (overflow2 == .overflow ? 1 : 0)
+ return (sum2, carry)
+ }
+
+ let lhs = self.magnitude
+ let rhs = other.magnitude
+
+ let a = mul(rhs._storage.low, lhs._storage.low)
+ let b = mul(rhs._storage.low, lhs._storage.high)
+ let c = mul(rhs._storage.high, lhs._storage.low)
+ let d = mul(rhs._storage.high, lhs._storage.high)
+
+ let mid1 = sum(a.carry, b.partial, c.partial)
+ let mid2 = sum(b.carry, c.carry, d.partial)
+
+ let low = DoubleWidth<Low>((mid1.partial, a.partial))
+ let high = DoubleWidth(
+ (High(mid2.carry + d.carry), mid1.carry + mid2.partial))
+
+ if isNegative {
+ let (lowComplement, overflow) = (~low).addingReportingOverflow(1)
+ return (~high + (overflow == .overflow ? 1 : 0), lowComplement)
+ } else {
+ return (high, low)
+ }
+ }
+
+ public func dividingFullWidth(
+ _ dividend: (high: DoubleWidth, low: DoubleWidth.Magnitude)
+ ) -> (quotient: DoubleWidth, remainder: DoubleWidth) {
+ let lhs = DoubleWidth<DoubleWidth<Base>>(dividend)
+ let rhs = DoubleWidth<DoubleWidth<Base>>(self)
+ let (quotient, remainder) = lhs.quotientAndRemainder(dividingBy: rhs)
+
+ // FIXME(integers): check for overflow of quotient and remainder
+ return (DoubleWidth(quotient.low), DoubleWidth(remainder.low))
+ }
+
+% for operator in ['&', '|', '^']:
+ public static func ${operator}=(
+ lhs: inout DoubleWidth, rhs: DoubleWidth
+ ) {
+ lhs._storage.low ${operator}= rhs._storage.low
+ lhs._storage.high ${operator}= rhs._storage.high
+ }
+% end
+
+ public static func <<=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
+ if rhs < (0 as DoubleWidth) {
+ lhs >>= 0 - rhs
+ return
+ }
+
+ if rhs._storage.high != (0 as High) ||
+ rhs._storage.low >= DoubleWidth.bitWidth
+ {
+ lhs = 0
+ return
+ }
+
+ // Shift is exactly the width of `Base`, so low -> high.
+ if rhs._storage.low == Base.bitWidth {
+ lhs = DoubleWidth((High(extendingOrTruncating: lhs._storage.low), 0))
+ return
+ }
+
+ lhs &<<= rhs
+ }
+
+ public static func >>=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
+ if rhs < (0 as DoubleWidth) {
+ lhs <<= 0 - rhs
+ return
+ }
+
+ // Shift is larger than this type's bit width.
+ if rhs._storage.high != (0 as High) ||
+ rhs._storage.low >= DoubleWidth.bitWidth
+ {
+ lhs = lhs < (0 as DoubleWidth) ? ~0 : 0
+ return
+ }
+
+ // Shift is exactly the width of `Base`, so high -> low.
+ if rhs._storage.low == Base.bitWidth {
+ lhs = DoubleWidth((
+ lhs < (0 as DoubleWidth) ? ~0 : 0,
+ Low(extendingOrTruncating: lhs._storage.high)
+ ))
+ return
+ }
+
+ lhs &>>= rhs
+ }
+
+ public static func &<<=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
+ let rhs = rhs & DoubleWidth(DoubleWidth.bitWidth - 1)
+
+ lhs._storage.high <<= High(rhs._storage.low)
+ if Base.bitWidth > rhs._storage.low {
+ lhs._storage.high |= High(extendingOrTruncating: lhs._storage.low >>
+ (numericCast(Base.bitWidth) - rhs._storage.low))
+ } else {
+ lhs._storage.high |= High(extendingOrTruncating: lhs._storage.low <<
+ (rhs._storage.low - numericCast(Base.bitWidth)))
+ }
+ lhs._storage.low <<= rhs._storage.low
+ }
+
+ public static func &>>=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
+ let rhs = rhs & DoubleWidth(DoubleWidth.bitWidth - 1)
+
+ lhs._storage.low >>= rhs._storage.low
+ if Base.bitWidth > rhs._storage.low {
+ lhs._storage.low |= Low(extendingOrTruncating: lhs._storage.high <<
+ numericCast(numericCast(Base.bitWidth) - rhs._storage.low))
+ } else {
+ lhs._storage.low |= Low(extendingOrTruncating: lhs._storage.high >>
+ numericCast(rhs._storage.low - numericCast(Base.bitWidth)))
+ }
+ lhs._storage.high >>= High(extendingOrTruncating: rhs._storage.low)
+ }
+
+%{
+binaryOperators = [
+ ('+', 'adding', '_', '+'),
+ ('-', 'subtracting', '_', '-'),
+ ('*', 'multiplied', 'by', '*'),
+ ('/', 'divided', 'by', '/'),
+ ('%', 'remainder', 'dividingBy', '/'),
+]
+}%
+% for (operator, name, firstArg, kind) in binaryOperators:
+
+ // FIXME(integers): remove this once the operators are back to Numeric
+ public static func ${operator} (
+ lhs: DoubleWidth, rhs: DoubleWidth
+ ) -> DoubleWidth {
+ var lhs = lhs
+ lhs ${operator}= rhs
+ return lhs
+ }
+
+% argumentLabel = (firstArg + ':') if firstArg != '_' else ''
+ public static func ${operator}=(
+ lhs: inout DoubleWidth, rhs: DoubleWidth
+ ) {
+ let (result, overflow) = lhs.${name}ReportingOverflow(${argumentLabel}rhs)
+ _precondition(overflow == .none, "Overflow in ${operator}=")
+ lhs = result
+ }
+% end
+
+ public init(_truncatingBits bits: UInt) {
+ _storage.low = Low(_truncatingBits: bits)
+ _storage.high = High(_truncatingBits: bits >> UInt(Base.bitWidth))
+ }
+
+ // other
+ //
+ public init(_builtinIntegerLiteral x: _MaxBuiltinIntegerType) {
+ // FIXME: This won't work if `x` is out of range for `Int64`
+ self.init(Int64(_builtinIntegerLiteral: x))
+ }
+
+ public var description: String {
+ return "(\(_storage.high), \(_storage.low))"
+ }
+
+ public var leadingZeroBitCount: Int {
+ return high == (0 as High)
+ ? Base.bitWidth + low.leadingZeroBitCount
+ : high.leadingZeroBitCount
+ }
+
+ public var trailingZeroBitCount: Int {
+ return low == (0 as Low)
+ ? Base.bitWidth + high.trailingZeroBitCount
+ : low.trailingZeroBitCount
+ }
+
+ public var nonzeroBitCount: Int {
+ return high.nonzeroBitCount + low.nonzeroBitCount
+ }
+
+ public var hashValue: Int {
+ return _mixInt(high.hashValue) ^ low.hashValue
+ }
+
+ @_transparent
+ public var byteSwapped: DoubleWidth {
+ return DoubleWidth((High(extendingOrTruncating: low.byteSwapped),
+ Low(extendingOrTruncating: high.byteSwapped)))
+ }
+}
+
+// FIXME(ABI) (Conditional Conformance):
+// DoubleWidth should conform to SignedInteger where Base : SignedInteger
+extension DoubleWidth where Base : SignedInteger {
+ /// Returns the additive inverse of the specified value.
+ ///
+ /// The negation operator (prefix `-`) returns the additive inverse of its
+ /// argument.
+ ///
+ /// let x = 21 as DoubleWidth<Int>
+ /// let y = -x
+ /// // y == -21
+ ///
+ /// The resulting value must be representable in the same type as the
+ /// argument. In particular, negating a signed, fixed-width integer type's
+ /// minimum results in a value that cannot be represented.
+ ///
+ /// let z = -DoubleWidth<Int>.min
+ /// // Overflow error
+ ///
+ /// - Returns: The additive inverse of this value.
+ ///
+ /// - SeeAlso: `negate()`
+ public static prefix func - (_ operand: DoubleWidth) -> DoubleWidth {
+ return 0 - operand
+ }
+
+ /// Replaces this value with its additive inverse.
+ ///
+ /// The following example uses the `negate()` method to negate the value of
+ /// an integer `x`:
+ ///
+ /// var x = 21 as DoubleWidth<Int>
+ /// x.negate()
+ /// // x == -21
+ ///
+ /// - SeeAlso: The unary minus operator (`-`).
+ public mutating func negate() {
+ self = 0 - self
+ }
+}
diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json
index e22e387..c4c41db 100644
--- a/stdlib/public/core/GroupInfo.json
+++ b/stdlib/public/core/GroupInfo.json
@@ -124,6 +124,7 @@
"BuiltinMath.swift",
{
"Integers": [
+ "DoubleWidth.swift",
"Integers.swift",
"IntegerParsing.swift"],
"Floating": [
diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb
index 092973b..a084337 100644
--- a/stdlib/public/core/HashedCollections.swift.gyb
+++ b/stdlib/public/core/HashedCollections.swift.gyb
@@ -1730,13 +1730,13 @@
/// print(wordToValue)
/// // Prints "["three": 3, "four": 4, "five": 5, "one": 1, "two": 2]"
///
- /// - Parameter keysAndValues: A sequence of `(Key, Value)` tuples to use for
+ /// - Parameter keysAndValues: A sequence of key-value pairs to use for
/// the new dictionary. Every key in `keysAndValues` must be unique.
/// - Returns: A new dictionary initialized with the elements of
/// `keysAndValues`.
public init<S: Sequence>(
uniqueKeysWithValues keysAndValues: S
- ) where S.Iterator.Element == (Key, Value) {
+ ) where S.Element == (Key, Value) {
if let d = keysAndValues as? Dictionary<Key, Value> {
self = d
} else {
@@ -1773,7 +1773,7 @@
/// // ["b": 4, "a": 3]
///
/// - Parameters:
- /// - keysAndValues: A sequence of `(Key, Value)` tuples to use for the new
+ /// - keysAndValues: A sequence of key-value pairs to use for the new
/// dictionary.
/// - combine: A closure that is called with the values for any duplicate
/// keys that are encountered. The closure returns the desired value for
@@ -1781,7 +1781,7 @@
public init<S: Sequence>(
_ keysAndValues: S,
uniquingKeysWith combine: (Value, Value) throws -> Value
- ) rethrows where S.Iterator.Element == (Key, Value) {
+ ) rethrows where S.Element == (Key, Value) {
self = Dictionary(minimumCapacity: keysAndValues.underestimatedCount)
try _variantBuffer.merge(keysAndValues, uniquingKeysWith: combine)
}
@@ -1810,8 +1810,8 @@
/// `values`.
public init<S: Sequence>(
grouping values: S,
- by keyForValue: (S.Iterator.Element) throws -> Key
- ) rethrows where Value == [S.Iterator.Element] {
+ by keyForValue: (S.Element) throws -> Key
+ ) rethrows where Value == [S.Element] {
self = [:]
for value in values {
self[try keyForValue(value), default: []].append(value)
@@ -2093,27 +2093,60 @@
/// var dictionary = ["a": 1, "b": 2]
///
/// // Keeping existing value for key "a":
- /// dictionary.merge(["a": 3, "c": 4])
- /// { (current, _) in current }
+ /// dictionary.merge(zip(["a", "c"], [3, 4])) { (current, _) in current }
/// // ["b": 2, "a": 1, "c": 4]
///
/// // Taking the new value for key "a":
- /// dictionary.merge(["a": 5, "d": 6])
- /// { (_, new) in new }
+ /// dictionary.merge(zip(["a", "d"], [5, 6])) { (_, new) in new }
/// // ["b": 2, "a": 5, "c": 4, "d": 6]
///
/// - Parameters:
- /// - other: A sequence of `(Key, Value)` tuples.
+ /// - other: A sequence of key-value pairs.
/// - combine: A closure that takes the current and new values for any
/// duplicate keys. The closure returns the desired value for the final
/// dictionary.
public mutating func merge<S: Sequence>(
_ other: S,
uniquingKeysWith combine: (Value, Value) throws -> Value
- ) rethrows where S.Iterator.Element == (Key, Value) {
+ ) rethrows where S.Element == (Key, Value) {
try _variantBuffer.merge(other, uniquingKeysWith: combine)
}
+ /// Merges the given dictionary into this dictionary, using a combining
+ /// closure to determine the value for any duplicate keys.
+ ///
+ /// Use the `combine` closure to select which value to use in the updated
+ /// dictionary, or to combine existing and new values. As the key-values
+ /// pairs in `other` are merged with this dictionary, the `combine` closure
+ /// is called with the current and new values for any duplicate keys that
+ /// are encountered.
+ ///
+ /// This example shows how to choose the current or new values for any
+ /// duplicate keys:
+ ///
+ /// var dictionary = ["a": 1, "b": 2]
+ ///
+ /// // Keeping existing value for key "a":
+ /// dictionary.merge(["a": 3, "c": 4]) { (current, _) in current }
+ /// // ["b": 2, "a": 1, "c": 4]
+ ///
+ /// // Taking the new value for key "a":
+ /// dictionary.merge(["a": 5, "d": 6]) { (_, new) in new }
+ /// // ["b": 2, "a": 5, "c": 4, "d": 6]
+ ///
+ /// - Parameters:
+ /// - other: A dictionary to merge.
+ /// - combine: A closure that takes the current and new values for any
+ /// duplicate keys. The closure returns the desired value for the final
+ /// dictionary.
+ public mutating func merge(
+ _ other: [Key: Value],
+ uniquingKeysWith combine: (Value, Value) throws -> Value) rethrows
+ {
+ try _variantBuffer.merge(
+ other.lazy.map { ($0, $1) }, uniquingKeysWith: combine)
+ }
+
/// Returns a new dictionary created by merging the key-value pairs in the
/// given sequence into the dictionary, using a combining closure to
/// determine the value for any duplicate keys.
@@ -2128,16 +2161,15 @@
/// duplicate keys:
///
/// let dictionary = ["a": 1, "b": 2]
- /// let otherDictionary = ["a": 3, "b": 4]
- /// let keepingCurrent = dictionary.merging(otherDictionary)
- /// { (current, _) in current }
+ /// let newKeyValues = zip(["a", "b"], [3, 4])
+ ///
+ /// let keepingCurrent = dictionary.merging(newKeyValues) { (current, _) in current }
/// // ["b": 2, "a": 1]
- /// let replacingCurrent = dictionary.merging(otherDictionary)
- /// { (_, new) in new }
+ /// let replacingCurrent = dictionary.merging(newKeyValues) { (_, new) in new }
/// // ["b": 4, "a": 3]
///
/// - Parameters:
- /// - other: A sequence of `(Key, Value)` tuples.
+ /// - other: A sequence of key-value pairs.
/// - combine: A closure that takes the current and new values for any
/// duplicate keys. The closure returns the desired value for the final
/// dictionary.
@@ -2146,7 +2178,46 @@
public func merging<S: Sequence>(
_ other: S,
uniquingKeysWith combine: (Value, Value) throws -> Value
- ) rethrows -> [Key: Value] where S.Iterator.Element == (Key, Value) {
+ ) rethrows -> [Key: Value] where S.Element == (Key, Value) {
+ var result = self
+ try result._variantBuffer.merge(other, uniquingKeysWith: combine)
+ return result
+ }
+
+ /// Returns a new dictionary created by merging the given dictionary into
+ /// this dictionary, using a combining closure to determine the value for
+ /// any duplicate keys.
+ ///
+ /// Use the `combine` closure to select which value to use in the returned
+ /// dictionary, or to combine existing and new values. As the key-value
+ /// pairs in `other` are merged with this dictionary, the `combine` closure
+ /// is called with the current and new values for any duplicate keys that
+ /// are encountered.
+ ///
+ /// This example shows how to choose the current or new values for any
+ /// duplicate keys:
+ ///
+ /// let dictionary = ["a": 1, "b": 2]
+ /// let otherDictionary = ["a": 3, "b": 4]
+ ///
+ /// let keepingCurrent = dictionary.merging(otherDictionary)
+ /// { (current, _) in current }
+ /// // ["b": 2, "a": 1]
+ /// let replacingCurrent = dictionary.merging(otherDictionary)
+ /// { (_, new) in new }
+ /// // ["b": 4, "a": 3]
+ ///
+ /// - Parameters:
+ /// - other: A dictionary to merge.
+ /// - combine: A closure that takes the current and new values for any
+ /// duplicate keys. The closure returns the desired value for the final
+ /// dictionary.
+ /// - Returns: A new dictionary with the combined keys and values of this
+ /// dictionary and `other`.
+ public func merging(
+ _ other: [Key: Value],
+ uniquingKeysWith combine: (Value, Value) throws -> Value
+ ) rethrows -> [Key: Value] {
var result = self
try result.merge(other, uniquingKeysWith: combine)
return result
@@ -4938,7 +5009,7 @@
internal mutating func nativeMerge<S: Sequence>(
_ keysAndValues: S,
uniquingKeysWith combine: (Value, Value) throws -> Value
- ) rethrows where S.Iterator.Element == (Key, Value) {
+ ) rethrows where S.Element == (Key, Value) {
for (key, value) in keysAndValues {
var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))
@@ -4969,7 +5040,7 @@
internal mutating func merge<S: Sequence>(
_ keysAndValues: S,
uniquingKeysWith combine: (Value, Value) throws -> Value
- ) rethrows where S.Iterator.Element == (Key, Value) {
+ ) rethrows where S.Element == (Key, Value) {
if _fastPath(guaranteedNative) {
try nativeMerge(keysAndValues, uniquingKeysWith: combine)
return
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index eff76b3..ebb1db5 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -3157,549 +3157,6 @@
return U(x)
}
-
-//===----------------------------------------------------------------------===//
-//===--- DoubleWidth ------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-
-/// A fixed-width integer that is twice the size of its base type.
-public struct DoubleWidth<Base : FixedWidthInteger> :
- FixedWidthInteger, _ExpressibleByBuiltinIntegerLiteral {
-
- public typealias High = Base
- public typealias Low = Base.Magnitude
-
- internal var _storage: (high: Base, low: Base.Magnitude)
-
- public // @testable
- init(_ _value: (High, Low)) {
- self._storage = (high: _value.0, low: _value.1)
- }
-
- public var high: High {
- return _storage.high
- }
-
- public var low: Low {
- return _storage.low
- }
-
- // Numeric
- //
- public init() {
- self.init((0, 0))
- }
-
- // BinaryInteger
- //
- public var magnitude: DoubleWidth<Low> {
- if Base.isSigned && _storage.high < (0 as High) {
- return self == .min
- ? DoubleWidth.max.magnitude &+ 1
- : (0 - self).magnitude
- }
- return DoubleWidth<Low>((
- _storage.high.magnitude, _storage.low.magnitude))
- }
-
- internal init(_ _magnitude: Magnitude) {
- self.init((High(_magnitude._storage.high), _magnitude._storage.low))
- }
-
- public static func ==(lhs: DoubleWidth, rhs: DoubleWidth) -> Bool {
- return (lhs._storage.high == rhs._storage.high) &&
- (lhs._storage.low == rhs._storage.low)
- }
-
- public static func <(lhs: DoubleWidth, rhs: DoubleWidth) -> Bool {
- if lhs._storage.high < rhs._storage.high {
- return true
- }
- if lhs._storage.high > rhs._storage.high {
- return false
- }
- return lhs._storage.low < rhs._storage.low
- }
-
- public init<T : BinaryInteger>(_ source: T) {
- self.init(exactly: source)!
- }
-
- public init?<T : BinaryInteger>(exactly source: T) {
- // Can't represent a negative 'source' if Base is unsigned
- guard source >= 0 || DoubleWidth.isSigned else { return nil }
-
- // Is 'source' is entirely representable in Low?
- if let low = Low(exactly: source.magnitude) {
- if source < (0 as T) {
- self.init((~0, ~low + 1))
- } else {
- self.init((0, low))
- }
- } else {
- // At this point we know source's bitWidth > Base.bitWidth, or else
- // we would've taken the first branch.
- let lowInT = source & T(~0 as Low)
- let highInT = source &>> numericCast(High.bitWidth)
-
- let low = Low(lowInT.magnitude)
- guard let high = High(exactly: highInT) else { return nil }
- self.init((high, low))
- }
- }
-
- public init<T : FloatingPoint>(_ source: T) {
- fatalError()
- }
-
- public init?<T : FloatingPoint>(exactly source: T) {
- fatalError()
- }
-
- public init<T : BinaryFloatingPoint>(_ source: T)
- where T.RawSignificand : FixedWidthInteger
- {
- _precondition(source.isFinite, "Can't create a DoubleWidth from a non-finite value")
- self.init(exactly: source.rounded(.towardZero))!
- }
-
- public init?<T : BinaryFloatingPoint>(exactly source: T)
- where T.RawSignificand : FixedWidthInteger
- {
- // Need a finite value
- guard source.isFinite else { return nil }
-
- // Don't need to go further with zero.
- if source.isZero {
- self.init(0)
- return
- }
-
- // Need a value with a non-negative exponent
- guard source.exponent >= 0 else { return nil }
-
- typealias Raw = T.RawSignificand
- let bitPattern = source.significandBitPattern |
- ((1 as Raw) &<< Raw(T.significandBitCount))
- let offset = T.significandBitCount - Int(source.exponent)
-
- // FIXME: spurious compile error when 'where' clause above is removed:
- // error: non-nominal type 'T.RawSignificand' does not support explicit initialization
- let fractionPart: Raw = bitPattern &<< Raw(Raw.bitWidth - offset)
- guard fractionPart == (0 as Raw) else {
- return nil
- }
-
- let integerPart: Raw = bitPattern &>> Raw(offset)
-
- // Should have caught any actual zero values above
- _sanityCheck(integerPart > (0 as Raw))
-
- if source.sign == .minus {
- if !DoubleWidth.isSigned || integerPart &- 1 > DoubleWidth.max {
- return nil
- }
- // Have to juggle, or else the intermediate step of creating a value
- // with Self.min's magnitude will overflow. It's okay to use wrapping
- // subtraction because integerPart > 0.
- self.init(integerPart &- 1)
- self = 0 &- self &- 1
- } else {
- self.init(exactly: integerPart)
- }
- }
-
- public func _word(at n: Int) -> UInt {
- if Base.bitWidth < ${word_bits} {
- if ${word_bits} % Base.bitWidth != 0 {
- fatalError("word(at:) is not supported on this type")
- }
- if n > 0 {
- // Since `Base` is narrower than word, any non-zero word will give us
- // the correct value here (0 or ~0).
- return _storage.high._word(at: n)
- }
- return _storage.low._word(at: 0) |
- (_storage.high._word(at: 0) << numericCast(Base.bitWidth))
- } else {
- // multiples of ${word_bits} only
- if Base.bitWidth % ${word_bits} != 0 {
- fatalError("word(at:) is not supported on this type")
- }
-
- // TODO: move to Int128 just like init(_builtinIntegerLiteral:) ?
- return (n < _storage.low.countRepresentedWords) ?
- _storage.low._word(at: n) :
- _storage.high._word(at: n - _storage.low.countRepresentedWords)
- }
- }
-
- public static var isSigned: Bool {
- return Base.isSigned
- }
-
- // fixed width
- //
- public static var max: DoubleWidth {
- return self.init((High.max, Low.max))
- }
-
- public static var min: DoubleWidth {
- return self.init((High.min, Low.min))
- }
-
- public static var bitWidth: Int {
- return 2 * Base.bitWidth
- }
-
-% # This covers + and -
-% for x in binaryArithmetic['Numeric'][:2]:
-% highAffectedByLowOverflow = 'Base.max' if x.operator == '+' else 'Base.min'
- public func ${x.name}ReportingOverflow(_ rhs: DoubleWidth)
- -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
- let (low, lowOverflow) =
- _storage.low.${x.name}ReportingOverflow(rhs._storage.low)
- let (high, highOverflow) =
- _storage.high.${x.name}ReportingOverflow(rhs._storage.high)
- let isLowOverflow = lowOverflow == .overflow
- let result = (high &${x.operator} (isLowOverflow ? 1 : 0), low)
- let overflow = ArithmeticOverflow(
- highOverflow == .overflow ||
- high == ${highAffectedByLowOverflow} && isLowOverflow
- )
- return (partialValue: DoubleWidth(result),
- overflow: overflow)
- }
-% end
-
- public func multipliedReportingOverflow(
- by rhs: DoubleWidth
- ) -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
- let (carry, product) = multipliedFullWidth(by: rhs)
- let result = DoubleWidth(extendingOrTruncating: product)
-
- let isNegative = (self < (0 as DoubleWidth)) != (rhs < (0 as DoubleWidth))
- let didCarry = isNegative
- ? carry != ~(0 as DoubleWidth)
- : carry != (0 as DoubleWidth)
- let hadPositiveOverflow = !isNegative &&
- DoubleWidth.isSigned && product.leadingZeroBitCount == 0
-
- return (result, ArithmeticOverflow(didCarry || hadPositiveOverflow))
- }
-
- public func quotientAndRemainder(dividingBy other: DoubleWidth)
- -> (quotient: DoubleWidth, remainder: DoubleWidth) {
- let isNegative = (self < (0 as DoubleWidth)) != (other < (0 as DoubleWidth))
-
- let rhs = other.magnitude
- var q = self.magnitude
-
- // Bail if |other| > |self|
- if rhs.leadingZeroBitCount < q.leadingZeroBitCount {
- return (0, self)
- }
-
- // Calculate the number of bits before q and rhs line up,
- // we can skip that many bits of iteration.
- let initialOffset = q.leadingZeroBitCount +
- (DoubleWidth.bitWidth - rhs.leadingZeroBitCount) - 1
-
- // TODO(performance): Use &>> instead here?
- // Start with remainder capturing the high bits of q.
- var r = q >> Magnitude(DoubleWidth.bitWidth - initialOffset)
- q <<= Magnitude(initialOffset)
-
- let highBit = ~(~0 >> 1) as Magnitude
- for _ in initialOffset..<DoubleWidth.bitWidth {
- r <<= 1
- if q & highBit != (0 as Magnitude) {
- r += 1 as Magnitude
- }
- q <<= 1
-
- if r >= rhs {
- q |= 1
- r -= rhs
- }
- }
-
- // Sign of remainder matches dividend
- let remainder = self < (0 as DoubleWidth)
- ? 0 - DoubleWidth(r)
- : DoubleWidth(r)
-
- if isNegative {
- return (0 - DoubleWidth(q), remainder)
- } else {
- return (DoubleWidth(q), remainder)
- }
- }
-
- public func dividedReportingOverflow(by other: DoubleWidth)
- -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
- if other == (0 as DoubleWidth) ||
- (DoubleWidth.isSigned && other == (-1 as Int) && self == .min)
- {
- return (self, .overflow)
- }
-
- return (quotientAndRemainder(dividingBy: other).quotient, .none)
- }
-
- public func remainderReportingOverflow(dividingBy other: DoubleWidth)
- -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
- if other == 0 ||
- (DoubleWidth.isSigned && other == -1 && self == .min)
- {
- return (self, .overflow)
- }
-
- return (quotientAndRemainder(dividingBy: other).remainder, .none)
- }
-
- public func multipliedFullWidth(by other: DoubleWidth)
- -> (high: DoubleWidth, low: DoubleWidth.Magnitude) {
- let isNegative = DoubleWidth.isSigned &&
- (self < (0 as DoubleWidth)) != (other < (0 as DoubleWidth))
-
- func mul(_ x: Low, _ y: Low) -> (partial: Low, carry: Low) {
- let (high, low) = x.multipliedFullWidth(by: y)
- return (low, high)
- }
-
- func sum(_ x: Low, _ y: Low, _ z: Low) -> (partial: Low, carry: Low) {
- let (sum1, overflow1) = x.addingReportingOverflow(y)
- let (sum2, overflow2) = sum1.addingReportingOverflow(z)
- let carry: Low = (overflow1 == .overflow ? 1 : 0) +
- (overflow2 == .overflow ? 1 : 0)
- return (sum2, carry)
- }
-
- let lhs = self.magnitude
- let rhs = other.magnitude
-
- let a = mul(rhs._storage.low, lhs._storage.low)
- let b = mul(rhs._storage.low, lhs._storage.high)
- let c = mul(rhs._storage.high, lhs._storage.low)
- let d = mul(rhs._storage.high, lhs._storage.high)
-
- let mid1 = sum(a.carry, b.partial, c.partial)
- let mid2 = sum(b.carry, c.carry, d.partial)
-
- let low = DoubleWidth<Low>((mid1.partial, a.partial))
- let high = DoubleWidth(
- (High(mid2.carry + d.carry), mid1.carry + mid2.partial))
-
- if isNegative {
- let (lowComplement, overflow) = (~low).addingReportingOverflow(1)
- return (~high + (overflow == .overflow ? 1 : 0), lowComplement)
- } else {
- return (high, low)
- }
- }
-
- public func dividingFullWidth(
- _ dividend: (high: DoubleWidth, low: DoubleWidth.Magnitude)
- ) -> (quotient: DoubleWidth, remainder: DoubleWidth) {
- let lhs = DoubleWidth<DoubleWidth<Base>>(dividend)
- let rhs = DoubleWidth<DoubleWidth<Base>>(self)
- let (quotient, remainder) = lhs.quotientAndRemainder(dividingBy: rhs)
-
- // FIXME(integers): check for overflow of quotient and remainder
- return (DoubleWidth(quotient.low), DoubleWidth(remainder.low))
- }
-
-% for x in binaryBitwise:
- public static func ${x.operator}=(
- lhs: inout DoubleWidth, rhs: DoubleWidth
- ) {
- lhs._storage.low ${x.operator}= rhs._storage.low
- lhs._storage.high ${x.operator}= rhs._storage.high
- }
-% end
-
- public static func <<=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
- if rhs < (0 as DoubleWidth) {
- lhs >>= 0 - rhs
- return
- }
-
- if rhs._storage.high != (0 as High) ||
- rhs._storage.low >= DoubleWidth.bitWidth
- {
- lhs = 0
- return
- }
-
- // Shift is exactly the width of `Base`, so low -> high.
- if rhs._storage.low == Base.bitWidth {
- lhs = DoubleWidth((High(extendingOrTruncating: lhs._storage.low), 0))
- return
- }
-
- lhs &<<= rhs
- }
-
- public static func >>=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
- if rhs < (0 as DoubleWidth) {
- lhs <<= 0 - rhs
- return
- }
-
- // Shift is larger than this type's bit width.
- if rhs._storage.high != (0 as High) ||
- rhs._storage.low >= DoubleWidth.bitWidth
- {
- lhs = lhs < (0 as DoubleWidth) ? ~0 : 0
- return
- }
-
- // Shift is exactly the width of `Base`, so high -> low.
- if rhs._storage.low == Base.bitWidth {
- lhs = DoubleWidth((
- lhs < (0 as DoubleWidth) ? ~0 : 0,
- Low(extendingOrTruncating: lhs._storage.high)
- ))
- return
- }
-
- lhs &>>= rhs
- }
-
- public static func &<<=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
- let rhs = rhs & DoubleWidth(DoubleWidth.bitWidth - 1)
-
- lhs._storage.high <<= High(rhs._storage.low)
- if Base.bitWidth > rhs._storage.low {
- lhs._storage.high |= High(extendingOrTruncating: lhs._storage.low >>
- (numericCast(Base.bitWidth) - rhs._storage.low))
- } else {
- lhs._storage.high |= High(extendingOrTruncating: lhs._storage.low <<
- (rhs._storage.low - numericCast(Base.bitWidth)))
- }
- lhs._storage.low <<= rhs._storage.low
- }
-
- public static func &>>=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
- let rhs = rhs & DoubleWidth(DoubleWidth.bitWidth - 1)
-
- lhs._storage.low >>= rhs._storage.low
- if Base.bitWidth > rhs._storage.low {
- lhs._storage.low |= Low(extendingOrTruncating: lhs._storage.high <<
- numericCast(numericCast(Base.bitWidth) - rhs._storage.low))
- } else {
- lhs._storage.low |= Low(extendingOrTruncating: lhs._storage.high >>
- numericCast(rhs._storage.low - numericCast(Base.bitWidth)))
- }
- lhs._storage.high >>= High(extendingOrTruncating: rhs._storage.low)
- }
-
-% for x in chain(*binaryArithmetic.values()):
-
- // FIXME(integers): remove this once the operators are back to Numeric
- public static func ${x.operator} (
- lhs: DoubleWidth, rhs: DoubleWidth
- ) -> DoubleWidth {
- var lhs = lhs
- lhs ${x.operator}= rhs
- return lhs
- }
-
-% argumentLabel = (x.firstArg + ':') if x.firstArg != '_' else ''
- public static func ${x.operator}=(
- lhs: inout DoubleWidth, rhs: DoubleWidth
- ) {
- let (result, overflow) = lhs.${x.name}ReportingOverflow(${argumentLabel}rhs)
- _precondition(overflow == .none, "Overflow in ${x.operator}=")
- lhs = result
- }
-% end
-
- public init(_truncatingBits bits: UInt) {
- _storage.low = Low(_truncatingBits: bits)
- _storage.high = High(_truncatingBits: bits >> UInt(Base.bitWidth))
- }
-
- // other
- //
- public init(_builtinIntegerLiteral x: _MaxBuiltinIntegerType) {
- // FIXME: This won't work if `x` is out of range for `Int64`
- self.init(Int64(_builtinIntegerLiteral: x))
- }
-
- public var description: String {
- return "(\(_storage.high), \(_storage.low))"
- }
-
- public var leadingZeroBitCount: Int {
- return high == (0 as High)
- ? Base.bitWidth + low.leadingZeroBitCount
- : high.leadingZeroBitCount
- }
-
- public var trailingZeroBitCount: Int {
- return low == (0 as Low)
- ? Base.bitWidth + high.trailingZeroBitCount
- : low.trailingZeroBitCount
- }
-
- public var nonzeroBitCount: Int {
- return high.nonzeroBitCount + low.nonzeroBitCount
- }
-
- public var hashValue: Int {
- return _mixInt(high.hashValue) ^ low.hashValue
- }
-
- @_transparent
- public var byteSwapped: DoubleWidth {
- return DoubleWidth((High(extendingOrTruncating: low.byteSwapped),
- Low(extendingOrTruncating: high.byteSwapped)))
- }
-}
-
-// FIXME(ABI) (Conditional Conformance):
-// DoubleWidth should conform to SignedInteger where Base : SignedInteger
-extension DoubleWidth where Base : SignedInteger {
- /// Returns the additive inverse of the specified value.
- ///
- /// The negation operator (prefix `-`) returns the additive inverse of its
- /// argument.
- ///
- /// let x = 21 as DoubleWidth<Int>
- /// let y = -x
- /// // y == -21
- ///
- /// The resulting value must be representable in the same type as the
- /// argument. In particular, negating a signed, fixed-width integer type's
- /// minimum results in a value that cannot be represented.
- ///
- /// let z = -DoubleWidth<Int>.min
- /// // Overflow error
- ///
- /// - Returns: The additive inverse of this value.
- ///
- /// - SeeAlso: `negate()`
- public static prefix func - (_ operand: DoubleWidth) -> DoubleWidth {
- return 0 - operand
- }
-
- /// Replaces this value with its additive inverse.
- ///
- /// The following example uses the `negate()` method to negate the value of
- /// an integer `x`:
- ///
- /// var x = 21 as DoubleWidth<Int>
- /// x.negate()
- /// // x == -21
- ///
- /// - SeeAlso: The unary minus operator (`-`).
- public mutating func negate() {
- self = 0 - self
- }
-}
-
// FIXME(integers): switch to using `FixedWidthInteger.unsafeAdding`
internal func _unsafePlus(_ lhs: Int, _ rhs: Int) -> Int {
#if INTERNAL_CHECKS_ENABLED
diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp
index 2ccd48b..c500356 100644
--- a/stdlib/public/runtime/Errors.cpp
+++ b/stdlib/public/runtime/Errors.cpp
@@ -46,8 +46,10 @@
#include <execinfo.h>
#endif
-#ifdef __APPLE__
+#if defined(__APPLE__)
#include <asl.h>
+#elif defined(__ANDROID__)
+#include <android/log.h>
#endif
namespace FatalErrorFlags {
@@ -228,8 +230,10 @@
#else
write(STDERR_FILENO, message, strlen(message));
#endif
-#ifdef __APPLE__
+#if defined(__APPLE__)
asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", message);
+#elif defined(__ANDROID__)
+ __android_log_print(ANDROID_LOG_FATAL, "SwiftRuntime", "%s", message);
#endif
#if SWIFT_SUPPORTS_BACKTRACE_REPORTING
if (flags & FatalErrorFlags::ReportBacktrace) {
diff --git a/test/Compatibility/lazy_properties.swift b/test/Compatibility/lazy_properties.swift
new file mode 100644
index 0000000..c621521
--- /dev/null
+++ b/test/Compatibility/lazy_properties.swift
@@ -0,0 +1,57 @@
+// RUN: %target-typecheck-verify-swift -parse-as-library -swift-version 3
+
+class ReferenceSelfInLazyProperty {
+ lazy var refs = (i, f())
+ // expected-error@-1 {{cannot use instance member 'i' within property initializer; property initializers run before 'self' is available}}
+ lazy var trefs: (Int, Int) = (i, f())
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+
+ lazy var qrefs = (self.i, self.f())
+ lazy var qtrefs: (Int, Int) = (self.i, self.f())
+
+ lazy var crefs = { (i, f()) }()
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+
+ lazy var ctrefs: (Int, Int) = { (i, f()) }()
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+
+ lazy var cqrefs = { (self.i, self.f()) }()
+ lazy var cqtrefs: (Int, Int) = { (self.i, self.f()) }()
+
+ lazy var mrefs = { () -> (Int, Int) in return (i, f()) }()
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+
+ lazy var mtrefs: (Int, Int) = { return (i, f()) }()
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+
+ lazy var mqrefs = { () -> (Int, Int) in (self.i, self.f()) }()
+ lazy var mqtrefs: (Int, Int) = { return (self.i, self.f()) }()
+
+ lazy var lcqrefs = { [unowned self] in (self.i, self.f()) }()
+ lazy var lcqtrefs: (Int, Int) = { [unowned self] in (self.i, self.f()) }()
+
+ lazy var lmrefs = { [unowned self] () -> (Int, Int) in return (i, f()) }()
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+ lazy var lmtrefs: (Int, Int) = { [unowned self] in return (i, f()) }()
+ // expected-error@-1 {{instance member 'i' cannot be used on type 'ReferenceSelfInLazyProperty'}}
+
+ lazy var lmqrefs = { [unowned self] () -> (Int, Int) in (self.i, self.f()) }()
+ lazy var lmqtrefs: (Int, Int) = { [unowned self] in return (self.i, self.f()) }()
+
+ var i = 42
+ func f() -> Int { return 0 }
+}
+
+class ReferenceStaticInLazyProperty {
+ lazy var refs1 = i
+ lazy var refs2 = f()
+ // expected-error@-1 {{use of unresolved identifier 'f'}}
+
+ lazy var trefs1: Int = i
+ lazy var trefs2: Int = f()
+ // expected-error@-1 {{use of unresolved identifier 'f'}}
+
+ static var i = 42
+ static func f() -> Int { return 0 }
+ // expected-note@-1 {{did you mean 'f'?}}
+}
diff --git a/test/Constraints/availability.swift b/test/Constraints/availability.swift
new file mode 100644
index 0000000..81cf130
--- /dev/null
+++ b/test/Constraints/availability.swift
@@ -0,0 +1,17 @@
+// RUN: %target-typecheck-verify-swift -swift-version 4
+
+// Ensure that we do not select the unavailable failable init as the
+// only solution and then fail to typecheck.
+protocol P {}
+
+class C : P {
+ @available(swift, obsoleted: 4)
+ public init?(_ c: C) {
+ }
+
+ public init<T : P>(_ c: T) {}
+}
+
+func f(c: C) {
+ let _: C? = C(c)
+}
diff --git a/test/Constraints/patterns.swift b/test/Constraints/patterns.swift
index 319d7b8..d99ccb3 100644
--- a/test/Constraints/patterns.swift
+++ b/test/Constraints/patterns.swift
@@ -165,7 +165,7 @@
// <rdar://problem/21995744> QoI: Binary operator '~=' cannot be applied to operands of type 'String' and 'String?'
switch ("foo" as String?) {
-case "what": break // expected-error{{expression pattern of type 'String' cannot match values of type 'String?'}}
+case "what": break // expected-error{{expression pattern of type 'String' cannot match values of type 'String?'}} {{12-12=?}}
default: break
}
diff --git a/test/Driver/bridging-pch.swift b/test/Driver/bridging-pch.swift
index 5899649..bb3ac15 100644
--- a/test/Driver/bridging-pch.swift
+++ b/test/Driver/bridging-pch.swift
@@ -42,6 +42,12 @@
// PERSISTENT-YESPCHJOB: {{.*}}swift -frontend {{.*}} -emit-pch -pch-output-dir {{.*}}/pch
// PERSISTENT-YESPCHJOB: {{.*}}swift -frontend {{.*}} -import-objc-header {{.*}}bridging-header.h -pch-output-dir {{.*}}/pch -pch-disable-validation
+// RUN: %swiftc_driver -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -serialize-diagnostics %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG1
+// PERSISTENT-YESPCHJOB-DIAG1: {{.*}}swift -frontend {{.*}} -serialize-diagnostics-path {{.*}}bridging-header-{{.*}}.dia {{.*}} -emit-pch -pch-output-dir {{.*}}/pch
+
+// RUN: %swiftc_driver -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch-out-dir -serialize-diagnostics %s -emit-module -emit-module-path /module-path-dir 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG2
+// PERSISTENT-YESPCHJOB-DIAG2: {{.*}}swift -frontend {{.*}} -serialize-diagnostics-path {{.*}}/pch-out-dir/bridging-header-{{.*}}.dia {{.*}} -emit-pch -pch-output-dir {{.*}}/pch-out-dir
+
// RUN: %swiftc_driver -typecheck -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -parseable-output -driver-skip-execution %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-OUTPUT
// PERSISTENT-OUTPUT-NOT: "outputs": [
diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift
index 81967a8..a6815ca 100644
--- a/test/IDE/complete_decl_attribute.swift
+++ b/test/IDE/complete_decl_attribute.swift
@@ -58,7 +58,7 @@
@#^KEYWORD3^#
class C {}
-// KEYWORD3: Begin completions, 10 items
+// KEYWORD3: Begin completions, 8 items
// KEYWORD3-NEXT: Keyword/None: available[#Class Attribute#]; name=available{{$}}
// KEYWORD3-NEXT: Keyword/None: objc[#Class Attribute#]; name=objc{{$}}
// KEYWORD3-NEXT: Keyword/None: IBDesignable[#Class Attribute#]; name=IBDesignable{{$}}
@@ -67,8 +67,6 @@
// KEYWORD3-NEXT: Keyword/None: objcMembers[#Class Attribute#]; name=objcMembers{{$}}
// KEYWORD3-NEXT: Keyword/None: NSApplicationMain[#Class Attribute#]; name=NSApplicationMain{{$}}
// KEYWORD3-NEXT: Keyword/None: objc_non_lazy_realization[#Class Attribute#]; name=objc_non_lazy_realization{{$}}
-// KEYWORD3-NEXT: Keyword/None: NSKeyedArchiverClassName[#Class Attribute#]; name=NSKeyedArchiverClassName{{$}}
-// KEYWORD3-NEXT: Keyword/None: NSKeyedArchiverEncodeNonGenericSubclassesOnly[#Class Attribute#]; name=NSKeyedArchiverEncodeNonGenericSubclassesOnly{{$}}
// KEYWORD3-NEXT: End completions
@#^KEYWORD4^#
@@ -88,7 +86,7 @@
@#^KEYWORD_LAST^#
-// KEYWORD_LAST: Begin completions, 23 items
+// KEYWORD_LAST: Begin completions, 21 items
// KEYWORD_LAST-NEXT: Keyword/None: available[#Declaration Attribute#]; name=available{{$}}
// KEYWORD_LAST-NEXT: Keyword/None: objc[#Declaration Attribute#]; name=objc{{$}}
// KEYWORD_LAST-NEXT: Keyword/None: noreturn[#Declaration Attribute#]; name=noreturn{{$}}
@@ -110,6 +108,4 @@
// KEYWORD_LAST-NEXT: Keyword/None: warn_unqualified_access[#Declaration Attribute#]; name=warn_unqualified_access
// KEYWORD_LAST-NEXT: Keyword/None: discardableResult[#Declaration Attribute#]; name=discardableResult
// KEYWORD_LAST-NEXT: Keyword/None: GKInspectable[#Declaration Attribute#]; name=GKInspectable{{$}}
-// KEYWORD_LAST-NEXT: Keyword/None: NSKeyedArchiverClassName[#Declaration Attribute#]; name=NSKeyedArchiverClassName{{$}}
-// KEYWORD_LAST-NEXT: Keyword/None: NSKeyedArchiverEncodeNonGenericSubclassesOnly[#Declaration Attribute#]; name=NSKeyedArchiverEncodeNonGenericSubclassesOnly{{$}}
// KEYWORD_LAST-NEXT: End completions
diff --git a/test/Interpreter/SDK/archive_attributes.swift b/test/Interpreter/SDK/archive_attributes.swift
index 3b45aad..6e8c74d 100644
--- a/test/Interpreter/SDK/archive_attributes.swift
+++ b/test/Interpreter/SDK/archive_attributes.swift
@@ -2,7 +2,7 @@
// RUN: %target-build-swift %s -module-name=test -DENCODE -o %t/encode
// RUN: %target-build-swift %s -module-name=test -o %t/decode
// RUN: %target-run %t/encode %t/test.arc
-// RUN: %FileCheck -check-prefix=CHECK-ARCHIVE %s < %t/test.arc
+// RUN: plutil -p %t/test.arc | %FileCheck -check-prefix=CHECK-ARCHIVE %s
// RUN: %target-run %t/decode %t/test.arc | %FileCheck %s
// REQUIRES: executable_test
@@ -14,8 +14,8 @@
import Foundation
struct ABC {
- // CHECK-ARCHIVE-DAG: nested_class_coding
- @NSKeyedArchiverClassName("nested_class_coding")
+ // CHECK-ARCHIVE-DAG: "$classname" => "nested_class_coding"
+ @objc(nested_class_coding)
class NestedClass : NSObject, NSCoding {
var i : Int
@@ -33,8 +33,8 @@
}
}
-// CHECK-ARCHIVE-DAG: private_class_coding
-@NSKeyedArchiverClassName("private_class_coding")
+// CHECK-ARCHIVE-DAG: "$classname" => "private_class_coding"
+@objc(private_class_coding)
private class PrivateClass : NSObject, NSCoding {
var pi : Int
@@ -51,7 +51,6 @@
}
}
-@NSKeyedArchiverEncodeNonGenericSubclassesOnly
class GenericClass<T> : NSObject, NSCoding {
var gi : T? = nil
@@ -65,7 +64,7 @@
}
}
-// CHECK-ARCHIVE-DAG: test.IntClass
+// CHECK-ARCHIVE-DAG: "$classname" => "test.IntClass"
class IntClass : GenericClass<Int> {
init(ii: Int) {
@@ -83,8 +82,8 @@
}
}
-// CHECK-ARCHIVE-DAG: double_class_coding
-@NSKeyedArchiverClassName("double_class_coding")
+// CHECK-ARCHIVE-DAG: "$classname" => "double_class_coding"
+@objc(double_class_coding)
class DoubleClass : GenericClass<Double> {
init(dd: Double) {
@@ -102,8 +101,8 @@
}
}
-// CHECK-ARCHIVE-DAG: top_level_coding
-@NSKeyedArchiverClassName("top_level_coding")
+// CHECK-ARCHIVE-DAG: "$classname" => "top_level_coding"
+@objc(top_level_coding)
class TopLevel : NSObject, NSCoding {
var tli : Int
diff --git a/test/Interpreter/SDK/archiving_generic_swift_class.swift b/test/Interpreter/SDK/archiving_generic_swift_class.swift
index 1a612a3..b862e60 100644
--- a/test/Interpreter/SDK/archiving_generic_swift_class.swift
+++ b/test/Interpreter/SDK/archiving_generic_swift_class.swift
@@ -6,7 +6,6 @@
import Foundation
-@NSKeyedArchiverEncodeNonGenericSubclassesOnly
final class Foo<T: NSCoding>: NSObject, NSCoding {
var one, two: T
diff --git a/test/NameBinding/name_lookup.swift b/test/NameBinding/name_lookup.swift
index b8b0aef..947adc8 100644
--- a/test/NameBinding/name_lookup.swift
+++ b/test/NameBinding/name_lookup.swift
@@ -528,7 +528,7 @@
// <rdar://problem/16954496> lazy properties must use "self." in their body, and can weirdly refer to class variables directly
class r16954496 {
func bar() {}
- lazy var x: Array<() -> Void> = [bar]
+ lazy var x: Array<() -> Void> = [bar] // expected-error {{cannot convert value of type '(r16954496) -> () -> ()' to expected element type '() -> Void'}}
}
diff --git a/test/SILGen/objc_properties.swift b/test/SILGen/objc_properties.swift
index d994537..4131834 100644
--- a/test/SILGen/objc_properties.swift
+++ b/test/SILGen/objc_properties.swift
@@ -242,7 +242,7 @@
return nil
}
- lazy var window = instanceMethod()
+ lazy var window = self.instanceMethod()
}
// CHECK-LABEL: sil hidden @_T015objc_properties15HasLazyPropertyC6windowSo8NSObjectCSgfg : $@convention(method) (@guaranteed HasLazyProperty) -> @owned Optional<NSObject> {
diff --git a/test/SILOptimizer/closure_specialize_consolidated.sil b/test/SILOptimizer/closure_specialize_consolidated.sil
index 9d7e878..5f815e2 100644
--- a/test/SILOptimizer/closure_specialize_consolidated.sil
+++ b/test/SILOptimizer/closure_specialize_consolidated.sil
@@ -543,9 +543,15 @@
%9999 = tuple ()
return %9999 : $()
}
-
-// CHECK-LABEL: sil @thin_thick_and_partial_apply_test : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
-// CHECK: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $Builtin.Int32, [[ARG2:%.*]] : $Builtin.NativeObject, [[ARG3:%.*]] : $Builtin.NativeObject):
+sil @guaranteed_apply_callee_throw : $@convention(thin) (@guaranteed @callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Error) -> @error Error {
+bb0(%0 : $@callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), %1 : $Builtin.NativeObject, %2 : $Builtin.Int32, %3 : $Builtin.NativeObject, %4 : $Builtin.NativeObject, %5: $Error):
+ retain_value %3 : $Builtin.NativeObject
+ apply %0(%1, %2, %3, %4) : $@callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
+ release_value %3 : $Builtin.NativeObject
+ throw %5 : $Error
+}
+// CHECK-LABEL: sil @thin_thick_and_partial_apply_test : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Error) -> () {
+// CHECK: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $Builtin.Int32, [[ARG2:%.*]] : $Builtin.NativeObject, [[ARG3:%.*]] : $Builtin.NativeObject, [[ARG4:%.*]] : $Error):
// CHECK: [[OLD_CLOSURE_CALLEE1:%.*]] = function_ref @large_closure_callee
// CHECK: [[OLD_CLOSURE_CALLEE2:%.*]] = function_ref @small_closure_callee
// CHECK: retain_value [[ARG0]] : $Builtin.NativeObject
@@ -580,8 +586,8 @@
// CHECK-NEXT: release_value [[DEAD_CLOSURE_1]]
// CHECK-NOT: release_value [[DEAD_CLOSURE_2]]
-// REMOVECLOSURES-LABEL: sil @thin_thick_and_partial_apply_test : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
-// REMOVECLOSURES: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $Builtin.Int32, [[ARG2:%.*]] : $Builtin.NativeObject, [[ARG3:%.*]] : $Builtin.NativeObject):
+// REMOVECLOSURES-LABEL: sil @thin_thick_and_partial_apply_test : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Error) -> () {
+// REMOVECLOSURES: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $Builtin.Int32, [[ARG2:%.*]] : $Builtin.NativeObject, [[ARG3:%.*]] : $Builtin.NativeObject, [[ARG4:%.*]] : $Error):
// REMOVECLOSURES: [[OLD_CLOSURE_CALLEE1:%.*]] = function_ref @large_closure_callee
// REMOVECLOSURES: [[OLD_CLOSURE_CALLEE2:%.*]] = function_ref @small_closure_callee
// REMOVECLOSURES: retain_value [[ARG0]] : $Builtin.NativeObject
@@ -596,6 +602,7 @@
// REMOVECLOSURES-NEXT: retain_value [[ARG2]] : $Builtin.NativeObject
// REMOVECLOSURES-NEXT: retain_value [[ARG3]] : $Builtin.NativeObject
// REMOVECLOSURES-NOT: partial_apply [[OLD_CLOSURE_CALLEE1]]
+// REMOVECLOSURES: [[SPECFUN4:%.*]] = function_ref @_T029guaranteed_apply_callee_throw014small_closure_C0Tf1cnnnnn_n
// REMOVECLOSURES: [[SPECFUN2:%.*]] = function_ref @_T023guaranteed_apply_callee014small_closure_C0Tf1cnnnn_n
// REMOVECLOSURES: [[SPECFUN3:%.*]] = function_ref @_T018owned_apply_callee014small_closure_C0Tf1cnnnn_n
// REMOVECLOSURES-NOT: thin_to_thick_function [[OLD_CLOSURE_CALLEE2]]
@@ -606,13 +613,14 @@
// REMOVECLOSURES-NEXT: strong_release [[ARG0]] : $Builtin.NativeObject
// REMOVECLOSURES-NEXT: strong_release [[ARG2]] : $Builtin.NativeObject
// REMOVECLOSURES-NEXT: strong_release [[ARG3]] : $Builtin.NativeObject
-
-sil @thin_thick_and_partial_apply_test : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
-bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int32, %2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject):
+// REMOVECLOSURES-NEXT: try_apply [[SPECFUN4]](
+sil @thin_thick_and_partial_apply_test : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Error) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int32, %2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject, %11: $Error):
%4 = function_ref @owned_apply_callee : $@convention(thin) (@owned @callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
%5 = function_ref @guaranteed_apply_callee : $@convention(thin) (@guaranteed @callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
%6 = function_ref @large_closure_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
%7 = function_ref @small_closure_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
+ %10 = function_ref @guaranteed_apply_callee_throw : $@convention(thin) (@guaranteed @callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Error) -> @error Error
retain_value %0 : $Builtin.NativeObject
retain_value %2 : $Builtin.NativeObject
@@ -627,6 +635,15 @@
apply %5(%9, %0, %1, %2, %3) : $@convention(thin) (@guaranteed @callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
release_value %8 : $@callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> ()
+ try_apply %10(%9, %0, %1, %2, %3, %11) : $@convention(thin) (@guaranteed @callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> (), Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Error) -> @error Error, normal bb2, error bb3
+
+bb2(%n : $()):
+ br bb4
+
+bb3(%e : $Error):
+ br bb4
+
+bb4:
%9999 = tuple()
return %9999 : $()
}
diff --git a/test/SILOptimizer/guaranteed_arc_opts_qualified.sil b/test/SILOptimizer/guaranteed_arc_opts_qualified.sil
index cda4fc2..d8e5d21 100644
--- a/test/SILOptimizer/guaranteed_arc_opts_qualified.sil
+++ b/test/SILOptimizer/guaranteed_arc_opts_qualified.sil
@@ -137,3 +137,24 @@
%9999 = tuple()
return %9999 : $()
}
+
+class C {
+ var val: Builtin.Int32
+ init(i: Builtin.Int32)
+ deinit
+}
+
+// CHECK-LABEL: sil @access_test : $@convention(thin) (@owned C, Builtin.Int32) -> ()
+// CHECK-NOT: strong_retain
+// CHECK-NOT: strong_release
+sil @access_test : $@convention(thin) (@owned C, Builtin.Int32) -> () {
+bb0(%0 : $C, %1 : $Builtin.Int32):
+ strong_retain %0 : $C
+ %valadr = ref_element_addr %0 : $C, #C.val
+ %access = begin_access [modify] [dynamic] %valadr : $*Builtin.Int32
+ store %1 to %access : $*Builtin.Int32
+ end_access %access : $*Builtin.Int32
+ strong_release %0 : $C
+ %9999 = tuple()
+ return %9999 : $()
+}
diff --git a/test/SILOptimizer/inline_semantics.sil b/test/SILOptimizer/inline_semantics.sil
index 8947788..c025b87 100644
--- a/test/SILOptimizer/inline_semantics.sil
+++ b/test/SILOptimizer/inline_semantics.sil
@@ -7,9 +7,9 @@
sil [_semantics "no_inline_plz"] @callee_func : $@convention(thin) () -> Int32 {
bb0:
- %0 = integer_literal $Builtin.Int32, 3 // user: %1
- %1 = struct $Int32 (%0 : $Builtin.Int32) // user: %2
- return %1 : $Int32 // id: %2
+ %0 = integer_literal $Builtin.Int32, 3
+ %1 = struct $Int32 (%0 : $Builtin.Int32)
+ return %1 : $Int32
}
//Not every @_semantics should be skipped during the early inlining pass, but
@@ -21,16 +21,16 @@
//CHECK: end sil function 'caller_func'
sil @caller_func : $@convention(thin) () -> Int32 {
bb0:
- %0 = function_ref @callee_func : $@convention(thin) () -> Int32 // user: %1
- %1 = apply %0() : $@convention(thin) () -> Int32 // user: %2
- return %1 : $Int32 // id: %2
+ %0 = function_ref @callee_func : $@convention(thin) () -> Int32
+ %1 = apply %0() : $@convention(thin) () -> Int32
+ return %1 : $Int32
}
sil [_semantics "array.make_mutable"] @callee_func_with_to_be_skipped_during_inlining_semantics : $@convention(method) (@inout Int32) -> Int32 {
bb0(%self : $*Int32):
- %0 = integer_literal $Builtin.Int32, 3 // user: %1
- %1 = struct $Int32 (%0 : $Builtin.Int32) // user: %2
- return %1 : $Int32 // id: %2
+ %0 = integer_literal $Builtin.Int32, 3
+ %1 = struct $Int32 (%0 : $Builtin.Int32)
+ return %1 : $Int32
}
//Not every @_semantics should be skipped during the early inlining pass, but
@@ -44,17 +44,57 @@
bb0:
%self = alloc_stack $Int32
%0 = function_ref @callee_func_with_to_be_skipped_during_inlining_semantics : $@convention(method) (@inout Int32) -> Int32 // user: %1
- %1 = apply %0(%self) : $@convention(method) (@inout Int32) -> Int32 // user: %2
+ %1 = apply %0(%self) : $@convention(method) (@inout Int32) -> Int32
dealloc_stack %self : $*Int32
- return %1 : $Int32 // id: %2
+ return %1 : $Int32
+}
+
+sil [_semantics "pair_no_escaping_closure"] @callee_func_with_pair_no_escaping_closure_semantics : $@convention(method) (@inout Int32) -> Int32 {
+bb0(%self : $*Int32):
+ %0 = integer_literal $Builtin.Int32, 3
+ %1 = struct $Int32 (%0 : $Builtin.Int32)
+ return %1 : $Int32
+}
+
+//CHECK-LABEL: caller_func3
+//CHECK: function_ref
+//CHECK: apply
+//CHECK: end sil function 'caller_func3'
+sil @caller_func3 : $@convention(thin) () -> Int32 {
+bb0:
+ %self = alloc_stack $Int32
+ %0 = function_ref @callee_func_with_pair_no_escaping_closure_semantics : $@convention(method) (@inout Int32) -> Int32 // user: %1
+ %1 = apply %0(%self) : $@convention(method) (@inout Int32) -> Int32
+ dealloc_stack %self : $*Int32
+ return %1 : $Int32
+}
+
+sil [_semantics "self_no_escaping_closure"] @callee_func_with_self_no_escaping_closure_semantics : $@convention(method) (@inout Int32) -> Int32 {
+bb0(%self : $*Int32):
+ %0 = integer_literal $Builtin.Int32, 3
+ %1 = struct $Int32 (%0 : $Builtin.Int32)
+ return %1 : $Int32
+}
+
+//CHECK-LABEL: caller_func4
+//CHECK: function_ref
+//CHECK: apply
+//CHECK: end sil function 'caller_func4'
+sil @caller_func4 : $@convention(thin) () -> Int32 {
+bb0:
+ %self = alloc_stack $Int32
+ %0 = function_ref @callee_func_with_self_no_escaping_closure_semantics : $@convention(method) (@inout Int32) -> Int32 // user: %1
+ %1 = apply %0(%self) : $@convention(method) (@inout Int32) -> Int32
+ dealloc_stack %self : $*Int32
+ return %1 : $Int32
}
// A function annotated with the @effects(readonly) attribute.
sil [readonly] @callee_func2 : $@convention(thin) () -> Int32 {
bb0:
- %0 = integer_literal $Builtin.Int32, 3 // user: %1
- %1 = struct $Int32 (%0 : $Builtin.Int32) // user: %2
- return %1 : $Int32 // id: %2
+ %0 = integer_literal $Builtin.Int32, 3
+ %1 = struct $Int32 (%0 : $Builtin.Int32)
+ return %1 : $Int32
}
//CHECK-LABEL: caller_func1
@@ -63,8 +103,8 @@
//CHECK-NEXT: ret
sil @caller_func1 : $@convention(thin) () -> Int32 {
bb0:
- %0 = function_ref @callee_func2 : $@convention(thin) () -> Int32 // user: %1
- %1 = apply %0() : $@convention(thin) () -> Int32 // user: %2
- return %1 : $Int32 // id: %2
+ %0 = function_ref @callee_func2 : $@convention(thin) () -> Int32
+ %1 = apply %0() : $@convention(thin) () -> Int32
+ return %1 : $Int32
}
diff --git a/test/attr/attr_fixed_layout.swift b/test/attr/attr_fixed_layout.swift
index be40c16..0eefb79 100644
--- a/test/attr/attr_fixed_layout.swift
+++ b/test/attr/attr_fixed_layout.swift
@@ -1,5 +1,7 @@
// RUN: %target-swift-frontend -typecheck -verify -dump-ast -enable-resilience %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-ON %s
+// RUN: %target-swift-frontend -typecheck -verify -dump-ast -enable-resilience -enable-testing %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-ON %s
// RUN: %target-swift-frontend -typecheck -verify -dump-ast %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-OFF %s
+// RUN: %target-swift-frontend -typecheck -verify -dump-ast %s -enable-testing 2>&1 | %FileCheck --check-prefix=RESILIENCE-OFF %s
//
// Public types with @_fixed_layout are always fixed layout
diff --git a/test/attr/attr_inlineable.swift b/test/attr/attr_inlineable.swift
index 2c659fa..ebca886 100644
--- a/test/attr/attr_inlineable.swift
+++ b/test/attr/attr_inlineable.swift
@@ -1,4 +1,5 @@
// RUN: %target-typecheck-verify-swift -swift-version 4
+// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-testing
@_inlineable struct TestInlineableStruct {}
// expected-error@-1 {{@_inlineable cannot be applied to this declaration}}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index aee8afa..20897b6 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -419,6 +419,13 @@
@objc func foo() {} // expected-error {{@objc is not supported within extensions of generic classes}}
}
+@objc(CustomNameForSubclassOfGeneric) // okay
+class ConcreteSubclassOfGeneric3 : GenericContext3<Int> {}
+
+extension ConcreteSubclassOfGeneric3 {
+ @objc func foo() {} // expected-error {{@objc is not supported within extensions of generic classes}}
+}
+
class subject_subscriptIndexed1 {
@objc
subscript(a: Int) -> Int { // no-error
diff --git a/test/attr/attr_objc_swift3_deprecated.swift b/test/attr/attr_objc_swift3_deprecated.swift
index 28bb52d..823f003 100644
--- a/test/attr/attr_objc_swift3_deprecated.swift
+++ b/test/attr/attr_objc_swift3_deprecated.swift
@@ -19,6 +19,21 @@
dynamic var bar: NSObject? = nil // expected-warning{{inference of '@objc' for 'dynamic' members is deprecated}}{{3-3=@objc }}
}
+class GenericClass<T>: NSObject {}
+
+class SubclassOfGeneric: GenericClass<Int> {
+ func foo() { } // expected-warning{{inference of '@objc' for members of Objective-C-derived classes is deprecated}}
+ // expected-note@-1{{add `@objc` to continue exposing an Objective-C entry point (Swift 3 behavior)}}{{3-3=@objc }}
+ // expected-note@-2{{add `@nonobjc` to suppress the Objective-C entry point (Swift 4 behavior)}}{{3-3=@nonobjc }}
+}
+
+@objc(SubclassOfGenericCustom)
+class SubclassOfGenericCustomName: GenericClass<Int> {
+ func foo() { } // expected-warning{{inference of '@objc' for members of Objective-C-derived classes is deprecated}}
+ // expected-note@-1{{add `@objc` to continue exposing an Objective-C entry point (Swift 3 behavior)}}{{3-3=@objc }}
+ // expected-note@-2{{add `@nonobjc` to suppress the Objective-C entry point (Swift 4 behavior)}}{{3-3=@nonobjc }}
+}
+
// Suppress diagnostices about references to inferred @objc declarations
// in this mode.
func test(sc: ObjCSubclass, dm: DynamicMembers) {
diff --git a/test/attr/attr_versioned.swift b/test/attr/attr_versioned.swift
index 0d72404..9f6cb39 100644
--- a/test/attr/attr_versioned.swift
+++ b/test/attr/attr_versioned.swift
@@ -1,4 +1,5 @@
// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -enable-testing
@_versioned private func privateVersioned() {}
// expected-error@-1 {{'@_versioned' attribute can only be applied to internal declarations, but 'privateVersioned' is private}}
diff --git a/test/decl/nested/protocol.swift b/test/decl/nested/protocol.swift
index 231c457..fa563d3 100644
--- a/test/decl/nested/protocol.swift
+++ b/test/decl/nested/protocol.swift
@@ -40,9 +40,11 @@
associatedtype Stripes
class Claw<T> { // expected-error{{type 'Claw' cannot be nested in protocol 'Racoon'}}
func mangle(_ s: Stripes) {}
+ // expected-error@-1 {{use of undeclared type 'Stripes'}}
}
struct Fang<T> { // expected-error{{type 'Fang' cannot be nested in protocol 'Racoon'}}
func gnaw(_ s: Stripes) {}
+ // expected-error@-1 {{use of undeclared type 'Stripes'}}
}
enum Fur { // expected-error{{type 'Fur' cannot be nested in protocol 'Racoon'}}
case Stripes
diff --git a/test/decl/protocol/conforms/nscoding.swift b/test/decl/protocol/conforms/nscoding.swift
index 51982d9..ee8aaf2 100644
--- a/test/decl/protocol/conforms/nscoding.swift
+++ b/test/decl/protocol/conforms/nscoding.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -enable-nskeyedarchiver-diagnostics -verify
-// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s 2>&1 | %FileCheck -check-prefix CHECK-NO-DIAGS %s
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -verify
+// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -disable-nskeyedarchiver-diagnostics 2>&1 | %FileCheck -check-prefix CHECK-NO-DIAGS %s
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -dump-ast 2> %t.ast
// RUN: %FileCheck %s < %t.ast
@@ -12,6 +12,7 @@
import Foundation
// Top-level classes
+// CHECK-NOT: class_decl "CodingA"{{.*}}@_staticInitializeObjCMetadata
class CodingA : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
@@ -20,26 +21,29 @@
// Nested classes
extension CodingA {
+ // CHECK: class_decl "NestedA"{{.*}}@_staticInitializeObjCMetadata
class NestedA : NSObject, NSCoding { // expected-error{{nested class 'CodingA.NestedA' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#Objective-C class name#>)}}
- // expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiverClassName' to record the Swift 3 mangled name}}{{3-3=@NSKeyedArchiverClassName("_TtCC8nscoding7CodingA7NestedA")}}
+ // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCC8nscoding7CodingA7NestedA)}}
+ // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
class NestedB : NSObject {
- // expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#Objective-C class name#>)}}
- // expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiverClassName' to record the Swift 3 mangled name}}{{3-3=@NSKeyedArchiverClassName("_TtCC8nscoding7CodingA7NestedB")}}
+ // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCC8nscoding7CodingA7NestedB)}}
+ // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
+ // CHECK: class_decl "NestedC"{{.*}}@_staticInitializeObjCMetadata
@objc(CodingA_NestedC)
class NestedC : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
+ // CHECK: class_decl "NestedD"{{.*}}@_staticInitializeObjCMetadata
@objc(CodingA_NestedD)
class NestedD : NSObject {
required init(coder: NSCoder) { }
@@ -54,102 +58,102 @@
}
// Generic classes
-class CodingB<T> : NSObject, NSCoding { // expected-error{{generic class 'CodingB<T>' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{generic class 'CodingB<T>' should not be archived directly}}{{1-1=@NSKeyedArchiverEncodeNonGenericSubclassesOnly}}
+// CHECK-NOT: class_decl "CodingB"{{.*}}@_staticInitializeObjCMetadata
+class CodingB<T> : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
extension CodingB {
- class NestedA : NSObject, NSCoding { // expected-error{{generic class 'CodingB<T>.NestedA' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{generic class 'CodingB<T>.NestedA' should not be archived directly}}{{3-3=@NSKeyedArchiverEncodeNonGenericSubclassesOnly}}
+ class NestedA : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
}
// Fileprivate classes.
-fileprivate class CodingC : NSObject, NSCoding { // expected-error{{fileprivate class 'CodingC' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#Objective-C class name#>)}}
- // expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiverClassName' to record the Swift 3 mangled name}}{{1-1=@NSKeyedArchiverClassName("_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingC")}}
+// CHECK-NOT: class_decl "CodingC"{{.*}}@_staticInitializeObjCMetadata
+fileprivate class CodingC : NSObject, NSCoding { // expected-error{{fileprivate class 'CodingC' has an unstable name when archiving via 'NSCoding'}}
+ // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingC)}}
+ // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
// Private classes
-private class CodingD : NSObject, NSCoding { // expected-error{{private class 'CodingD' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#Objective-C class name#>)}}
- // expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiverClassName' to record the Swift 3 mangled name}}{{1-1=@NSKeyedArchiverClassName("_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingD")}}
+private class CodingD : NSObject, NSCoding { // expected-error{{private class 'CodingD' has an unstable name when archiving via 'NSCoding'}}
+ // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingD)}}
+ // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
// Local classes.
func someFunction() {
- class LocalCoding : NSObject, NSCoding { // expected-error{{local class 'LocalCoding' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#Objective-C class name#>)}}
- // expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiverClassName' to record the Swift 3 mangled name}}{{3-3=@NSKeyedArchiverClassName("_TtCF8nscoding12someFunctionFT_T_L_11LocalCoding")}}
+ class LocalCoding : NSObject, NSCoding { // expected-error{{local class 'LocalCoding' has an unstable name when archiving via 'NSCoding'}}
+ // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCF8nscoding12someFunctionFT_T_L_11LocalCoding)}}
+ // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
}
// Inherited conformances.
-class CodingE<T> : CodingB<T> { // expected-error{{generic class 'CodingE<T>' has an unstable name when archiving via 'NSCoding'}}
- // expected-note@-1{{generic class 'CodingE<T>' should not be archived directly}}{{1-1=@NSKeyedArchiverEncodeNonGenericSubclassesOnly}}
+// CHECK-NOT: class_decl "CodingE"{{.*}}@_staticInitializeObjCMetadata
+class CodingE<T> : CodingB<T> {
required init(coder: NSCoder) { super.init(coder: coder) }
override func encode(coder: NSCoder) { }
}
-// @NSKeyedArchiverClassName suppressions
-extension CodingA {
- @NSKeyedArchiverClassName("TheNestedE")
- class NestedE : NSObject, NSCoding {
- required init(coder: NSCoder) { }
- func encode(coder: NSCoder) { }
- }
-}
-
-@NSKeyedArchiverEncodeNonGenericSubclassesOnly
-class CodingGeneric<T> : NSObject, NSCoding {
- required init(coder: NSCoder) { }
- func encode(coder: NSCoder) { }
-}
-
-@NSKeyedArchiverClassName("TheCodingF")
+// @objc suppressions
+@objc(TheCodingF)
fileprivate class CodingF : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
-@NSKeyedArchiverClassName("TheCodingG")
+@objc(TheCodingG)
private class CodingG : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
-// Errors with @NSKeyedArchiverClassName.
-@NSKeyedArchiverClassName("TheCodingG") // expected-error{{@NSKeyedArchiverClassName may only be used on 'class' declarations}}
-struct Foo { }
-
-@NSKeyedArchiverClassName("TheCodingG") // expected-error{{'@NSKeyedArchiverClassName' cannot be applied to generic class 'Bar<T>'}}
-class Bar<T> : NSObject { }
-
extension CodingB {
- @NSKeyedArchiverClassName("GenericViaParent") // expected-error{{'@NSKeyedArchiverClassName' cannot be applied to generic class 'CodingB<T>.GenericViaParent'}}
- class GenericViaParent : NSObject { }
+ // CHECK-NOT: class_decl "GenericViaScope"{{.*}}@_staticInitializeObjCMetadata
+ @objc(GenericViaScope) // expected-error {{generic subclasses of '@objc' classes cannot have an explicit '@objc' because they are not directly visible from Objective-C}}
+ class GenericViaScope : NSObject { }
}
// Inference of @_staticInitializeObjCMetadata.
+// CHECK-NOT: class_decl "SubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
+class SubclassOfCodingA : CodingA { }
+
+// CHECK: class_decl "SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
class SubclassOfCodingE : CodingE<Int> { }
-// But don't allow one to write @_staticInitializeObjCMetadata!
+// Do not warn when simply inheriting from classes that conform to NSCoding.
+// The subclass may never be serialized. But do still infer static
+// initialization, just in case.
+// CHECK-NOT: class_decl "PrivateSubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
+private class PrivateSubclassOfCodingA : CodingA { }
+// CHECK: class_decl "PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
+private class PrivateSubclassOfCodingE : CodingE<Int> { }
+
+// But do warn when inherited through a protocol.
+protocol AlsoNSCoding : NSCoding {}
+private class CodingH : NSObject, AlsoNSCoding { // expected-error{{private class 'CodingH' has an unstable name when archiving via 'NSCoding'}}
+ // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingH)}}
+ // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
+ required init(coder: NSCoder) { }
+ func encode(coder: NSCoder) { }
+}
+
+@NSKeyedArchiverClassName( "abc" ) // expected-error {{@NSKeyedArchiverClassName has been removed; use @objc instead}} {{2-26=objc}} {{28-29=}} {{32-33=}}
+class OldArchiverAttribute: NSObject {}
+
+@NSKeyedArchiverEncodeNonGenericSubclassesOnly // expected-error {{@NSKeyedArchiverEncodeNonGenericSubclassesOnly is no longer necessary}} {{1-48=}}
+class OldArchiverAttributeGeneric<T>: NSObject {}
+
+// Don't allow one to write @_staticInitializeObjCMetadata!
@_staticInitializeObjCMetadata // expected-error{{unknown attribute '_staticInitializeObjCMetadata'}}
class DontAllowStaticInits { }
-
-// CHECK-NOT: class_decl "CodingA"{{.*}}@_staticInitializeObjCMetadata
-// CHECK: class_decl "NestedA"{{.*}}@_staticInitializeObjCMetadata
-// CHECK: class_decl "NestedC"{{.*}}@_staticInitializeObjCMetadata
-// CHECK-NOT: class_decl "NestedE"{{.*}}@_staticInitializeObjCMetadata
-// CHECK-NOT: class_decl "CodingGeneric"{{.*}}@_staticInitializeObjCMetadata
-// CHECK: class_decl "SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
\ No newline at end of file
diff --git a/test/decl/typealias/generic.swift b/test/decl/typealias/generic.swift
index 1b37520..436f00f 100644
--- a/test/decl/typealias/generic.swift
+++ b/test/decl/typealias/generic.swift
@@ -338,12 +338,64 @@
protocol P {
associatedtype A
- typealias G1<T> = MyType<Self, T>
- typealias G2<T> = MyType<T, A>
+ typealias G1<T> = MyType<Self, T> // expected-note {{did you mean 'G1'?}}
+ typealias G2<T> = MyType<T, A> // expected-note {{did you mean 'G2'?}}
+ typealias G3<T> = () -> () // expected-note {{did you mean 'G3'?}}
+ typealias G4<T> = (T) -> () // expected-note {{did you mean 'G4'?}}
+
+ func firstRequirement(_: G1<Int>)
+ func secondRequirement(_: G2<Int>)
+ func thirdRequirement(_: G3<Int>)
+ func fourthRequirement(_: G4<Int>)
+
+ func firstRequirementGeneric<T>(_: G1<T>)
+ func secondRequirementGeneric<T>(_: G2<T>)
+ func thirdRequirementGeneric<T>(_: G3<T>, _: T)
+ func fourthRequirementGeneric<T>(_: G4<T>)
}
struct S : P {
typealias A = Float
+
+ func shouldFail(fn: (Int) -> ()) {
+ thirdRequirement(fn)
+ // expected-error@-1 {{cannot convert value of type '(Int) -> ()' to expected argument type '() -> ()'}}
+ }
+
+ func firstRequirement(_: G1<Int>) {}
+ func secondRequirement(_: G2<Int>) {}
+ func thirdRequirement(_: G3<Int>) {}
+ func fourthRequirement(_: G4<Int>) {}
+
+ func firstRequirementGeneric<T>(_: G1<T>) {
+ _ = G1<T>.self // FIXME // expected-error {{use of unresolved identifier 'G1'}}
+ }
+
+ func secondRequirementGeneric<T>(_: G2<T>) {
+ _ = G2<T>.self // FIXME // expected-error {{use of unresolved identifier 'G2'}}
+ }
+
+ func thirdRequirementGeneric<T>(_: G3<T>, _: T) {
+ _ = G3<T>.self // FIXME // expected-error {{use of unresolved identifier 'G3'}}
+ }
+
+ func fourthRequirementGeneric<T>(_: G4<T>) {
+ _ = G4<T>.self // FIXME // expected-error {{use of unresolved identifier 'G4'}}
+ }
+
+ func expressionContext() {
+ let _: G1 = MyType<S, Int>(a: S(), b: 3)
+ let _: G1<Int> = MyType<S, Int>(a: S(), b: 3)
+
+ let _: S.G1 = MyType<S, Int>(a: S(), b: 3)
+ let _: S.G1<Int> = MyType<S, Int>(a: S(), b: 3)
+
+ let _: G2 = MyType<Int, Float>(a: 3, b: 1.0)
+ let _: G2<Int> = MyType<Int, Float>(a: 3, b: 1.0)
+
+ let _: S.G2 = MyType<Int, Float>(a: 3, b: 1.0)
+ let _: S.G2<Int> = MyType<Int, Float>(a: 3, b: 1.0)
+ }
}
func takesMyType(x: MyType<S, Int>) {}
diff --git a/test/decl/typealias/protocol.swift b/test/decl/typealias/protocol.swift
index 39b71c4..a6a9236 100644
--- a/test/decl/typealias/protocol.swift
+++ b/test/decl/typealias/protocol.swift
@@ -202,6 +202,8 @@
func inExpressionContext() {
_ = Y.self
+ _ = T5.T1.self
+ _ = T5.T2.self
}
}
diff --git a/test/decl/var/lazy_properties.swift b/test/decl/var/lazy_properties.swift
index e6e9eea..0964785 100644
--- a/test/decl/var/lazy_properties.swift
+++ b/test/decl/var/lazy_properties.swift
@@ -1,4 +1,3 @@
-// RUN: %target-typecheck-verify-swift -parse-as-library -swift-version 3
// RUN: %target-typecheck-verify-swift -parse-as-library -swift-version 4
lazy func lazy_func() {} // expected-error {{'lazy' may only be used on 'var' declarations}} {{1-6=}}
@@ -159,4 +158,22 @@
var i = 42
func f() -> Int { return 0 }
+
+ lazy var refBaseClassProp = baseInstanceProp
+}
+
+class ReferenceStaticInLazyProperty {
+ lazy var refs1 = i
+ // expected-error@-1 {{static member 'i' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
+ lazy var refs2 = f()
+ // expected-error@-1 {{static member 'f' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
+
+ lazy var trefs1: Int = i
+ // expected-error@-1 {{static member 'i' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
+
+ lazy var trefs2: Int = f()
+ // expected-error@-1 {{static member 'f' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
+
+ static var i = 42
+ static func f() -> Int { return 0 }
}
diff --git a/test/expr/unary/selector/selector.swift b/test/expr/unary/selector/selector.swift
index 11484d0..7eef1c0 100644
--- a/test/expr/unary/selector/selector.swift
+++ b/test/expr/unary/selector/selector.swift
@@ -134,7 +134,7 @@
}
switch optionalSel {
-case #selector(SR1827.bar): // expected-error{{expression pattern of type 'Selector' cannot match values of type 'Selector?'}} {{26-26=?}}
+case #selector(SR1827.bar): // expected-error{{expression pattern of type 'Selector' cannot match values of type 'Selector?'}} {{27-27=?}}
break
case #selector(SR1827.bar)!: // expected-error{{cannot force unwrap value of non-optional type 'Selector'}}
break
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 4197dac..8d0d927 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -175,13 +175,11 @@
class SDKContext {
llvm::StringSet<> TextData;
- std::vector<std::unique_ptr<SDKNode>> OwnedNodes;
+ llvm::BumpPtrAllocator Allocator;
public:
- SDKNode* own(SDKNode *Node) {
- assert(Node);
- OwnedNodes.emplace_back(Node);
- return Node;
+ llvm::BumpPtrAllocator &allocator() {
+ return Allocator;
}
StringRef buffer(StringRef Text) {
return TextData.insert(Text).first->getKey();
@@ -1069,15 +1067,14 @@
}
SDKNode *SDKNodeInitInfo::createSDKNode(SDKNodeKind Kind) {
- SDKNode *Result;
switch(Kind) {
#define NODE_KIND(X) \
case SDKNodeKind::X: \
- Result = static_cast<SDKNode*>(new SDKNode##X(*this)); \
+ return static_cast<SDKNode*>(new (Ctx.allocator().Allocate<SDKNode##X>()) \
+ SDKNode##X(*this)); \
break;
#include "swift/IDE/DigesterEnums.def"
}
- return Ctx.own(Result);
}
// Recursively construct a node that represents a type, for instance,
diff --git a/utils/android/build-toolchain b/utils/android/build-toolchain
new file mode 100755
index 0000000..53f44a3
--- /dev/null
+++ b/utils/android/build-toolchain
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+#
+# android/build-toolchain
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+# Licensed under Apache License v2.0 with Runtime Library Exception
+#
+# See https://swift.org/LICENSE.txt for license information
+# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+set -e
+
+cd "$(dirname $0)/../.." || exit
+SRC_DIR=$PWD
+
+ANDROID_NDK_DIR="${ANDROID_NDK_DIR:?Please set the Android NDK directory in the ANDROID_NDK_DIR environment variable}"
+ANDROID_ICU_DIR="${ANDROID_ICU_DIR:?Please set the libiconv-libicu-android directory in the ANDROID_ICU_DIR environment variable}"
+
+SWIFT_TOOLCHAIN_DIR="${SRC_DIR}/../swift-android-toolchain"
+SWIFT_LINUX_DIR="${SRC_DIR}/../build/Ninja-ReleaseAssert/swift-linux-x86_64"
+
+./utils/build-script \
+ -R \
+ --android \
+ --android-ndk "${ANDROID_NDK_DIR}" \
+ --android-api-level 21 \
+ --android-icu-uc "${ANDROID_ICU_DIR}/armeabi-v7a" \
+ --android-icu-uc-include "${ANDROID_ICU_DIR}/armeabi-v7a/icu/source/common" \
+ --android-icu-i18n "${ANDROID_ICU_DIR}/armeabi-v7a" \
+ --android-icu-i18n-include "${ANDROID_ICU_DIR}/armeabi-v7a/icu/source/i18n" || exit
+
+test -e ${SWIFT_LINUX_DIR} || exit
+rm -rf ${SWIFT_TOOLCHAIN_DIR}
+mkdir -p ${SWIFT_TOOLCHAIN_DIR}/usr
+
+cp -r ${SWIFT_LINUX_DIR}/{bin,lib,include} ${SWIFT_TOOLCHAIN_DIR}/usr
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index 355bda1..3ac8253 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -744,6 +744,25 @@
install-libdispatch
reconfigure
+# Linux package with out test
+[preset: buildbot_linux,no_test]
+mixin-preset=buildbot_linux
+
+dash-dash
+
+skip-test-cmark
+skip-test-lldb
+skip-test-swift
+skip-test-llbuild
+skip-test-swiftpm
+skip-test-xctest
+skip-test-foundation
+skip-test-libdispatch
+skip-test-playgroundlogger
+skip-test-playgroundsupport
+skip-test-libicu
+
+
# Ubuntu 16.10 preset for backwards compat and future customizations.
[preset: buildbot_linux_1610]
mixin-preset=buildbot_linux
diff --git a/utils/cmpcodesize/cmpcodesize/compare.py b/utils/cmpcodesize/cmpcodesize/compare.py
index 6a230f6..4a07a0d 100644
--- a/utils/cmpcodesize/cmpcodesize/compare.py
+++ b/utils/cmpcodesize/cmpcodesize/compare.py
@@ -32,7 +32,8 @@
# Function signature specialization of a generic specialization.
["FuncSigGen Spec", re.compile(
'^__(TTSf.*__TTSg|T0.*T[gGpP]q?[0-9].*Tfq?[0-9])')],
- ["Generic Spec", re.compile('^__(TTSg|T0.*T[gGpP]q?[0-9])')],
+ ["Generic Spec", re.compile('^__(TTSg|T0.*T[gG]q?[0-9])')],
+ ["Partial Spec", re.compile('^__(T0.*T[pP]q?[0-9])')],
["FuncSig Spec", re.compile('^__(TTSf|T0.*Tfq?[0-9])')],
["Generic Function", re.compile(
'__(T[^0].*q(x|d?[0-9]*_)|T0.*q(z|d?[0-9]*_))')],
@@ -151,17 +152,26 @@
add_function(sizes, curr_func, start_addr, end_addr, group_by_prefix)
-def compare_sizes(old_sizes, new_sizes, name_key, title):
+def compare_sizes(old_sizes, new_sizes, name_key, title, total_size_key=""):
old_size = old_sizes[name_key]
new_size = new_sizes[name_key]
+ if total_size_key:
+ old_total_size = old_sizes[total_size_key]
+ new_total_size = new_sizes[total_size_key]
if old_size is not None and new_size is not None:
if old_size != 0:
perc = "%.1f%%" % (
(1.0 - float(new_size) / float(old_size)) * 100.0)
else:
perc = "- "
- print("%-26s%16s: %8d %8d %6s" %
- (title, name_key, old_size, new_size, perc))
+ if total_size_key:
+ print("%-26s%16s: %8d (%2d%%) %8d (%2d%%) %7s" %
+ (title, name_key, old_size,
+ old_size * 100.0 / old_total_size,
+ new_size, new_size * 100.0 / new_total_size, perc))
+ else:
+ print("%-26s%16s: %14d %14d %7s" %
+ (title, name_key, old_size, new_size, perc))
def compare_sizes_of_file(old_files, new_files, all_sections, list_categories):
@@ -181,11 +191,11 @@
else:
title = "old-new"
- compare_sizes(old_sizes, new_sizes, "__text", title)
+ compare_sizes(old_sizes, new_sizes, "__text", title, "")
if list_categories:
for cat in categories:
cat_name = cat[0]
- compare_sizes(old_sizes, new_sizes, cat_name, "")
+ compare_sizes(old_sizes, new_sizes, cat_name, "", "__text")
if all_sections:
section_title = " section"
diff --git a/utils/cmpcodesize/cmpcodesize/main.py b/utils/cmpcodesize/cmpcodesize/main.py
index b112a04..3f02353 100644
--- a/utils/cmpcodesize/cmpcodesize/main.py
+++ b/utils/cmpcodesize/cmpcodesize/main.py
@@ -183,7 +183,7 @@
else:
compare_function_sizes(old_files, new_files)
else:
- print("%-26s%16s %8s %8s %s" %
+ print("%-26s%16s %14s %14s %s" %
("", "Section", "Old", "New", "Percent"))
if parsed_arguments.sum_sizes:
compare_sizes_of_file(old_files, new_files,
diff --git a/utils/symbolicate-linux-fatal b/utils/symbolicate-linux-fatal
index 81d403f..e6592b6 100755
--- a/utils/symbolicate-linux-fatal
+++ b/utils/symbolicate-linux-fatal
@@ -28,7 +28,17 @@
import os
import subprocess
-import lldb
+try:
+ import lldb
+except ImportError:
+ from distutils import spawn
+ swift_exec = spawn.find_executable('swift')
+ if swift_exec is not None:
+ site_packages = os.path.join(os.path.dirname(swift_exec),
+ '../lib/python2.7/site-packages/')
+ import sys
+ sys.path.append(site_packages)
+ import lldb
def process_ldd(lddoutput):
@@ -38,7 +48,7 @@
if len(ldd_tokens) >= 2:
lib = ldd_tokens[-2]
dyn_libs[ldd_tokens[0]] = lib
- real_name = os.path.basename(os.path.realpath(lib))
+ real_name = os.path.basename(os.path.realpath(lib))
dyn_libs[real_name] = lib
return dyn_libs
@@ -58,7 +68,19 @@
return lldb_target
+def add_lldb_target_modules(lldb_target, memmap):
+ for dynlib_path in memmap:
+ module = lldb_target.AddModule(
+ dynlib_path, lldb.LLDB_ARCH_DEFAULT, None, None)
+ lldb_target.SetModuleLoadAddress(module, memmap[dynlib_path])
+
+lldb_target = None
+known_memmap = {}
+
+
def process_stack(binary, dyn_libs, stack):
+ global lldb_target
+ global known_memmap
if len(stack) == 0:
return
memmap = {}
@@ -77,21 +99,29 @@
framePC = int(stack_tokens[2], 16)
symbol_offset = int(stack_tokens[-1], 10)
dynlib_baseaddr = framePC - symbol_offset
- if dynlib_path in memmap:
- if memmap[dynlib_path] != dynlib_baseaddr:
+ if dynlib_path in memmap or dynlib_path in known_memmap:
+ if dynlib_path in memmap:
+ existing_baseaddr = memmap[dynlib_path]
+ else:
+ existing_baseaddr = known_memmap[dynlib_path]
+ if existing_baseaddr != dynlib_baseaddr:
error_msg = "Mismatched base address for: {0:s}, " \
"had: {1:x}, now got {2:x}"
error_msg = error_msg.format(
- dynlib_path, memmap[dynlib_path], dynlib_baseaddr)
+ dynlib_path, existing_baseaddr, dynlib_baseaddr)
raise Exception(error_msg)
else:
+ known_memmap[dynlib_path] = dynlib_baseaddr
memmap[dynlib_path] = dynlib_baseaddr
else:
framePC = int(stack_tokens[2], 16) + int(stack_tokens[-1], 10)
full_stack.append(
{"line": line, "framePC": framePC, "dynlib_fname": dynlib_fname})
- lldb_target = create_lldb_target(binary, memmap)
+ if lldb_target is None:
+ lldb_target = create_lldb_target(binary, memmap)
+ else:
+ add_lldb_target_modules(lldb_target, memmap)
frame_idx = 0
for frame in full_stack:
use_orig_line = True
@@ -130,8 +160,8 @@
parser.add_argument(
"binary", help="Executable which produced the log file")
parser.add_argument(
- "log", type=argparse.FileType("rU"),
- help="Log file containing the stack trace to symbolicate")
+ "log", nargs='?', type=argparse.FileType("rU"), default="-",
+ help="Log file for symbolication. Defaults to stdin.")
args = parser.parse_args()
binary = args.binary
diff --git a/validation-test/compiler_crashers/28752-hasinterfacetype-no-interface-type-was-set.swift b/validation-test/compiler_crashers/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
similarity index 80%
copy from validation-test/compiler_crashers/28752-hasinterfacetype-no-interface-type-was-set.swift
copy to validation-test/compiler_crashers/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
index 10271f6..81e2b26 100644
--- a/validation-test/compiler_crashers/28752-hasinterfacetype-no-interface-type-was-set.swift
+++ b/validation-test/compiler_crashers/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
@@ -7,4 +7,4 @@
// REQUIRES: asserts
// RUN: not --crash %target-swift-frontend %s -emit-ir
-@objc protocol P{typealias e:P{}var a}{}extension P{typealias e:P
+protocol P{{}func a{}typealias e}struct A:P{typealias e:Self.a{}typealias e:Self.a{}typealias e:P
diff --git a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift b/validation-test/compiler_crashers/28770-selfty-isequal-proto-getselfinterfacetype.swift
similarity index 88%
rename from validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
rename to validation-test/compiler_crashers/28770-selfty-isequal-proto-getselfinterfacetype.swift
index 66e67fc..2cf5925 100644
--- a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
+++ b/validation-test/compiler_crashers/28770-selfty-isequal-proto-getselfinterfacetype.swift
@@ -7,4 +7,4 @@
// REQUIRES: asserts
// RUN: not --crash %target-swift-frontend %s -emit-ir
-protocol A:A{{}class a{let ca{a{
+protocol P{protocol b:P{{}typealias e:a.a}typealias a
diff --git a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift b/validation-test/compiler_crashers/28771-unreachable-executed-at-swift-include-swift-ast-cantypevisitor-h-41.swift
similarity index 85%
copy from validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
copy to validation-test/compiler_crashers/28771-unreachable-executed-at-swift-include-swift-ast-cantypevisitor-h-41.swift
index 66e67fc..effc4cd 100644
--- a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
+++ b/validation-test/compiler_crashers/28771-unreachable-executed-at-swift-include-swift-ast-cantypevisitor-h-41.swift
@@ -5,6 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// REQUIRES: asserts
// RUN: not --crash %target-swift-frontend %s -emit-ir
-protocol A:A{{}class a{let ca{a{
+protocol A{typealias a{}typealias a=FlattenCollection}protocol b:A
diff --git a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift b/validation-test/compiler_crashers/28774-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
similarity index 87%
copy from validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
copy to validation-test/compiler_crashers/28774-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
index 66e67fc..f408747 100644
--- a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
+++ b/validation-test/compiler_crashers/28774-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
@@ -5,6 +5,6 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// REQUIRES: asserts
// RUN: not --crash %target-swift-frontend %s -emit-ir
-protocol A:A{{}class a{let ca{a{
+protocol P{typealias e:P.e
+protocol P{typealias e:Self
diff --git a/validation-test/compiler_crashers_2_fixed/0105-sr1261.swift b/validation-test/compiler_crashers_2_fixed/0105-sr1261.swift
new file mode 100644
index 0000000..9870be7
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0105-sr1261.swift
@@ -0,0 +1,26 @@
+// RUN: %target-swift-frontend %s -emit-ir
+
+class Expression<A, R> {
+ typealias Arg = A
+ typealias Ret = R
+ subscript(x: Arg) -> Ret! { return nil }
+}
+class Op<A, R> : Expression<A, R> {
+ typealias OpType = (Arg) -> Ret
+ let op: OpType
+ init(op: @escaping OpType) {
+ self.op = op
+ super.init()
+ }
+}
+
+class BinaryOp<A1, A2, R> : Op<((A1, A2)), R> {
+ override init(op: @escaping OpType) {
+ super.init(op: op)
+ }
+ override subscript(x: Arg) -> Ret! {
+ return op(x)
+ }
+}
+let add = BinaryOp<Int, Int, Int> { return $0.0 + $0.1 }
+print(add[(1,1)])
diff --git a/validation-test/compiler_crashers/28728-d-isbeingvalidated-d-hasvalidsignature.swift b/validation-test/compiler_crashers_fixed/28728-d-isbeingvalidated-d-hasvalidsignature.swift
similarity index 87%
rename from validation-test/compiler_crashers/28728-d-isbeingvalidated-d-hasvalidsignature.swift
rename to validation-test/compiler_crashers_fixed/28728-d-isbeingvalidated-d-hasvalidsignature.swift
index 57e4115..8f0ba7d 100644
--- a/validation-test/compiler_crashers/28728-d-isbeingvalidated-d-hasvalidsignature.swift
+++ b/validation-test/compiler_crashers_fixed/28728-d-isbeingvalidated-d-hasvalidsignature.swift
@@ -6,6 +6,6 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
typealias e:a
struct A:a{}typealias a=A
diff --git a/validation-test/compiler_crashers/28733-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift b/validation-test/compiler_crashers_fixed/28733-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
similarity index 87%
rename from validation-test/compiler_crashers/28733-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
rename to validation-test/compiler_crashers_fixed/28733-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
index 9482b4a..9b66b76 100644
--- a/validation-test/compiler_crashers/28733-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
+++ b/validation-test/compiler_crashers_fixed/28733-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{class a:Self.a
diff --git a/validation-test/compiler_crashers/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift b/validation-test/compiler_crashers_fixed/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
similarity index 87%
rename from validation-test/compiler_crashers/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
rename to validation-test/compiler_crashers_fixed/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
index 4319075..0242964 100644
--- a/validation-test/compiler_crashers/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
+++ b/validation-test/compiler_crashers_fixed/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{{}typealias a:=A.a:struct A:P
diff --git a/validation-test/compiler_crashers/28743-swift-typechecker-substmembertypewithbase-swift-moduledecl-swift-typedecl-swift-.swift b/validation-test/compiler_crashers_fixed/28743-swift-typechecker-substmembertypewithbase-swift-moduledecl-swift-typedecl-swift-.swift
similarity index 87%
rename from validation-test/compiler_crashers/28743-swift-typechecker-substmembertypewithbase-swift-moduledecl-swift-typedecl-swift-.swift
rename to validation-test/compiler_crashers_fixed/28743-swift-typechecker-substmembertypewithbase-swift-moduledecl-swift-typedecl-swift-.swift
index fd6d161..0b92258 100644
--- a/validation-test/compiler_crashers/28743-swift-typechecker-substmembertypewithbase-swift-moduledecl-swift-typedecl-swift-.swift
+++ b/validation-test/compiler_crashers_fixed/28743-swift-typechecker-substmembertypewithbase-swift-moduledecl-swift-typedecl-swift-.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P}extension P{typealias a:Self.a{}func a:Self.a
diff --git a/validation-test/compiler_crashers/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift b/validation-test/compiler_crashers_fixed/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
similarity index 87%
rename from validation-test/compiler_crashers/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
rename to validation-test/compiler_crashers_fixed/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
index 7461adb..f9d112f 100644
--- a/validation-test/compiler_crashers/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
+++ b/validation-test/compiler_crashers_fixed/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
&{LazyFilterIndex{
diff --git a/validation-test/compiler_crashers/28748-genericenv-nullptr-too-much-circularity.swift b/validation-test/compiler_crashers_fixed/28748-genericenv-nullptr-too-much-circularity.swift
similarity index 88%
rename from validation-test/compiler_crashers/28748-genericenv-nullptr-too-much-circularity.swift
rename to validation-test/compiler_crashers_fixed/28748-genericenv-nullptr-too-much-circularity.swift
index 7dd56b9..8d68e87 100644
--- a/validation-test/compiler_crashers/28748-genericenv-nullptr-too-much-circularity.swift
+++ b/validation-test/compiler_crashers_fixed/28748-genericenv-nullptr-too-much-circularity.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol A:a{{}typealias e:a}{}class a:A{typealias e:b
diff --git a/validation-test/compiler_crashers/28751-membertype-missing-type-witness.swift b/validation-test/compiler_crashers_fixed/28751-membertype-missing-type-witness.swift
similarity index 88%
rename from validation-test/compiler_crashers/28751-membertype-missing-type-witness.swift
rename to validation-test/compiler_crashers_fixed/28751-membertype-missing-type-witness.swift
index dbf30be..da91b69 100644
--- a/validation-test/compiler_crashers/28751-membertype-missing-type-witness.swift
+++ b/validation-test/compiler_crashers_fixed/28751-membertype-missing-type-witness.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
{class a:P{{}typealias a:Self.a}protocol P{typealias a
diff --git a/validation-test/compiler_crashers/28752-hasinterfacetype-no-interface-type-was-set.swift b/validation-test/compiler_crashers_fixed/28752-hasinterfacetype-no-interface-type-was-set.swift
similarity index 88%
rename from validation-test/compiler_crashers/28752-hasinterfacetype-no-interface-type-was-set.swift
rename to validation-test/compiler_crashers_fixed/28752-hasinterfacetype-no-interface-type-was-set.swift
index 10271f6..675bf9e 100644
--- a/validation-test/compiler_crashers/28752-hasinterfacetype-no-interface-type-was-set.swift
+++ b/validation-test/compiler_crashers_fixed/28752-hasinterfacetype-no-interface-type-was-set.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
@objc protocol P{typealias e:P{}var a}{}extension P{typealias e:P
diff --git a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift b/validation-test/compiler_crashers_fixed/28753-conforms-equivclass-conformsto-end.swift
similarity index 87%
copy from validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
copy to validation-test/compiler_crashers_fixed/28753-conforms-equivclass-conformsto-end.swift
index 66e67fc..f14b655 100644
--- a/validation-test/compiler_crashers/28753-conforms-equivclass-conformsto-end.swift
+++ b/validation-test/compiler_crashers_fixed/28753-conforms-equivclass-conformsto-end.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol A:A{{}class a{let ca{a{
diff --git a/validation-test/compiler_crashers/28762-valuetype-hasunboundgenerictype-valuetype-hastypeparameter.swift b/validation-test/compiler_crashers_fixed/28762-valuetype-hasunboundgenerictype-valuetype-hastypeparameter.swift
similarity index 87%
rename from validation-test/compiler_crashers/28762-valuetype-hasunboundgenerictype-valuetype-hastypeparameter.swift
rename to validation-test/compiler_crashers_fixed/28762-valuetype-hasunboundgenerictype-valuetype-hastypeparameter.swift
index 5f1c5d6..963d2de 100644
--- a/validation-test/compiler_crashers/28762-valuetype-hasunboundgenerictype-valuetype-hastypeparameter.swift
+++ b/validation-test/compiler_crashers_fixed/28762-valuetype-hasunboundgenerictype-valuetype-hastypeparameter.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
guard let f==A:UnfoldSequence
diff --git a/validation-test/compiler_crashers/28763-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/28763-swift-typebase-getcanonicaltype.swift
similarity index 87%
rename from validation-test/compiler_crashers/28763-swift-typebase-getcanonicaltype.swift
rename to validation-test/compiler_crashers_fixed/28763-swift-typebase-getcanonicaltype.swift
index 36aa305..1f1e769 100644
--- a/validation-test/compiler_crashers/28763-swift-typebase-getcanonicaltype.swift
+++ b/validation-test/compiler_crashers_fixed/28763-swift-typebase-getcanonicaltype.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{func a}extension P{lazy var f=a
diff --git a/validation-test/compiler_crashers/28765-inprotocol-isrequirementsignaturecomputed-missing-signature.swift b/validation-test/compiler_crashers_fixed/28765-inprotocol-isrequirementsignaturecomputed-missing-signature.swift
similarity index 88%
rename from validation-test/compiler_crashers/28765-inprotocol-isrequirementsignaturecomputed-missing-signature.swift
rename to validation-test/compiler_crashers_fixed/28765-inprotocol-isrequirementsignaturecomputed-missing-signature.swift
index 8cc3798..a50bb7f 100644
--- a/validation-test/compiler_crashers/28765-inprotocol-isrequirementsignaturecomputed-missing-signature.swift
+++ b/validation-test/compiler_crashers_fixed/28765-inprotocol-isrequirementsignaturecomputed-missing-signature.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{{}class a:A{}protocol A:P.a{typealias a{}func a:a
diff --git a/validation-test/compiler_crashers/28767-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift b/validation-test/compiler_crashers_fixed/28767-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
similarity index 88%
rename from validation-test/compiler_crashers/28767-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
rename to validation-test/compiler_crashers_fixed/28767-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
index 8d37713..5eba003 100644
--- a/validation-test/compiler_crashers/28767-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
+++ b/validation-test/compiler_crashers_fixed/28767-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
@objc protocol P{struct B{var f=_=a{}}class a{}typealias a
diff --git a/validation-test/compiler_crashers/28768-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift b/validation-test/compiler_crashers_fixed/28768-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
similarity index 87%
rename from validation-test/compiler_crashers/28768-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
rename to validation-test/compiler_crashers_fixed/28768-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
index 5a8b2cc..5b4f0e4 100644
--- a/validation-test/compiler_crashers/28768-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
+++ b/validation-test/compiler_crashers_fixed/28768-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
@@ -6,6 +6,6 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
Indexable
& ManagedBuffer
diff --git a/validation-test/compiler_crashers/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift b/validation-test/compiler_crashers_fixed/28772-loc-isvalid-diagnosing-attribute-with-invalid-location.swift
similarity index 82%
copy from validation-test/compiler_crashers/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
copy to validation-test/compiler_crashers_fixed/28772-loc-isvalid-diagnosing-attribute-with-invalid-location.swift
index 7461adb..615f29c 100644
--- a/validation-test/compiler_crashers/28745-ty-getnominalorboundgenericnominal-ty-is-dynamicselftype-ty-isexistentialtype-ty.swift
+++ b/validation-test/compiler_crashers_fixed/28772-loc-isvalid-diagnosing-attribute-with-invalid-location.swift
@@ -6,5 +6,6 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-&{LazyFilterIndex{
+// RUN: not %target-swift-frontend %s -emit-ir
+class a{@objc@dynamic
+let d
diff --git a/validation-test/compiler_crashers/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift b/validation-test/compiler_crashers_fixed/28773-unreachable-executed-at-swift-lib-sema-cssimplify-cpp-4808.swift
similarity index 77%
copy from validation-test/compiler_crashers/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
copy to validation-test/compiler_crashers_fixed/28773-unreachable-executed-at-swift-lib-sema-cssimplify-cpp-4808.swift
index 4319075..8e53a26 100644
--- a/validation-test/compiler_crashers/28742-swift-type-subst-llvm-function-ref-swift-type-swift-substitutabletype-llvm-funct.swift
+++ b/validation-test/compiler_crashers_fixed/28773-unreachable-executed-at-swift-lib-sema-cssimplify-cpp-4808.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-protocol P{{}typealias a:=A.a:struct A:P
+// RUN: not %target-swift-frontend %s -emit-ir
+@objc protocol P{{}typealias a{}class a{let c=a{
diff --git a/validation-test/stdlib/Dictionary.swift b/validation-test/stdlib/Dictionary.swift
index 3ea23fd..0e93771 100644
--- a/validation-test/stdlib/Dictionary.swift
+++ b/validation-test/stdlib/Dictionary.swift
@@ -477,7 +477,7 @@
}
}
-DictionaryTestSuite.test("COW.Fast.MergeDoesNotReallocate") {
+DictionaryTestSuite.test("COW.Fast.MergeSequenceDoesNotReallocate") {
do {
var d1 = getCOWFastDictionary()
var identity1 = d1._rawIdentifier()
@@ -501,6 +501,13 @@
assert(d1.count == 7)
assert(d1[30]! == 1030)
assert(d1[70]! == 2070)
+
+ let d2 = d1.merging([(40, 3040), (80, 3080)]) { _, y in y }
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 != d2._rawIdentifier())
+ assert(d2.count == 8)
+ assert(d2[40]! == 3040)
+ assert(d2[80]! == 3080)
}
do {
@@ -591,6 +598,127 @@
}
}
+DictionaryTestSuite.test("COW.Fast.MergeDictionaryDoesNotReallocate") {
+ do {
+ var d1 = getCOWFastDictionary()
+ var identity1 = d1._rawIdentifier()
+
+ // Merge some new values.
+ d1.merge([40: 2040, 50: 2050]) { _, y in y }
+ assert(identity1 == d1._rawIdentifier())
+ assert(d1.count == 5)
+ assert(d1[50]! == 2050)
+
+ // Merge and overwrite some existing values.
+ d1.merge([10: 2010, 60: 2060]) { _, y in y }
+ assert(identity1 == d1._rawIdentifier())
+ assert(d1.count == 6)
+ assert(d1[10]! == 2010)
+ assert(d1[60]! == 2060)
+
+ // Merge, keeping existing values.
+ d1.merge([30: 2030, 70: 2070]) { x, _ in x }
+ assert(identity1 == d1._rawIdentifier())
+ assert(d1.count == 7)
+ assert(d1[30]! == 1030)
+ assert(d1[70]! == 2070)
+
+ let d2 = d1.merging([40: 3040, 80: 3080]) { _, y in y }
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 != d2._rawIdentifier())
+ assert(d2.count == 8)
+ assert(d2[40]! == 3040)
+ assert(d2[80]! == 3080)
+ }
+
+ do {
+ var d1 = getCOWFastDictionary()
+ var identity1 = d1._rawIdentifier()
+
+ var d2 = d1
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 == d2._rawIdentifier())
+
+ // Merge some new values.
+ d2.merge([40: 2040, 50: 2050]) { _, y in y }
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 != d2._rawIdentifier())
+
+ assert(d1.count == 3)
+ assert(d1[10]! == 1010)
+ assert(d1[20]! == 1020)
+ assert(d1[30]! == 1030)
+ assert(d1[40] == nil)
+
+ assert(d2.count == 5)
+ assert(d2[10]! == 1010)
+ assert(d2[20]! == 1020)
+ assert(d2[30]! == 1030)
+ assert(d2[40]! == 2040)
+ assert(d2[50]! == 2050)
+
+ // Keep variables alive.
+ _fixLifetime(d1)
+ _fixLifetime(d2)
+ }
+
+ do {
+ var d1 = getCOWFastDictionary()
+ var identity1 = d1._rawIdentifier()
+
+ var d2 = d1
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 == d2._rawIdentifier())
+
+ // Merge and overwrite some existing values.
+ d2.merge([10: 2010]) { _, y in y }
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 != d2._rawIdentifier())
+
+ assert(d1.count == 3)
+ assert(d1[10]! == 1010)
+ assert(d1[20]! == 1020)
+ assert(d1[30]! == 1030)
+
+ assert(d2.count == 3)
+ assert(d2[10]! == 2010)
+ assert(d2[20]! == 1020)
+ assert(d2[30]! == 1030)
+
+ // Keep variables alive.
+ _fixLifetime(d1)
+ _fixLifetime(d2)
+ }
+
+ do {
+ var d1 = getCOWFastDictionary()
+ var identity1 = d1._rawIdentifier()
+
+ var d2 = d1
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 == d2._rawIdentifier())
+
+ // Merge, keeping existing values.
+ d2.merge([10: 2010]) { x, _ in x }
+ assert(identity1 == d1._rawIdentifier())
+ assert(identity1 != d2._rawIdentifier())
+
+ assert(d1.count == 3)
+ assert(d1[10]! == 1010)
+ assert(d1[20]! == 1020)
+ assert(d1[30]! == 1030)
+
+ assert(d2.count == 3)
+ assert(d2[10]! == 1010)
+ assert(d2[20]! == 1020)
+ assert(d2[30]! == 1030)
+
+ // Keep variables alive.
+ _fixLifetime(d1)
+ _fixLifetime(d2)
+ }
+}
+
DictionaryTestSuite.test("COW.Fast.DefaultedSubscriptDoesNotReallocate") {
do {
var d1 = getCOWFastDictionary()