Merge pull request #17729 from DougGregor/minimize-override-checking
[Type checker] Minimize checking needed to compute the set of overridden declarations
diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h
index 0b918ff..95d842a 100644
--- a/include/swift/AST/ASTScope.h
+++ b/include/swift/AST/ASTScope.h
@@ -489,11 +489,14 @@
/// introduced by this statement.
static ASTScope *createIfNeeded(const ASTScope *parent, Stmt *stmt);
- /// Create a new AST scope if one is needed for the given expression.
+ /// Create a new AST scope if one is needed for the given child expression(s).
+ /// In the first variant, the expression can be \c null.
///
/// \returns the newly-created AST scope, or \c null if there is no scope
/// introduced by this expression.
- static ASTScope *createIfNeeded(const ASTScope *parent, Expr *Expr);
+ static ASTScope *createIfNeeded(const ASTScope *parent, Expr *expr);
+ static ASTScope *createIfNeeded(const ASTScope *parent,
+ ArrayRef<Expr *> exprs);
/// Create a new AST scope if one is needed for the given AST node.
///
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 2edbebf..e33843d 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -4134,6 +4134,9 @@
/// is a member. Currently only variables can be static.
inline bool isStatic() const; // defined in this header
+ /// \brief Return the interface type of the stored value.
+ Type getValueInterfaceType() const;
+
/// \brief Determine how this storage is implemented.
StorageImplInfo getImplInfo() const {
if (auto ptr = Accessors.getPointer())
diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def
index ddaaa02..37cc113 100644
--- a/include/swift/AST/DiagnosticsDriver.def
+++ b/include/swift/AST/DiagnosticsDriver.def
@@ -155,10 +155,6 @@
"the option '-driver-use-filelists' is deprecated; use "
"'-driver-filelist-threshold=0' instead", ())
-WARNING(warn_emit_public_type_metadata_accessors_deprecated, none,
- "the option '-emit-public-type-metadata-accessors' is no longer "
- "needed and is deprecated; consider removing it", ())
-
ERROR(cannot_find_migration_script, none,
"missing migration script from path '%0'", (StringRef))
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 8e2a5b9..1f76292 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -686,8 +686,8 @@
ERROR(use_unresolved_identifier,none,
"use of unresolved %select{identifier|operator}1 %0", (DeclName, bool))
ERROR(use_unresolved_identifier_corrected,none,
- "use of unresolved %select{identifier|operator}1 %0; did you mean %2?",
- (DeclName, bool, DeclName))
+ "use of unresolved %select{identifier|operator}1 %0; did you mean '%2'?",
+ (DeclName, bool, StringRef))
NOTE(confusable_character,none,
"%select{identifier|operator}0 '%1' contains possibly confused characters; "
"did you mean to use '%2'?",
diff --git a/include/swift/AST/ExistentialLayout.h b/include/swift/AST/ExistentialLayout.h
index 7610fcc..3126fd4 100644
--- a/include/swift/AST/ExistentialLayout.h
+++ b/include/swift/AST/ExistentialLayout.h
@@ -37,8 +37,8 @@
ExistentialLayout(ProtocolType *type);
ExistentialLayout(ProtocolCompositionType *type);
- /// The superclass constraint, if any.
- Type superclass;
+ /// The explicit superclass constraint, if any.
+ Type explicitSuperclass;
/// Whether the existential contains an explicit '& AnyObject' constraint.
bool hasExplicitAnyObject : 1;
@@ -50,7 +50,9 @@
bool isObjC() const {
// FIXME: Does the superclass have to be @objc?
- return ((superclass || hasExplicitAnyObject || !getProtocols().empty()) &&
+ return ((explicitSuperclass ||
+ hasExplicitAnyObject ||
+ !getProtocols().empty()) &&
!containsNonObjCProtocol);
}
@@ -58,11 +60,16 @@
/// '& AnyObject' member or because of a superclass or protocol constraint.
bool requiresClass() const;
- // Does this existential contain the Error protocol?
+ /// Returns the existential's superclass, if any; this is either an explicit
+ /// superclass term in a composition type, or the superclass of one of the
+ /// protocols.
+ Type getSuperclass() const;
+
+ /// Does this existential contain the Error protocol?
bool isExistentialWithError(ASTContext &ctx) const;
- // Does this existential consist of an Error protocol only with no other
- // constraints?
+ /// Does this existential consist of an Error protocol only with no other
+ /// constraints?
bool isErrorExistential() const;
static inline ProtocolType *getProtocolType(const Type &Ty) {
diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h
index 1ae9020..0f665db 100644
--- a/include/swift/AST/Module.h
+++ b/include/swift/AST/Module.h
@@ -151,7 +151,7 @@
};
private:
- /// If non-NULL, an plug-in that should be used when performing external
+ /// If non-NULL, a plug-in that should be used when performing external
/// lookups.
// FIXME: Do we really need to bloat all modules with this?
DebuggerClient *DebugClient = nullptr;
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 7bb1322..2238b0a 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -358,11 +358,6 @@
Alias<warn_swift3_objc_inference_complete>,
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, HelpHidden]>;
-def emit_public_type_metadata_accessors :
- Flag<["-"], "emit-public-type-metadata-accessors">,
- Flags<[FrontendOption]>,
- HelpText<"Emit all type metadata accessors as public (deprecated: now does nothing)">;
-
def Rpass_EQ : Joined<["-"], "Rpass=">,
Flags<[FrontendOption]>,
HelpText<"Report performed transformations by optimization passes whose "
diff --git a/include/swift/Runtime/Config.h b/include/swift/Runtime/Config.h
index 2113157..dd83b7c 100644
--- a/include/swift/Runtime/Config.h
+++ b/include/swift/Runtime/Config.h
@@ -17,8 +17,79 @@
#ifndef SWIFT_RUNTIME_CONFIG_H
#define SWIFT_RUNTIME_CONFIG_H
-// Bring in visibility attribute macros for library visibility.
-#include "llvm/Support/Compiler.h"
+/// \macro SWIFT_RUNTIME_GNUC_PREREQ
+/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
+/// available.
+#ifndef SWIFT_RUNTIME_GNUC_PREREQ
+# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define SWIFT_RUNTIME_GNUC_PREREQ(maj, min, patch) \
+ ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
+ ((maj) << 20) + ((min) << 10) + (patch))
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define SWIFT_RUNTIME_GNUC_PREREQ(maj, min, patch) \
+ ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
+# else
+# define SWIFT_RUNTIME_GNUC_PREREQ(maj, min, patch) 0
+# endif
+#endif
+
+/// SWIFT_RUNTIME_LIBRARY_VISIBILITY - If a class marked with this attribute is
+/// linked into a shared library, then the class should be private to the
+/// library and not accessible from outside it. Can also be used to mark
+/// variables and functions, making them private to any shared library they are
+/// linked into.
+/// On PE/COFF targets, library visibility is the default, so this isn't needed.
+#if (__has_attribute(visibility) || SWIFT_RUNTIME_GNUC_PREREQ(4, 0, 0)) && \
+ !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32)
+#define SWIFT_RUNTIME_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
+#else
+#define SWIFT_RUNTIME_LIBRARY_VISIBILITY
+#endif
+
+/// Attributes.
+/// SWIFT_RUNTIME_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
+/// mark a method "not for inlining".
+#if __has_attribute(noinline) || SWIFT_RUNTIME_GNUC_PREREQ(3, 4, 0)
+#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER)
+#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE __declspec(noinline)
+#else
+#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
+#endif
+
+/// SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
+/// so, mark a method "always inline" because it is performance sensitive. GCC
+/// 3.4 supported this but is buggy in various cases and produces unimplemented
+/// errors, just use it in GCC 4.0 and later.
+#if __has_attribute(always_inline) || SWIFT_RUNTIME_GNUC_PREREQ(4, 0, 0)
+#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
+#elif defined(_MSC_VER)
+#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE __forceinline
+#else
+#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+#ifdef __GNUC__
+#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN __declspec(noreturn)
+#else
+#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN
+#endif
+
+/// SWIFT_RUNTIME_BUILTIN_TRAP - On compilers which support it, expands to an expression
+/// which causes the program to exit abnormally.
+#if __has_builtin(__builtin_trap) || SWIFT_RUNTIME_GNUC_PREREQ(4, 3, 0)
+# define SWIFT_RUNTIME_BUILTIN_TRAP __builtin_trap()
+#elif defined(_MSC_VER)
+// The __debugbreak intrinsic is supported by MSVC, does not require forward
+// declarations involving platform-specific typedefs (unlike RaiseException),
+// results in a call to vectored exception handlers, and encodes to a short
+// instruction that still causes the trapping behavior we want.
+# define SWIFT_RUNTIME_BUILTIN_TRAP __debugbreak()
+#else
+# define SWIFT_RUNTIME_BUILTIN_TRAP *(volatile int*)0x11 = 0
+#endif
/// Does the current Swift platform support "unbridged" interoperation
/// with Objective-C? If so, the implementations of various types must
diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h
index 0ecc8f8..9c5de7b 100644
--- a/include/swift/Runtime/Debug.h
+++ b/include/swift/Runtime/Debug.h
@@ -17,7 +17,6 @@
#ifndef _SWIFT_RUNTIME_DEBUG_HELPERS_
#define _SWIFT_RUNTIME_DEBUG_HELPERS_
-#include <llvm/Support/Compiler.h>
#include <cstdarg>
#include <cstdio>
#include <stdint.h>
@@ -41,23 +40,23 @@
};
extern "C" {
-LLVM_LIBRARY_VISIBILITY
+SWIFT_RUNTIME_LIBRARY_VISIBILITY
extern struct crashreporter_annotations_t gCRAnnotations;
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
static inline void CRSetCrashLogMessage(const char *message) {
gCRAnnotations.message = reinterpret_cast<uint64_t>(message);
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
static inline const char *CRGetCrashLogMessage() {
return reinterpret_cast<const char *>(gCRAnnotations.message);
}
#else
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
static inline void CRSetCrashLogMessage(const char *) {}
#endif
@@ -73,18 +72,18 @@
// swift::crash() halts with a crash log message,
// but otherwise tries not to disturb register state.
-LLVM_ATTRIBUTE_NORETURN
-LLVM_ATTRIBUTE_ALWAYS_INLINE // Minimize trashed registers
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE // Minimize trashed registers
static inline void crash(const char *message) {
CRSetCrashLogMessage(message);
- LLVM_BUILTIN_TRAP;
+ SWIFT_RUNTIME_BUILTIN_TRAP;
swift_runtime_unreachable("Expected compiler to crash.");
}
// swift::fatalError() halts with a crash log message,
// but makes no attempt to preserve register state.
-LLVM_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
extern void
fatalError(uint32_t flags, const char *format, ...);
@@ -94,7 +93,7 @@
// swift_dynamicCastFailure halts using fatalError()
// with a description of a failed cast's types.
-LLVM_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
void
swift_dynamicCastFailure(const Metadata *sourceType,
const Metadata *targetType,
@@ -102,7 +101,7 @@
// swift_dynamicCastFailure halts using fatalError()
// with a description of a failed cast's types.
-LLVM_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
void
swift_dynamicCastFailure(const void *sourceType, const char *sourceName,
const void *targetType, const char *targetName,
@@ -112,19 +111,19 @@
void swift_reportError(uint32_t flags, const char *message);
// Halt due to an overflow in swift_retain().
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
void swift_abortRetainOverflow();
// Halt due to reading an unowned reference to a dead object.
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
void swift_abortRetainUnowned(const void *object);
// Halt due to an overflow in swift_unownedRetain().
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
void swift_abortUnownedRetainOverflow();
// Halt due to an overflow in incrementWeak().
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
void swift_abortWeakRetainOverflow();
/// This function dumps one line of a stack trace. It is assumed that \p framePC
@@ -134,7 +133,7 @@
void dumpStackTraceEntry(unsigned index, void *framePC,
bool shortOutput = false);
-LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
void printCurrentBacktrace(unsigned framesToSkip = 1);
/// Debugger breakpoint ABI. This structure is passed to the debugger (and needs
@@ -221,7 +220,7 @@
bool _swift_shouldReportFatalErrorsToDebugger();
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
inline static int swift_asprintf(char **strp, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
diff --git a/include/swift/Runtime/Heap.h b/include/swift/Runtime/Heap.h
index 6ff7558..4f9e3c8 100644
--- a/include/swift/Runtime/Heap.h
+++ b/include/swift/Runtime/Heap.h
@@ -17,6 +17,4 @@
#ifndef SWIFT_RUNTIME_HEAP_H
#define SWIFT_RUNTIME_HEAP_H
-#include <llvm/Support/Compiler.h>
-
#endif /* SWIFT_RUNTIME_HEAP_H */
diff --git a/include/swift/Runtime/Unreachable.h b/include/swift/Runtime/Unreachable.h
index 671e261..4147d4c 100644
--- a/include/swift/Runtime/Unreachable.h
+++ b/include/swift/Runtime/Unreachable.h
@@ -18,11 +18,12 @@
#ifndef SWIFT_RUNTIME_UNREACHABLE_H
#define SWIFT_RUNTIME_UNREACHABLE_H
-#include "llvm/Support/Compiler.h"
#include <assert.h>
#include <stdlib.h>
-LLVM_ATTRIBUTE_NORETURN
+#include "swift/Runtime/Config.h"
+
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
inline static void swift_runtime_unreachable(const char *msg) {
assert(false && msg);
(void)msg;
diff --git a/include/swift/SIL/Projection.h b/include/swift/SIL/Projection.h
index 8566f70..eace9a2 100644
--- a/include/swift/SIL/Projection.h
+++ b/include/swift/SIL/Projection.h
@@ -78,7 +78,7 @@
/// TypeAlignments.h.
///
/// Projection Kinds which can be represented via indices can use as many bits
-/// as they want to represent the kind. When the index value is uses at most 11
+/// as they want to represent the kind. When the index value uses at most 11
/// bits, we represent it inline in the data structure. This is taking advantage
/// of the fact that on most modern OSes (including Darwin), the zero page is
/// not allocated. In the case where we have more than 11 bits of value
diff --git a/include/swift/SILOptimizer/Analysis/CallerAnalysis.h b/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
index e1eb98c..375c06e 100644
--- a/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
@@ -40,49 +40,9 @@
/// In addition of caller information this analysis also provides information
/// about partial applies of a function.
class CallerAnalysis : public SILAnalysis {
-
public:
+ class FunctionInfo;
- /// NOTE: this can be extended to contain the callsites of the function.
- class FunctionInfo {
- friend class CallerAnalysis;
-
- /// A list of all the functions this function calls or partially applies.
- llvm::SetVector<SILFunction *> Callees;
- /// A list of all the callers this function has.
- llvm::SmallSet<SILFunction *, 4> Callers;
-
- /// The number of partial applied arguments of this function.
- ///
- /// Specifically, it stores the minimum number of partial applied arguments
- /// of each function which contain one or multiple partial_applys of this
- /// function.
- /// This is a little bit off-topic because a partial_apply is not really
- /// a "call" of this function.
- llvm::DenseMap<SILFunction *, int> PartialAppliers;
-
- public:
- /// Returns true if this function has at least one caller.
- bool hasCaller() const {
- return !Callers.empty();
- }
-
- /// Returns non zero if this function is partially applied anywhere.
- ///
- /// The return value is the minimum number of partially applied arguments.
- /// Usually all partial applies of a function partially apply the same
- /// number of arguments anyway.
- int getMinPartialAppliedArgs() const {
- int minArgs = 0;
- for (auto Iter : PartialAppliers) {
- int numArgs = Iter.second;
- if (minArgs == 0 || numArgs < minArgs)
- minArgs = numArgs;
- }
- return minArgs;
- }
- };
-
private:
/// Current module we are analyzing.
SILModule &Mod;
@@ -167,6 +127,44 @@
}
};
+/// NOTE: this can be extended to contain the callsites of the function.
+class CallerAnalysis::FunctionInfo {
+ friend class CallerAnalysis;
+
+ /// A list of all the functions this function calls or partially applies.
+ llvm::SetVector<SILFunction *> Callees;
+ /// A list of all the callers this function has.
+ llvm::SmallSet<SILFunction *, 4> Callers;
+
+ /// The number of partial applied arguments of this function.
+ ///
+ /// Specifically, it stores the minimum number of partial applied arguments
+ /// of each function which contain one or multiple partial_applys of this
+ /// function.
+ /// This is a little bit off-topic because a partial_apply is not really
+ /// a "call" of this function.
+ llvm::DenseMap<SILFunction *, int> PartialAppliers;
+
+public:
+ /// Returns true if this function has at least one caller.
+ bool hasCaller() const { return !Callers.empty(); }
+
+ /// Returns non zero if this function is partially applied anywhere.
+ ///
+ /// The return value is the minimum number of partially applied arguments.
+ /// Usually all partial applies of a function partially apply the same
+ /// number of arguments anyway.
+ int getMinPartialAppliedArgs() const {
+ int minArgs = 0;
+ for (auto Iter : PartialAppliers) {
+ int numArgs = Iter.second;
+ if (minArgs == 0 || numArgs < minArgs)
+ minArgs = numArgs;
+ }
+ return minArgs;
+ }
+};
+
} // end namespace swift
#endif
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 9f3a625..7cf2c52 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4148,19 +4148,20 @@
protos.push_back(proto->getDecl());
auto layoutConstraint = layout.getLayoutConstraint();
+ auto layoutSuperclass = layout.getSuperclass();
auto arena = AllocationArena::Permanent;
void *mem = ctx.Allocate(
totalSizeToAlloc<ProtocolDecl *, Type, LayoutConstraint, UUID>(
protos.size(),
- layout.superclass ? 1 : 0,
+ layoutSuperclass ? 1 : 0,
layoutConstraint ? 1 : 0, 1),
alignof(ArchetypeType), arena);
// FIXME: Pass in class layout constraint
auto result =
::new (mem) ArchetypeType(ctx, existential,
- protos, layout.superclass,
+ protos, layoutSuperclass,
layoutConstraint, *knownID);
openedExistentialArchetypes[*knownID] = result;
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 08ae82e..654992e 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -654,7 +654,7 @@
assert(((relatedEntityKind[0] >= 'a' && relatedEntityKind[0] <= 'j') ||
(relatedEntityKind[0] >= 'A' && relatedEntityKind[0] <= 'J')) &&
"Only [a-jA-J] are reserved for related entity kinds");
- return appendOperatorParam("L", synthesizedTypeAttr->getManglingName());
+ return appendOperatorParam("L", relatedEntityKind);
}
StringRef privateDiscriminator = getPrivateDiscriminatorIfNecessary(decl);
@@ -838,8 +838,8 @@
if (First)
appendOperator("y");
- if (layout.superclass) {
- appendType(layout.superclass);
+ if (auto superclass = layout.explicitSuperclass) {
+ appendType(superclass);
return appendOperator("Xc");
} else if (layout.hasExplicitAnyObject) {
return appendOperator("Xl");
diff --git a/lib/AST/ASTScope.cpp b/lib/AST/ASTScope.cpp
index b13f137..41d83f8 100644
--- a/lib/AST/ASTScope.cpp
+++ b/lib/AST/ASTScope.cpp
@@ -1070,9 +1070,8 @@
}
/// Find all of the (non-nested) closures referenced within this expression.
-static SmallVector<ClosureExpr *, 4> findClosures(Expr *expr) {
- SmallVector<ClosureExpr *, 4> closures;
- if (!expr) return closures;
+static void findClosures(Expr *expr, SmallVectorImpl<ClosureExpr *> &closures) {
+ if (!expr) return;
/// AST walker that finds top-level closures in an expression.
class ClosureFinder : public ASTWalker {
@@ -1110,14 +1109,20 @@
};
expr->walk(ClosureFinder(closures));
- return closures;
}
ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Expr *expr) {
if (!expr) return nullptr;
+ return createIfNeeded(parent, llvm::makeArrayRef(expr));
+}
- // Dig out closure expressions within the given expression.
- auto closures = findClosures(expr);
+ASTScope *ASTScope::createIfNeeded(const ASTScope *parent,
+ ArrayRef<Expr *> exprs) {
+ SmallVector<ClosureExpr*, 4> closures;
+
+ // Dig out closure expressions within the given expressions.
+ for (auto expr: exprs)
+ findClosures(expr, closures);
if (closures.empty())
return nullptr;
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 4b70ec6..0d95ad2 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -934,6 +934,7 @@
void verifyChecked(DeferStmt *S) {
auto FT = S->getTempDecl()->getInterfaceType()->castTo<AnyFunctionType>();
assert(FT->isNoEscape() && "Defer statements must not escape");
+ (void)FT;
verifyCheckedBase(S);
}
@@ -1251,7 +1252,7 @@
}
auto layout = srcTy->getExistentialLayout();
- if (layout.superclass ||
+ if (layout.explicitSuperclass ||
!layout.isObjC() ||
layout.getProtocols().size() != 1) {
Out << "ProtocolMetatypeToObject with non-ObjC-protocol metatype:\n";
diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp
index 26a286c..50209f9 100644
--- a/lib/AST/ConformanceLookupTable.cpp
+++ b/lib/AST/ConformanceLookupTable.cpp
@@ -246,7 +246,7 @@
}
if (inheritedType->isExistentialType()) {
auto layout = inheritedType->getExistentialLayout();
- if (layout.superclass) {
+ if (layout.explicitSuperclass) {
superclassLoc = inherited.getSourceRange().Start;
return superclassLoc;
}
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 7b47141..6824d87 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3394,6 +3394,10 @@
return true;
}
}
+ if (type->getClassOrBoundGenericClass()) {
+ Bits.ProtocolDecl.RequiresClass = true;
+ return true;
+ }
}
return Bits.ProtocolDecl.RequiresClass;
@@ -4067,6 +4071,12 @@
return SourceLoc();
}
+Type AbstractStorageDecl::getValueInterfaceType() const {
+ if (auto var = dyn_cast<VarDecl>(this))
+ return var->getInterfaceType();
+ return cast<SubscriptDecl>(this)->getElementInterfaceType();
+}
+
Type VarDecl::getType() const {
if (!typeInContext) {
const_cast<VarDecl *>(this)->typeInContext =
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 683bcd6..c117271 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1544,6 +1544,7 @@
assert((Implicit || ElementNames.size() == ElementNameLocs.size() ||
(!hasNonEmptyIdentifier(ElementNames) && ElementNameLocs.empty())) &&
"trying to create non-implicit tuple-expr without name locations");
+ (void)hasNonEmptyIdentifier;
size_t size =
totalSizeToAlloc<Expr *, Identifier, SourceLoc>(SubExprs.size(),
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 3941a3f..2b4b83c 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -4788,9 +4788,9 @@
anyErrors = true;
}
- if (layout.superclass) {
+ if (auto superclass = layout.explicitSuperclass) {
if (isErrorResult(addSuperclassRequirementDirect(resolvedSubject,
- layout.superclass,
+ superclass,
source)))
anyErrors = true;
}
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 0f40db1..4ddf34d 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -611,15 +611,29 @@
// If the existential is class-constrained, the class might conform
// concretely.
- if (layout.superclass) {
- if (auto result = lookupConformance(layout.superclass, protocol))
+ if (auto superclass = layout.explicitSuperclass) {
+ if (auto result = lookupConformance(superclass, protocol))
return result;
}
// Otherwise, the existential might conform abstractly.
for (auto proto : layout.getProtocols()) {
auto *protoDecl = proto->getDecl();
- if (protoDecl == protocol || protoDecl->inheritsFrom(protocol))
+
+ // If we found the protocol we're looking for, return an abstract
+ // conformance to it.
+ if (protoDecl == protocol)
+ return ProtocolConformanceRef(protocol);
+
+ // If the protocol has a superclass constraint, we might conform
+ // concretely.
+ if (auto superclass = protoDecl->getSuperclass()) {
+ if (auto result = lookupConformance(superclass, protocol))
+ return result;
+ }
+
+ // Now check refined protocols.
+ if (protoDecl->inheritsFrom(protocol))
return ProtocolConformanceRef(protocol);
}
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 888fb6a..291acc9 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -1728,8 +1728,8 @@
stack.push_back(proto);
// Look into the superclasses of this archetype.
- if (auto superclassTy = archetypeTy->getSuperclass())
- if (auto superclassDecl = superclassTy->getAnyNominal())
+ if (auto superclass = archetypeTy->getSuperclass())
+ if (auto superclassDecl = superclass->getClassOrBoundGenericClass())
if (visited.insert(superclassDecl).second)
stack.push_back(superclassDecl);
}
@@ -1747,8 +1747,8 @@
stack.push_back(protoDecl);
}
- if (layout.superclass) {
- auto *nominalDecl = layout.superclass->getAnyNominal();
+ if (auto superclass = layout.explicitSuperclass) {
+ auto *nominalDecl = superclass->getClassOrBoundGenericClass();
if (visited.insert(nominalDecl).second)
stack.push_back(nominalDecl);
}
@@ -1843,13 +1843,18 @@
}
if (visitSuperclass) {
- if (auto superclassType = classDecl->getSuperclass())
- if (auto superclassDecl = superclassType->getClassOrBoundGenericClass())
- if (visited.insert(superclassDecl).second)
- stack.push_back(superclassDecl);
+ if (auto superclassDecl = classDecl->getSuperclassDecl())
+ if (visited.insert(superclassDecl).second)
+ stack.push_back(superclassDecl);
}
}
+ if (auto protocolDecl = dyn_cast<ProtocolDecl>(current)) {
+ if (auto superclassDecl = protocolDecl->getSuperclassDecl())
+ if (visited.insert(superclassDecl).second)
+ stack.push_back(superclassDecl);
+ }
+
// If we're not looking at a protocol and we're not supposed to
// visit the protocols that this type conforms to, skip the next
// step.
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 01db66d..056ffa9 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -257,7 +257,7 @@
auto members = type->getMembers();
if (!members.empty() &&
isa<ClassDecl>(members[0]->getAnyNominal())) {
- superclass = members[0];
+ explicitSuperclass = members[0];
members = members.slice(1);
}
@@ -284,7 +284,7 @@
}
bool ExistentialLayout::requiresClass() const {
- if (hasExplicitAnyObject || superclass)
+ if (hasExplicitAnyObject || explicitSuperclass)
return true;
for (auto proto : getProtocols()) {
@@ -295,8 +295,20 @@
return false;
}
+Type ExistentialLayout::getSuperclass() const {
+ if (explicitSuperclass)
+ return explicitSuperclass;
+
+ for (auto proto : getProtocols()) {
+ if (auto superclass = proto->getSuperclass())
+ return superclass;
+ }
+
+ return Type();
+}
+
bool ExistentialLayout::isAnyObject() const {
- return (hasExplicitAnyObject && !superclass && getProtocols().empty());
+ return (hasExplicitAnyObject && !explicitSuperclass && getProtocols().empty());
}
bool TypeBase::isObjCExistentialType() {
@@ -624,7 +636,7 @@
bool ExistentialLayout::isErrorExistential() const {
auto protocols = getProtocols();
return (!hasExplicitAnyObject &&
- !superclass &&
+ !explicitSuperclass &&
protocols.size() == 1 &&
protocols[0]->getDecl()->isSpecificProtocol(KnownProtocolKind::Error));
}
@@ -785,7 +797,17 @@
parenTy->getParameterFlags()));
return result;
}
-
+
+ // If `Void` has been explicitly specified, resulting decomposition
+ // should be empty, just like empty tuple would be.
+ case TypeKind::NameAlias: {
+ auto &ctx = type->getASTContext();
+ auto *typealias = cast<NameAliasType>(type.getPointer());
+ if (typealias->getDecl() == ctx.getVoidDecl())
+ return result;
+ break;
+ }
+
default:
// Default behavior below; inject the argument as the sole parameter.
break;
@@ -1443,8 +1465,11 @@
if (auto dynamicSelfTy = getAs<DynamicSelfType>())
return dynamicSelfTy->getSelfType();
+ if (auto protocolTy = getAs<ProtocolType>())
+ return protocolTy->getDecl()->getSuperclass();
+
if (auto compositionTy = getAs<ProtocolCompositionType>())
- return compositionTy->getExistentialLayout().superclass;
+ return compositionTy->getExistentialLayout().getSuperclass();
// No other types have superclasses.
return Type();
@@ -1848,8 +1873,8 @@
if (type->isExistentialType()) {
auto layout = type->getExistentialLayout();
if (layout.isObjC() &&
- (!layout.superclass ||
- getObjCObjectRepresentable(layout.superclass, dc) ==
+ (!layout.explicitSuperclass ||
+ getObjCObjectRepresentable(layout.explicitSuperclass, dc) ==
ForeignRepresentableKind::Object))
return ForeignRepresentableKind::Object;
}
@@ -3186,7 +3211,7 @@
} else if (auto dynamicSelfTy = t->getAs<DynamicSelfType>()) {
return dynamicSelfTy->getSelfType();
} else if (auto compositionTy = t->getAs<ProtocolCompositionType>()) {
- return compositionTy->getExistentialLayout().superclass;
+ return compositionTy->getExistentialLayout().explicitSuperclass;
}
}
return t;
@@ -4086,8 +4111,8 @@
case TypeKind::ProtocolComposition: {
auto layout = getExistentialLayout();
assert(layout.requiresClass() && "Opaque existentials don't use refcounting");
- if (layout.superclass)
- return layout.superclass->usesNativeReferenceCounting(resilience);
+ if (auto superclass = layout.getSuperclass())
+ return superclass->usesNativeReferenceCounting(resilience);
return ::doesOpaqueClassUseNativeReferenceCounting(type->getASTContext());
}
diff --git a/lib/Basic/Unix/TaskQueue.inc b/lib/Basic/Unix/TaskQueue.inc
index ecdd37f..07410f9 100644
--- a/lib/Basic/Unix/TaskQueue.inc
+++ b/lib/Basic/Unix/TaskQueue.inc
@@ -556,6 +556,7 @@
assert((events & POLLNVAL) == 0 && "Asked poll() to watch a closed fd");
const short expectedEvents = POLLIN | POLLPRI | POLLHUP | POLLERR;
assert((events & ~expectedEvents) == 0 && "Received unexpected event");
+ (void)expectedEvents;
}
void TaskMonitor::readDataIfAvailable(const short events, const int fd,
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 981d2d3..dcf69ff 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -6399,11 +6399,10 @@
if (!decl->getDeclContext()->isTypeContext())
return;
- auto classTy = decl->getDeclContext()->getDeclaredInterfaceType()
- ->getAs<ClassType>();
- if (!classTy)
+ auto classDecl = decl->getDeclContext()->getAsClassOrClassExtensionContext();
+ if (!classDecl)
return;
- auto superTy = classTy->getSuperclass();
+ auto superTy = classDecl->getSuperclass();
if (!superTy)
return;
// Dig out the Objective-C superclass.
@@ -7909,6 +7908,7 @@
const ProtocolDecl *proto = conformance->getProtocol();
assert(origBase->isEqual(proto->getSelfInterfaceType()));
+ (void)proto;
return conformance->getTypeWitness(depMemTy->getAssocType(),
/*resolver=*/nullptr);
}
diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h
index 324fb81..2286d35 100644
--- a/lib/ClangImporter/ImporterImpl.h
+++ b/lib/ClangImporter/ImporterImpl.h
@@ -625,11 +625,9 @@
} else if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
assert(CD->getInterfaceType());
ty = CD->getResultInterfaceType();
- } else if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
- ty = SD->getElementInterfaceType();
} else {
- auto *VD = cast<VarDecl>(decl);
- ty = VD->getInterfaceType()->getReferenceStorageReferent();
+ ty = cast<AbstractStorageDecl>(decl)->getValueInterfaceType()
+ ->getReferenceStorageReferent();
}
#endif
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index abd382a..7872bd4 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -244,10 +244,6 @@
validateDebugInfoArgs(diags, args);
validateCompilationConditionArgs(diags, args);
validateAutolinkingArgs(diags, args);
-
- if (args.hasArg(options::OPT_emit_public_type_metadata_accessors))
- diags.diagnose(SourceLoc(),
- diag::warn_emit_public_type_metadata_accessors_deprecated);
}
std::unique_ptr<ToolChain>
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 7e13d1c..dbf283b 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -297,6 +297,7 @@
auto R =
jobsByInput.insert(std::make_pair(IA->getInputArg().getValue(), J));
assert(R.second);
+ (void)R;
}
for (const InputPair &P : C.getInputFiles()) {
auto I = jobsByInput.find(P.second->getValue());
diff --git a/lib/Frontend/FrontendInputsAndOutputs.cpp b/lib/Frontend/FrontendInputsAndOutputs.cpp
index fad6b90..4b11e1c 100644
--- a/lib/Frontend/FrontendInputsAndOutputs.cpp
+++ b/lib/Frontend/FrontendInputsAndOutputs.cpp
@@ -293,6 +293,7 @@
assert(outputFiles.size() == N && "Must have one main output per primary");
assert(supplementaryOutputs.size() == N &&
"Must have one set of supplementary outputs per primary");
+ (void)N;
unsigned i = 0;
for (auto &input : AllInputs) {
diff --git a/lib/FrontendTool/ReferenceDependencies.cpp b/lib/FrontendTool/ReferenceDependencies.cpp
index 0c62eb2..87c947e 100644
--- a/lib/FrontendTool/ReferenceDependencies.cpp
+++ b/lib/FrontendTool/ReferenceDependencies.cpp
@@ -490,8 +490,8 @@
}
auto layout = type->getExistentialLayout();
- assert(!layout.superclass && "Should not have a subclass existential "
- "in the inheritance clause of an extension");
+ assert(!layout.explicitSuperclass && "Should not have a subclass existential "
+ "in the inheritance clause of an extension");
for (auto protoTy : layout.getProtocols()) {
if (!declIsPrivate(protoTy->getDecl()))
return false;
diff --git a/lib/IRGen/GenCast.cpp b/lib/IRGen/GenCast.cpp
index 42489c4..0796a15 100644
--- a/lib/IRGen/GenCast.cpp
+++ b/lib/IRGen/GenCast.cpp
@@ -522,7 +522,7 @@
bool hasClassConstraint = layout.requiresClass();
bool hasClassConstraintByProtocol = false;
- bool hasSuperclassConstraint = bool(layout.superclass);
+ bool hasSuperclassConstraint = bool(layout.getSuperclass());
for (auto protoTy : layout.getProtocols()) {
auto *protoDecl = protoTy->getDecl();
@@ -563,7 +563,7 @@
// The source of a scalar cast is statically known to be a class or a
// metatype, so we only have to check the class constraint in two cases:
//
- // 1) The destination type has an explicit superclass constraint that is
+ // 1) The destination type has a superclass constraint that is
// more derived than what the source type is known to be.
//
// 2) We are casting between metatypes, in which case the source might
@@ -739,7 +739,7 @@
args.push_back(metadataValue);
if (checkSuperclassConstraint)
- args.push_back(IGF.emitTypeMetadataRef(CanType(layout.superclass)));
+ args.push_back(IGF.emitTypeMetadataRef(CanType(layout.getSuperclass())));
for (auto proto : witnessTableProtos)
args.push_back(proto);
diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp
index c70b3ac..d36aad4 100644
--- a/lib/IRGen/GenClangType.cpp
+++ b/lib/IRGen/GenClangType.cpp
@@ -623,10 +623,10 @@
return getClangIdType(getClangASTContext());
auto superclassTy = clangCtx.ObjCBuiltinIdTy;
- if (layout.superclass) {
+ if (auto layoutSuperclassTy = layout.getSuperclass()) {
superclassTy = clangCtx.getCanonicalType(
cast<clang::ObjCObjectPointerType>(
- Converter.convert(IGM, CanType(layout.superclass)))
+ Converter.convert(IGM, CanType(layoutSuperclassTy)))
->getPointeeType());
}
diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp
index e7e5fb5..4fc638d 100644
--- a/lib/IRGen/GenExistential.cpp
+++ b/lib/IRGen/GenExistential.cpp
@@ -1431,8 +1431,8 @@
ReferenceCounting refcounting = getReferenceCountingForType(IGM, T);
llvm::PointerType *reprTy = nullptr;
- if (layout.superclass) {
- auto &superTI = IGM.getTypeInfoForUnlowered(layout.superclass);
+ if (auto superclass = layout.getSuperclass()) {
+ auto &superTI = IGM.getTypeInfoForUnlowered(superclass);
reprTy = cast<llvm::PointerType>(superTI.getStorageType());
} else if (refcounting == ReferenceCounting::Native) {
reprTy = IGM.RefCountedPtrTy;
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 6ec7f07..20182e8 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -700,7 +700,10 @@
uint16_t getKindSpecificFlags() {
TypeContextDescriptorFlags flags;
- flags.setIsReflectable(true); // struct always reflectable
+ // Structs are reflectable unless we emit them with opaque reflection
+ // metadata.
+ flags.setIsReflectable(
+ !IGM.shouldEmitOpaqueTypeMetadataRecord(getType()));
getClangImportedFlags(flags);
return flags.getOpaqueValue();
@@ -875,7 +878,7 @@
auto *dc = fn.getDecl()->getDeclContext();
assert(!isa<ExtensionDecl>(dc));
- if (fn.getDecl()->getDeclContext() == getType()) {
+ if (dc == getType()) {
if (auto entry = VTable->getEntry(IGM.getSILModule(), fn)) {
assert(entry->TheKind == SILVTable::Entry::Kind::Normal);
auto *implFn = IGM.getAddrOfSILFunction(entry->Implementation,
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 7879df4..ea36378 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -2614,6 +2614,7 @@
return /*finished?*/ false;
});
assert(found && "too many conditional conformances");
+ (void)found;
sourceKey.Kind =
LocalTypeDataKind::forAbstractProtocolWitnessTable(conformingProto);
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index 16c8fd8..379bbe6 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -1400,4 +1400,5 @@
SILType T) const {
auto canType = T.getASTType();
assert(!canType->is<ArchetypeType>() && "Did not expect an ArchetypeType");
+ (void)canType;
}
diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp
index 003e72e..9f4aa69 100644
--- a/lib/IRGen/IRGenMangler.cpp
+++ b/lib/IRGen/IRGenMangler.cpp
@@ -141,19 +141,17 @@
if (i == 0)
appendOperator("_");
}
- if (layout.superclass) {
- auto superclassTy = layout.superclass;
-
+ if (auto superclass = layout.explicitSuperclass) {
// We share type infos for different instantiations of a generic type
// when the archetypes have the same exemplars. We cannot mangle
// archetypes, and the mangling does not have to be unique, so we just
// mangle the unbound generic form of the type.
- if (superclassTy->hasArchetype()) {
- superclassTy = superclassTy->getClassOrBoundGenericClass()
+ if (superclass->hasArchetype()) {
+ superclass = superclass->getClassOrBoundGenericClass()
->getDeclaredType();
}
- appendType(CanType(superclassTy));
+ appendType(CanType(superclass));
appendOperator("Xc");
} else if (layout.getLayoutConstraint()) {
appendOperator("Xl");
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 4553214..75df440 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -3956,6 +3956,7 @@
auto fnType = operandType.getAs<SILFunctionType>();
assert(fnType->getExtInfo().hasContext() && "Must have a closure operand");
+ (void)fnType;
// This code relies on that an optional<()->()>'s tag fits in the function
// pointer.
@@ -3963,6 +3964,7 @@
assert(TI.mayHaveExtraInhabitants(IGM) &&
"Must have extra inhabitants to be able to handle the optional "
"closure case");
+ (void)TI;
Explosion closure = getLoweredExplosion(i->getOperand());
auto func = closure.claimNext();
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 31b0700..9bca707 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -949,6 +949,7 @@
assert(pass.allocToApplyRetMap.find(opAsInstr) !=
pass.allocToApplyRetMap.end() &&
"Unexpected dealloc instr!");
+ (void)opAsInstr;
}
}
@@ -1377,6 +1378,7 @@
"Expected SILFunctionType or Optional for the result type");
assert(optionalType.is<SILFunctionType>() &&
"Expected a SILFunctionType inside the optional Type");
+ (void)optionalType;
}
continue;
}
@@ -2018,6 +2020,8 @@
assert(srcType && "Expected an address-type source");
assert(tgtType.isAddress() && "Expected an address-type target");
assert(srcType == tgtType && "Source and target type do not match");
+ (void)srcType;
+ (void)tgtType;
SILBuilderWithScope copyBuilder(instr);
createOutlinedCopyCall(copyBuilder, src, tgt, pass);
@@ -2406,6 +2410,7 @@
assert(oldYields.size() == newYields.size() &&
oldYields.size() == oldYieldedValues.size() &&
newYields.size() == newYieldedValues.size());
+ (void)newYields;
for (auto i : indices(oldYields)) {
SILValue oldValue = oldYieldedValues[i];
SILValue newValue = newYieldedValues[i];
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index 4769372..6fd74ea 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -561,8 +561,28 @@
if (nominalDecl->isGenericContext())
return false;
+ auto expansion = ResilienceExpansion::Maximal;
+
+ // Normally, if a value type is known to have a fixed layout to us, we will
+ // have emitted fully initialized metadata for it, including a payload size
+ // field for enum metadata for example, allowing the type metadata to be
+ // used in other resilience domains without initialization.
+ //
+ // However, when -enable-resilience-bypass is on, we might be using a value
+ // type from another module built with resilience enabled. In that case, the
+ // type looks like it has fixed size to us, since we're bypassing resilience,
+ // but the metadata still requires runtime initialization, so its incorrect
+ // to reference it directly.
+ //
+ // While unconditionally using minimal expansion is correct, it is not as
+ // efficient as it should be, so only do so if -enable-resilience-bypass is on.
+ //
+ // FIXME: All of this goes away once lldb supports resilience.
+ if (IGM.IRGen.Opts.EnableResilienceBypass)
+ expansion = ResilienceExpansion::Minimal;
+
// Resiliently-sized metadata access always requires an accessor.
- return (IGM.getTypeInfoForUnlowered(type).isFixedSize());
+ return (IGM.getTypeInfoForUnlowered(type).isFixedSize(expansion));
}
// The empty tuple type has a singleton metadata.
@@ -1155,9 +1175,9 @@
!layout.requiresClass());
llvm::Value *superclassConstraint =
llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy);
- if (layout.superclass) {
+ if (auto superclass = layout.explicitSuperclass) {
superclassConstraint = IGF.emitAbstractTypeMetadataRef(
- CanType(layout.superclass));
+ CanType(superclass));
}
auto call = IGF.Builder.CreateCall(IGF.IGM.getGetExistentialMetadataFn(),
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index 825fe29..b9c230a 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -1028,6 +1028,7 @@
}
// Change attribute(rawValue: "value") to "value"
+ // Change attribute("value") to "value"
if (auto *CE = dyn_cast<CallExpr>(E)) {
auto Found = false;
if (auto *CRC = dyn_cast<ConstructorRefCallExpr>(CE->getFn())) {
@@ -1040,10 +1041,14 @@
return false;
std::vector<CallArgInfo> AllArgs =
getCallArgInfo(SM, CE->getArg(), LabelRangeEndAt::LabelNameOnly);
- if (AllArgs.size() == 1 && AllArgs.front().LabelRange.str() == "rawValue") {
- Editor.replace(CE->getSourceRange(), Lexer::getCharSourceRangeFromSourceRange(SM,
- AllArgs.front().ArgExp->getSourceRange()).str());
- return true;
+ if (AllArgs.size() == 1) {
+ auto Label = AllArgs.front().LabelRange.str();
+ if (Label == "rawValue" || Label.empty()) {
+ Editor.replace(CE->getSourceRange(),
+ Lexer::getCharSourceRangeFromSourceRange(SM,
+ AllArgs.front().ArgExp->getSourceRange()).str());
+ return true;
+ }
}
}
return false;
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 605bc13..fb535ab 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -463,6 +463,17 @@
return sub;
}
+static Expr *formUnaryArgument(ASTContext &context, Expr *argument) {
+ if (isa<ParenExpr>(argument))
+ return argument;
+
+ auto *arg = new (context)
+ ParenExpr(argument->getStartLoc(), argument, argument->getEndLoc(),
+ /*hasTrailingClosure*/ false);
+ arg->setImplicit();
+ return arg;
+}
+
/// parseExprUnary
///
/// expr-unary(Mode):
@@ -538,8 +549,8 @@
}
}
- return makeParserResult(
- new (Context) PrefixUnaryExpr(Operator, SubExpr.get()));
+ return makeParserResult(new (Context) PrefixUnaryExpr(
+ Operator, formUnaryArgument(Context, SubExpr.get())));
}
/// expr-keypath-swift:
@@ -1330,8 +1341,9 @@
break;
Expr *oper = parseExprOperator();
- Result =
- makeParserResult(new (Context) PostfixUnaryExpr(oper, Result.get()));
+
+ Result = makeParserResult(new (Context) PostfixUnaryExpr(
+ oper, formUnaryArgument(Context, Result.get())));
SyntaxContext->createNodeInPlace(SyntaxKind::PostfixUnaryExpr);
continue;
}
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 2522604..624caeb 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -847,6 +847,7 @@
auto *GenericEnv = F->getGenericEnvironment();
assert(GenericEnv);
+ (void)GenericEnv;
IdentTypeReprLookup PerformLookup(P);
// Use parser lexical scopes to resolve references
diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp
index 7871a87..c7dd8aa 100644
--- a/lib/PrintAsObjC/PrintAsObjC.cpp
+++ b/lib/PrintAsObjC/PrintAsObjC.cpp
@@ -1733,14 +1733,14 @@
return;
}
- if (layout.superclass) {
- auto *CD = layout.superclass->getClassOrBoundGenericClass();
+ if (auto superclass = layout.explicitSuperclass) {
+ auto *CD = superclass->getClassOrBoundGenericClass();
assert(CD->isObjC());
if (isMetatype) {
os << "SWIFT_METATYPE(" << getNameForObjC(CD) << ")";
} else {
os << getNameForObjC(CD);
- if (auto *BGT = layout.superclass->getAs<BoundGenericClassType>())
+ if (auto *BGT = superclass->getAs<BoundGenericClassType>())
printGenericArgs(BGT);
}
} else {
@@ -1752,7 +1752,7 @@
protos.push_back(proto->getDecl());
printProtocols(protos);
- if (layout.superclass && !isMetatype)
+ if (layout.explicitSuperclass && !isMetatype)
os << " *";
printNullability(optionalKind);
@@ -2007,8 +2007,8 @@
void visitProtocolCompositionType(ProtocolCompositionType *composition) {
auto layout = composition->getExistentialLayout();
- if (layout.superclass)
- visit(layout.superclass);
+ if (auto superclass = layout.explicitSuperclass)
+ visit(superclass);
for (auto proto : layout.getProtocols())
visit(proto);
}
diff --git a/lib/SIL/InstructionUtils.cpp b/lib/SIL/InstructionUtils.cpp
index dacb37b..dfc6c32 100644
--- a/lib/SIL/InstructionUtils.cpp
+++ b/lib/SIL/InstructionUtils.cpp
@@ -355,6 +355,7 @@
static SILValue findClosureStoredIntoBlock(SILValue V) {
auto FnType = V->getType().castTo<SILFunctionType>();
assert(FnType->getRepresentation() == SILFunctionTypeRepresentation::Block);
+ (void)FnType;
// Given a no escape block argument to a function,
// pattern match to find the noescape closure that invoking the block
diff --git a/lib/SIL/SILCoverageMap.cpp b/lib/SIL/SILCoverageMap.cpp
index a215a6b..f2f0c94 100644
--- a/lib/SIL/SILCoverageMap.cpp
+++ b/lib/SIL/SILCoverageMap.cpp
@@ -45,6 +45,7 @@
// Assert that this coverage map is unique.
assert(result.second && "Duplicate coverage mapping for function");
+ (void)result;
return CM;
}
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index ff6681e..f82a76a 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -2122,6 +2122,7 @@
auto inserted = ConstantTypes.insert({constant, result});
assert(inserted.second);
+ (void)inserted;
return *result;
}
@@ -2289,6 +2290,7 @@
auto inserted = ConstantOverrideTypes.insert({{derived, base}, result});
assert(inserted.second);
+ (void)inserted;
return *result;
}
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index 259e7d7..ebabf1c 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -129,6 +129,7 @@
return isGuaranteedForwardingValueKind(SILNodeKind(I->getKind()));
}
+LLVM_ATTRIBUTE_UNUSED
static bool isOwnershipForwardingInst(SILInstruction *I) {
return isOwnershipForwardingValueKind(SILNodeKind(I->getKind()));
}
@@ -154,7 +155,9 @@
OwnershipUseCheckerResult> {
public:
private:
+ LLVM_ATTRIBUTE_UNUSED
SILModule &Mod;
+
const Operand &Op;
SILValue BaseValue;
ErrorBehaviorKind ErrorBehavior;
diff --git a/lib/SIL/SILProfiler.cpp b/lib/SIL/SILProfiler.cpp
index f32b86f..312320d 100644
--- a/lib/SIL/SILProfiler.cpp
+++ b/lib/SIL/SILProfiler.cpp
@@ -86,6 +86,7 @@
} // namespace swift
/// Check that the input AST has at least been type-checked.
+LLVM_ATTRIBUTE_UNUSED
static bool hasASTBeenTypeChecked(ASTNode N) {
DeclContext *DC = N.getAsDeclContext();
assert(DC && "Invalid AST node for profiling");
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index df4a5a7..b5fb13b 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -3151,8 +3151,8 @@
"init_existential of class existential with non-class type");
}
- if (layout.superclass) {
- require(layout.superclass->isExactSuperclassOf(concreteType),
+ if (auto superclass = layout.getSuperclass()) {
+ require(superclass->isExactSuperclassOf(concreteType),
"init_existential of subclass existential with wrong type");
}
@@ -4984,6 +4984,8 @@
"Witnesses must either have a concrete Self, or an "
"an abstract Self that is constrained to their "
"protocol.");
+ (void)protocol;
+ (void)witnessSelfProtocol;
}
}
}
diff --git a/lib/SILGen/Cleanup.cpp b/lib/SILGen/Cleanup.cpp
index bdaf095..0cd9596 100644
--- a/lib/SILGen/Cleanup.cpp
+++ b/lib/SILGen/Cleanup.cpp
@@ -56,7 +56,7 @@
}
void CleanupManager::emitCleanups(CleanupsDepth depth, CleanupLocation loc,
- bool popCleanups) {
+ ForUnwind_t forUnwind, bool popCleanups) {
auto begin = stack.stable_begin();
while (begin != depth) {
auto iter = stack.find(begin);
@@ -76,7 +76,7 @@
stack.pop();
if (cleanup.isActive() && SGF.B.hasValidInsertionPoint())
- cleanup.emit(SGF, loc);
+ cleanup.emit(SGF, loc, forUnwind);
stack.checkIterator(begin);
}
@@ -95,7 +95,7 @@
// Iteratively mark cleanups dead and pop them.
// Maybe we'd get better results if we marked them all dead in one shot?
- emitCleanups(depth, loc);
+ emitCleanups(depth, loc, NotForUnwind);
}
bool CleanupManager::hasAnyActiveCleanups(CleanupsDepth from,
@@ -111,11 +111,12 @@
/// threading out through any cleanups we might need to run. This does not
/// pop the cleanup stack.
void CleanupManager::emitBranchAndCleanups(JumpDest dest, SILLocation branchLoc,
- ArrayRef<SILValue> args) {
+ ArrayRef<SILValue> args,
+ ForUnwind_t forUnwind) {
SILGenBuilder &builder = SGF.getBuilder();
assert(builder.hasValidInsertionPoint() && "Emitting branch in invalid spot");
emitCleanups(dest.getDepth(), dest.getCleanupLocation(),
- /*popCleanups=*/false);
+ forUnwind, /*popCleanups=*/false);
builder.createBranch(branchLoc, dest.getBlock(), args);
}
@@ -123,7 +124,7 @@
SILGenBuilder &builder = SGF.getBuilder();
assert(builder.hasValidInsertionPoint() && "Emitting return in invalid spot");
(void)builder;
- emitCleanups(stack.stable_end(), loc, /*popCleanups=*/false);
+ emitCleanups(stack.stable_end(), loc, NotForUnwind, /*popCleanups=*/false);
}
/// Emit a new block that jumps to the specified location and runs necessary
@@ -131,7 +132,8 @@
/// returns the dest block.
SILBasicBlock *CleanupManager::emitBlockForCleanups(JumpDest dest,
SILLocation branchLoc,
- ArrayRef<SILValue> args) {
+ ArrayRef<SILValue> args,
+ ForUnwind_t forUnwind) {
// If there are no cleanups to run, just return the Dest block directly.
if (!hasAnyActiveCleanups(dest.getDepth()))
return dest.getBlock();
@@ -139,7 +141,7 @@
// Otherwise, create and emit a new block.
auto *newBlock = SGF.createBasicBlock();
SILGenSavedInsertionPoint IPRAII(SGF, newBlock);
- emitBranchAndCleanups(dest, branchLoc, args);
+ emitBranchAndCleanups(dest, branchLoc, args, forUnwind);
return newBlock;
}
diff --git a/lib/SILGen/Cleanup.h b/lib/SILGen/Cleanup.h
index 28dc213..4213811 100644
--- a/lib/SILGen/Cleanup.h
+++ b/lib/SILGen/Cleanup.h
@@ -37,6 +37,21 @@
class SharedBorrowFormalAccess;
class FormalEvaluationScope;
+/// Is a cleanup being executed as a result of some sort of forced
+/// unwinding, such as an error being thrown, or are we just cleaning up
+/// after some operation?
+///
+/// Most cleanups don't care, but the cleanups tied to l-value accesses do:
+/// the access will be aborted rather than ended normally, which may cause
+/// e.g. writebacks to be skipped. It is also important that no actions
+/// be undertaken by an unwind cleanup that might change control flow,
+/// such as throwing an error. In contrast, non-unwinding cleanups are
+/// permitted to change control flow.
+enum ForUnwind_t : bool {
+ NotForUnwind,
+ IsForUnwind
+};
+
/// The valid states that a cleanup can be in.
enum class CleanupState {
/// The cleanup is inactive but may be activated later.
@@ -80,7 +95,8 @@
bool isActive() const { return state >= CleanupState::Active; }
bool isDead() const { return state == CleanupState::Dead; }
- virtual void emit(SILGenFunction &SGF, CleanupLocation loc) = 0;
+ virtual void emit(SILGenFunction &SGF, CleanupLocation loc,
+ ForUnwind_t forUnwind) = 0;
virtual void dump(SILGenFunction &SGF) const = 0;
};
@@ -120,6 +136,7 @@
void popTopDeadCleanups(CleanupsDepth end);
void emitCleanups(CleanupsDepth depth, CleanupLocation l,
+ ForUnwind_t forUnwind,
bool popCleanups=true);
void endScope(CleanupsDepth depth, CleanupLocation l);
@@ -151,7 +168,8 @@
/// \param branchLoc The location of the branch instruction.
/// \param args Arguments to pass to the destination block.
void emitBranchAndCleanups(JumpDest dest, SILLocation branchLoc,
- ArrayRef<SILValue> args = {});
+ ArrayRef<SILValue> args = {},
+ ForUnwind_t forUnwind = NotForUnwind);
/// emitCleanupsForReturn - Emit the top-level cleanups needed prior to a
/// return from the function.
@@ -161,7 +179,8 @@
/// cleanups based on its level. If there are no cleanups to run, this just
/// returns the dest block.
SILBasicBlock *emitBlockForCleanups(JumpDest dest, SILLocation branchLoc,
- ArrayRef<SILValue> args = {});
+ ArrayRef<SILValue> args = {},
+ ForUnwind_t forUnwind = NotForUnwind);
/// pushCleanup - Push a new cleanup.
template<class T, class... A>
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index db9437f..8787f42 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -3338,7 +3338,7 @@
public:
DeallocateUninitializedBox(SILValue box) : box(box) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
SGF.B.createDeallocBox(l, box);
}
@@ -3857,6 +3857,7 @@
}
assert(substFnType->getNumResults() == 1);
+ (void)substFnType;
ManagedValue resultMV = SGF.emitInjectEnum(
uncurriedLoc, std::move(payload), SGF.getLoweredType(formalResultType),
element, uncurriedContext);
@@ -4829,7 +4830,7 @@
DeallocateUninitializedArray(SILValue array)
: Array(array) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
SGF.emitUninitializedArrayDeallocation(l, Array);
}
@@ -5198,6 +5199,7 @@
auto subscriptsTupleType = cast<TupleType>(subscripts.getType());
assert(accessType.getParams().size()
== 1 + subscriptsTupleType->getNumElements());
+ (void)subscriptsTupleType;
SmallVector<RValue, 8> eltRVs;
std::move(subscripts).extractElements(eltRVs);
for (auto &elt : eltRVs)
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 68bbb0e..9f1c46a 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -67,8 +67,8 @@
// They're also convertible to Error if they have a class bound that
// conforms to Error.
- if (auto cls = layout.superclass) {
- type = cls->getCanonicalType();
+ if (auto superclass = layout.getSuperclass()) {
+ type = superclass->getCanonicalType();
// Otherwise, they are not convertible to Error.
} else {
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index eb6b25e..879640c 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -219,6 +219,8 @@
SILFunctionTypeRepresentation::Thick &&
!fnType->isNoEscape() && resultFnType->isNoEscape() &&
"Expect a escaping to noescape conversion");
+ (void)fnType;
+ (void)resultFnType;
SILValue fnValue = fn.getValue();
SILValue result = createConvertEscapeToNoEscape(
loc, fnValue, resultTy, isEscapedByUser, false);
diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp
index 4a7d52a..007a74a 100644
--- a/lib/SILGen/SILGenBuiltin.cpp
+++ b/lib/SILGen/SILGenBuiltin.cpp
@@ -901,6 +901,7 @@
"ValueToBridgeObject should have one sub");
auto &fromTL = SGF.getTypeLowering(subs.getReplacementTypes()[0]);
assert(fromTL.isTrivial() && "Expected a trivial type");
+ (void)fromTL;
SILValue result = SGF.B.createValueToBridgeObject(loc, args[0].getValue());
return SGF.emitManagedRetain(loc, result);
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index e1358da..f7ae959 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -784,15 +784,13 @@
VarDecl *selfDecl) {
CanType selfFormalType = selfDecl->getType()->getCanonicalType();
if (selfFormalType->hasReferenceSemantics())
- return SGF.emitRValueForDecl(loc, selfDecl, selfDecl->getType(),
+ return SGF.emitRValueForDecl(loc, selfDecl, selfFormalType,
AccessSemantics::DirectToStorage,
SGFContext::AllowImmediatePlusZero)
.getAsSingleValue(SGF, loc);
else
- return SGF.emitLValueForDecl(loc, selfDecl,
- selfDecl->getType()->getCanonicalType(),
- AccessKind::Write,
- AccessSemantics::DirectToStorage);
+ return SGF.emitAddressOfLocalVarDecl(loc, selfDecl, selfFormalType,
+ AccessKind::Write);
}
static LValue emitLValueForMemberInit(SILGenFunction &SGF, SILLocation loc,
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index e816a99..6331c4c 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -131,7 +131,8 @@
SILValue closure;
public:
CleanupClosureConstant(SILValue closure) : closure(closure) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.B.emitDestroyValueOperation(l, closure);
}
void dump(SILGenFunction &) const override {
@@ -250,7 +251,8 @@
EndBorrowCleanup(SILValue original, SILValue borrowed)
: original(original), borrowed(borrowed) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.B.createEndBorrow(l, borrowed, original);
}
@@ -271,7 +273,8 @@
public:
ReleaseValueCleanup(SILValue v) : v(v) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
if (v->getType().isAddress())
SGF.B.createDestroyAddr(l, v);
else
@@ -295,7 +298,8 @@
public:
DeallocStackCleanup(SILValue addr) : Addr(addr) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.B.createDeallocStack(l, Addr);
}
@@ -316,7 +320,8 @@
public:
DestroyLocalVariable(VarDecl *var) : Var(var) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.destroyLocalVariable(l, Var);
}
@@ -349,7 +354,8 @@
public:
DeallocateUninitializedLocalVariable(VarDecl *var) : Var(var) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.deallocateUninitializedLocalVariable(l, Var);
}
@@ -1304,7 +1310,8 @@
concreteFormalType(concreteFormalType),
repr(repr) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
switch (repr) {
case ExistentialRepresentation::None:
case ExistentialRepresentation::Class:
@@ -1481,7 +1488,8 @@
state = newState;
}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
getEvaluation(SGF).finish(SGF);
}
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 14dc138..03453e1 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -168,7 +168,8 @@
EndBorrowCleanup(SILValue originalValue, SILValue borrowedValue)
: originalValue(originalValue), borrowedValue(borrowedValue) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.B.createEndBorrow(l, borrowedValue, originalValue);
}
@@ -187,7 +188,7 @@
FormalEvaluationEndBorrowCleanup() : Depth() {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
getEvaluation(SGF).finish(SGF);
}
@@ -276,7 +277,8 @@
EndBorrowArgumentCleanup(SILPHIArgument *arg) : arg(arg) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.B.createEndBorrowArgument(l, arg);
}
@@ -690,56 +692,6 @@
ArrayRef<SILValue>());
}
-/// Emit the specified declaration as an address if possible,
-/// otherwise return null.
-ManagedValue SILGenFunction::emitLValueForDecl(SILLocation loc, VarDecl *var,
- CanType formalRValueType,
- AccessKind accessKind,
- AccessSemantics semantics) {
- // For local decls, use the address we allocated or the value if we have it.
- auto It = VarLocs.find(var);
- if (It != VarLocs.end()) {
- // If this has an address, return it. By-value let's have no address.
- SILValue ptr = It->second.value;
- if (ptr->getType().isAddress())
- return ManagedValue::forLValue(ptr);
-
- // Otherwise, it is an RValue let.
- return ManagedValue();
- }
-
- auto strategy = var->getAccessStrategy(semantics, accessKind, FunctionDC);
-
- switch (strategy.getKind()) {
- case AccessStrategy::Storage:
- // The only kind of stored variable that should make it to here is
- // a global variable. Just invoke its accessor function to get its
- // address.
- return emitGlobalVariableRef(loc, var);
-
- case AccessStrategy::DirectToAccessor:
- case AccessStrategy::DispatchToAccessor: {
- auto accessor = strategy.getAccessor();
- if (accessor != AccessorKind::Address &&
- accessor != AccessorKind::MutableAddress)
- return ManagedValue();
-
- LValue lvalue =
- emitLValueForAddressedNonMemberVarDecl(loc, var, formalRValueType,
- accessKind, semantics);
- return emitAddressOfLValue(loc, std::move(lvalue), accessKind);
- }
-
- case AccessStrategy::MaterializeToTemporary:
- return ManagedValue();
-
- case AccessStrategy::BehaviorStorage:
- // TODO: Behaviors aren't supported on non-instance properties yet.
- llvm_unreachable("not implemented");
- }
- llvm_unreachable("bad access strategy");
-}
-
namespace {
/// This is a simple cleanup class that is only meant to help with delegating
@@ -758,7 +710,7 @@
SILValue value)
: loc(loc), lvalueAddress(lvalueAddress), value(value) {}
- void emit(SILGenFunction &SGF, CleanupLocation) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
SILValue valueToStore = value;
SILType lvalueObjTy = lvalueAddress->getType().getObjectType();
@@ -924,9 +876,6 @@
assert(!ncRefType->is<LValueType>() &&
"RValueEmitter shouldn't be called on lvalues");
- // Any writebacks for this access are tightly scoped.
- FormalEvaluationScope scope(*this);
-
// If this is a decl that we have an lvalue for, produce and return it.
ValueDecl *decl = declRef.getDecl();
@@ -954,140 +903,12 @@
return getUnmanagedRValue(B.createMetatype(loc, getLoweredType(refType)));
}
- // If this is a reference to a var, produce an address or value.
+ // If this is a reference to a var, emit it as an l-value and then load.
if (auto *var = dyn_cast<VarDecl>(decl)) {
assert(!declRef.isSpecialized() &&
"Cannot handle specialized variable references");
- // If this VarDecl is represented as an address, emit it as an lvalue, then
- // perform a load to get the rvalue.
- if (ManagedValue result =
- emitLValueForDecl(loc, var, refType, AccessKind::Read, semantics)) {
- bool guaranteedValid = false;
- IsTake_t shouldTake = IsNotTake;
-
- // We should only end up in this path for local and global variables,
- // i.e. ones whose lifetime is assured for the duration of the evaluation.
- // Therefore, if the variable is a constant, the value is guaranteed
- // valid as well.
- if (var->isLet())
- guaranteedValid = true;
-
- // Protect the lvalue read with access markers. The !is<LValueType> assert
- // above ensures that the "LValue" is actually immutable, so we use an
- // unenforced access marker.
- SILValue destAddr = result.getLValueAddress();
- SILValue accessAddr = UnenforcedFormalAccess::enter(*this, loc, destAddr,
- SILAccessKind::Read);
- auto propagateRValuePastAccess = [&](RValue &&rvalue) {
- // Check if a new begin_access was emitted and returned as the
- // RValue. This means that the load did not actually load. If so, then
- // fix the rvalue to begin_access operand. The end_access cleanup
- // doesn't change. FIXME: this can't happen with sil-opaque-values.
- if (accessAddr != destAddr && rvalue.isComplete()
- && rvalue.isPlusZero(*this) && !isa<TupleType>(rvalue.getType())) {
- auto mv = std::move(rvalue).getScalarValue();
- if (mv.getValue() == accessAddr)
- mv = std::move(mv).transform(
- cast<BeginAccessInst>(accessAddr)->getOperand());
- return RValue(*this, loc, refType, mv);
- }
- return std::move(rvalue);
- };
- // If we have self, see if we are in an 'init' delegation sequence. If so,
- // call out to the special delegation init routine. Otherwise, use the
- // normal RValue emission logic.
- if (var->getName() == getASTContext().Id_self &&
- SelfInitDelegationState != NormalSelf) {
- auto rvalue =
- emitRValueForSelfInDelegationInit(loc, refType, accessAddr, C);
- return propagateRValuePastAccess(std::move(rvalue));
- }
-
- // Avoid computing an abstraction pattern for local variables.
- // This is a slight compile-time optimization, but more importantly
- // it avoids problems where locals don't always have interface types.
- if (var->getDeclContext()->isLocalContext()) {
- auto rvalue = RValue(*this, loc, refType,
- emitLoad(loc, accessAddr, getTypeLowering(refType),
- C, shouldTake, guaranteedValid));
-
- return propagateRValuePastAccess(std::move(rvalue));
- }
-
- // Otherwise, do the full thing where we potentially bridge and
- // reabstract the declaration.
- auto origFormalType = SGM.Types.getAbstractionPattern(var);
- auto rvalue = RValue(*this, loc, refType,
- emitLoad(loc, accessAddr, origFormalType, refType,
- getTypeLowering(refType), C, shouldTake,
- guaranteedValid));
- return propagateRValuePastAccess(std::move(rvalue));
- }
-
- // For local decls, use the address we allocated or the value if we have it.
- auto It = VarLocs.find(decl);
- if (It != VarLocs.end()) {
- // Mutable lvalue and address-only 'let's are LValues.
- assert(!It->second.value->getType().isAddress() &&
- "LValue cases should be handled above");
-
- SILValue Scalar = It->second.value;
-
- // For weak and unowned types, convert the reference to the right
- // pointer.
- if (Scalar->getType().is<ReferenceStorageType>()) {
- Scalar = emitConversionToSemanticRValue(loc, Scalar,
- getTypeLowering(refType));
- // emitConversionToSemanticRValue always produces a +1 strong result.
- return RValue(*this, loc,
- refType, emitManagedRValueWithCleanup(Scalar));
- }
-
- // This is a let, so we can make guarantees, so begin the borrow scope.
- ManagedValue Result = emitManagedBeginBorrow(loc, Scalar);
-
- // If the client can't handle a +0 result, retain it to get a +1.
- // This is a 'let', so we can make guarantees.
- return RValue(*this, loc, refType,
- C.isGuaranteedPlusZeroOk()
- ? Result : Result.copyUnmanaged(*this, loc));
- }
-
- assert(var->getGetter() && "Unknown rvalue case");
-
- SILDeclRef getter = SGM.getGetterDeclRef(var);
-
- ArgumentSource selfSource;
-
- // Global properties have no base or subscript. Static properties
- // use the metatype as their base.
- // FIXME: This has to be dynamically looked up for classes, and
- // dynamically instantiated for generics.
- if (var->isStatic()) {
- auto baseTy = cast<NominalTypeDecl>(var->getDeclContext())
- ->getDeclaredInterfaceType();
- assert(!baseTy->is<BoundGenericType>() &&
- "generic static stored properties not implemented");
- assert((baseTy->getStructOrBoundGenericStruct() ||
- baseTy->getEnumOrBoundGenericEnum()) &&
- "static stored properties for classes/protocols not implemented");
- auto baseMeta = MetatypeType::get(baseTy)->getCanonicalType();
-
- auto metatype = B.createMetatype(loc,
- getLoweredLoadableType(baseMeta));
- auto metatypeMV = ManagedValue::forUnmanaged(metatype);
- auto metatypeRV = RValue(*this, loc, baseMeta, metatypeMV);
- selfSource = ArgumentSource(loc, std::move(metatypeRV));
- }
-
- bool isDirectAccessorUse =
- (semantics == AccessSemantics::DirectToImplementation);
- return emitGetAccessor(loc, getter,
- SGM.getNonMemberVarDeclSubstitutions(var),
- std::move(selfSource),
- /*isSuper=*/false, isDirectAccessorUse,
- RValue(), C);
+ return emitRValueForNonMemberVarDecl(loc, var, refType, semantics, C);
}
// If the referenced decl isn't a VarDecl, it should be a constant of some
@@ -1638,8 +1459,8 @@
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
selfValue =
- SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
- AccessKind::Read, dre->getAccessSemantics());
+ SGF.emitAddressOfLocalVarDecl(dre, vd, dre->getType()->getCanonicalType(),
+ AccessKind::Read);
selfValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
E, dre->getType()->getCanonicalType(),
selfValue.getLValueAddress(), ctx)
@@ -2856,11 +2677,11 @@
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
FES.emplace(SGF);
- selfValue =
- SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
- AccessKind::Read, dre->getAccessSemantics());
+ CanType formalRValueType = dre->getType()->getCanonicalType();
+ selfValue = SGF.emitAddressOfLocalVarDecl(dre, vd, formalRValueType,
+ AccessKind::Read);
selfValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
- loc, dre->getType()->getCanonicalType(),
+ loc, formalRValueType,
selfValue.getLValueAddress(), ctx)
.getAsSingleValue(SGF, loc);
}
@@ -4364,8 +4185,8 @@
// We know that self is a box, so get its address.
SILValue selfAddr =
- SGF.emitLValueForDecl(E, selfDecl, selfTy->getCanonicalType(),
- AccessKind::Write).getLValueAddress();
+ SGF.emitAddressOfLocalVarDecl(E, selfDecl, selfTy->getCanonicalType(),
+ AccessKind::Write).getLValueAddress();
// Handle a nested optional case (see above).
if (innerIsOptional)
@@ -4765,6 +4586,7 @@
void visitTupleExpr(TupleExpr *E) {
auto *TTy = E->getType()->castTo<TupleType>();
assert(TTy->hasLValueType() || TTy->isVoid());
+ (void)TTy;
for (auto &elt : E->getElements()) {
visit(elt);
}
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index d0d5b89..183e34d 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -498,6 +498,7 @@
// Fix up the string parameters to have the right type.
SILType nameArgTy = fnConv.getSILArgumentType(3);
assert(nameArgTy == fnConv.getSILArgumentType(2));
+ (void)nameArgTy;
auto managedName = ManagedValue::forUnmanaged(optName);
SILValue nilValue;
assert(optName->getType() == nameArgTy);
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index d7c69d8..6b49cc2 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -1059,14 +1059,18 @@
SILDeclRef constant,
CanSILFunctionType constantTy);
- /// Emit the specified VarDecl as an LValue if possible, otherwise return
- /// null.
- ManagedValue emitLValueForDecl(SILLocation loc, VarDecl *var,
- CanType formalRValueType,
- AccessKind accessKind,
- AccessSemantics semantics
- = AccessSemantics::Ordinary);
-
+ /// Given that a variable is a local stored variable, return its address.
+ ManagedValue emitAddressOfLocalVarDecl(SILLocation loc, VarDecl *var,
+ CanType formalRValueType,
+ AccessKind accessKind);
+
+ // FIXME: demote this to private state.
+ ManagedValue maybeEmitAddressOfNonMemberVarDecl(SILLocation loc,
+ VarDecl *var,
+ CanType formalRValueType,
+ AccessKind accessKind,
+ AccessSemantics semantics);
+
/// Produce an RValue for a reference to the specified declaration,
/// with the given type and in response to the specified expression. Try to
/// emit into the specified SGFContext to avoid copies (when provided).
@@ -1758,11 +1762,10 @@
LValue emitLValue(Expr *E, AccessKind accessKind,
LValueOptions options = LValueOptions());
- /// Emit a reference to a variable as an lvalue.
- LValue emitLValueForAddressedNonMemberVarDecl(SILLocation loc, VarDecl *var,
- CanType formalRValueType,
- AccessKind accessKind,
- AccessSemantics semantics);
+ RValue emitRValueForNonMemberVarDecl(SILLocation loc, VarDecl *var,
+ CanType formalRValueType,
+ AccessSemantics semantics,
+ SGFContext C);
/// Emit an lvalue that directly refers to the given instance variable
/// (without going through getters or setters).
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index f85301f..970b326 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -44,7 +44,9 @@
LValueWritebackCleanup() : Depth() {}
- void emit(SILGenFunction &SGF, CleanupLocation loc) override {
+ void emit(SILGenFunction &SGF, CleanupLocation loc,
+ ForUnwind_t forUnwind) override {
+ // TODO: honor forUnwind!
auto &evaluation = *SGF.FormalEvalContext.find(Depth);
assert(evaluation.getKind() == FormalAccess::Exclusive);
auto &lvalue = static_cast<ExclusiveBorrowFormalAccess &>(evaluation);
@@ -554,7 +556,8 @@
UnenforcedAccessCleanup() : Depth() {}
- void emit(SILGenFunction &SGF, CleanupLocation loc) override {
+ void emit(SILGenFunction &SGF, CleanupLocation loc,
+ ForUnwind_t forUnwind) override {
auto &evaluation = *SGF.FormalEvalContext.find(Depth);
assert(evaluation.getKind() == FormalAccess::Unenforced);
auto &formalAccess = static_cast<UnenforcedFormalAccess &>(evaluation);
@@ -2185,11 +2188,12 @@
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
auto *vd = cast<ParamDecl>(dre->getDecl());
+ CanType formalRValueType = dre->getType()->getCanonicalType();
ManagedValue selfLValue =
- SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
- AccessKind::Read, dre->getAccessSemantics());
+ SGF.emitAddressOfLocalVarDecl(dre, vd, formalRValueType,
+ AccessKind::Read);
selfLValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
- e, dre->getType()->getCanonicalType(),
+ e, formalRValueType,
selfLValue.getLValueAddress(), ctx)
.getAsSingleValue(SGF, e);
@@ -2276,17 +2280,6 @@
CanType(), typeData, storageType);
}
-LValue
-SILGenFunction::emitLValueForAddressedNonMemberVarDecl(SILLocation loc,
- VarDecl *var,
- CanType formalRValueType,
- AccessKind accessKind,
- AccessSemantics semantics) {
- LValue lv;
- addNonMemberVarDeclAddressorComponent(SGM, var, formalRValueType, lv);
- return lv;
-}
-
static LValue emitLValueForNonMemberVarDecl(SILGenFunction &SGF,
SILLocation loc, VarDecl *var,
CanType formalRValueType,
@@ -2321,8 +2314,9 @@
case AccessStrategy::Storage: {
// If it's a physical value (e.g. a local variable in memory), push its
// address.
- auto address = SGF.emitLValueForDecl(loc, var, formalRValueType,
- accessKind, semantics);
+ auto address =
+ SGF.maybeEmitAddressOfNonMemberVarDecl(loc, var, formalRValueType,
+ accessKind, semantics);
assert(address.isLValue() &&
"physical lvalue decl ref must evaluate to an address");
auto typeData = getPhysicalStorageTypeData(SGF.SGM, var, formalRValueType);
@@ -2357,6 +2351,212 @@
return lv;
}
+/// Emit the specified declaration as an address if possible,
+/// otherwise return null.
+ManagedValue
+SILGenFunction::maybeEmitAddressOfNonMemberVarDecl(SILLocation loc,
+ VarDecl *var,
+ CanType formalRValueType,
+ AccessKind accessKind,
+ AccessSemantics semantics) {
+ // For local decls, use the address we allocated or the value if we have it.
+ auto It = VarLocs.find(var);
+ if (It != VarLocs.end()) {
+ // If this has an address, return it. By-value let's have no address.
+ SILValue ptr = It->second.value;
+ if (ptr->getType().isAddress())
+ return ManagedValue::forLValue(ptr);
+
+ // Otherwise, it is an RValue let.
+ return ManagedValue();
+ }
+
+ auto strategy = var->getAccessStrategy(semantics, accessKind, FunctionDC);
+
+ switch (strategy.getKind()) {
+ case AccessStrategy::Storage:
+ // The only kind of stored variable that should make it to here is
+ // a global variable. Just invoke its accessor function to get its
+ // address.
+ return emitGlobalVariableRef(loc, var);
+
+ case AccessStrategy::DirectToAccessor:
+ case AccessStrategy::DispatchToAccessor: {
+ auto accessor = strategy.getAccessor();
+ if (accessor != AccessorKind::Address &&
+ accessor != AccessorKind::MutableAddress)
+ return ManagedValue();
+
+ LValue lv;
+ addNonMemberVarDeclAddressorComponent(SGM, var, formalRValueType, lv);
+ return emitAddressOfLValue(loc, std::move(lv), accessKind);
+ }
+
+ case AccessStrategy::MaterializeToTemporary:
+ return ManagedValue();
+
+ case AccessStrategy::BehaviorStorage:
+ // TODO: Behaviors aren't supported on non-instance properties yet.
+ llvm_unreachable("not implemented");
+ }
+ llvm_unreachable("bad access strategy");
+}
+
+ManagedValue
+SILGenFunction::emitAddressOfLocalVarDecl(SILLocation loc, VarDecl *var,
+ CanType formalRValueType,
+ AccessKind accessKind) {
+ assert(var->getDeclContext()->isLocalContext());
+ assert(var->getImplInfo().isSimpleStored());
+ auto address =
+ maybeEmitAddressOfNonMemberVarDecl(loc, var, formalRValueType, accessKind,
+ AccessSemantics::Ordinary);
+ assert(address);
+ assert(address.isLValue());
+ return address;
+}
+
+RValue SILGenFunction::emitRValueForNonMemberVarDecl(SILLocation loc,
+ VarDecl *var,
+ CanType formalRValueType,
+ AccessSemantics semantics,
+ SGFContext C) {
+ // Any writebacks for this access are tightly scoped.
+ FormalEvaluationScope scope(*this);
+
+ // If this VarDecl is represented as an address, emit it as an lvalue, then
+ // perform a load to get the rvalue.
+ if (ManagedValue result =
+ maybeEmitAddressOfNonMemberVarDecl(loc, var, formalRValueType,
+ AccessKind::Read, semantics)) {
+ bool guaranteedValid = false;
+ IsTake_t shouldTake = IsNotTake;
+
+ // We should only end up in this path for local and global variables,
+ // i.e. ones whose lifetime is assured for the duration of the evaluation.
+ // Therefore, if the variable is a constant, the value is guaranteed
+ // valid as well.
+ if (var->isLet())
+ guaranteedValid = true;
+
+ // Protect the lvalue read with access markers. The !is<LValueType> assert
+ // above ensures that the "LValue" is actually immutable, so we use an
+ // unenforced access marker.
+ SILValue destAddr = result.getLValueAddress();
+ SILValue accessAddr = UnenforcedFormalAccess::enter(*this, loc, destAddr,
+ SILAccessKind::Read);
+ auto propagateRValuePastAccess = [&](RValue &&rvalue) {
+ // Check if a new begin_access was emitted and returned as the
+ // RValue. This means that the load did not actually load. If so, then
+ // fix the rvalue to begin_access operand. The end_access cleanup
+ // doesn't change. FIXME: this can't happen with sil-opaque-values.
+ if (accessAddr != destAddr && rvalue.isComplete()
+ && rvalue.isPlusZero(*this) && !isa<TupleType>(rvalue.getType())) {
+ auto mv = std::move(rvalue).getScalarValue();
+ if (mv.getValue() == accessAddr)
+ mv = std::move(mv).transform(
+ cast<BeginAccessInst>(accessAddr)->getOperand());
+ return RValue(*this, loc, formalRValueType, mv);
+ }
+ return std::move(rvalue);
+ };
+ // If we have self, see if we are in an 'init' delegation sequence. If so,
+ // call out to the special delegation init routine. Otherwise, use the
+ // normal RValue emission logic.
+ if (var->getName() == getASTContext().Id_self &&
+ SelfInitDelegationState != NormalSelf) {
+ auto rvalue =
+ emitRValueForSelfInDelegationInit(loc, formalRValueType, accessAddr, C);
+ return propagateRValuePastAccess(std::move(rvalue));
+ }
+
+ // Avoid computing an abstraction pattern for local variables.
+ // This is a slight compile-time optimization, but more importantly
+ // it avoids problems where locals don't always have interface types.
+ if (var->getDeclContext()->isLocalContext()) {
+ auto &rvalueTL = getTypeLowering(formalRValueType);
+ auto rvalue = RValue(*this, loc, formalRValueType,
+ emitLoad(loc, accessAddr, rvalueTL,
+ C, shouldTake, guaranteedValid));
+
+ return propagateRValuePastAccess(std::move(rvalue));
+ }
+
+ // Otherwise, do the full thing where we potentially bridge and
+ // reabstract the declaration.
+ auto origFormalType = SGM.Types.getAbstractionPattern(var);
+ auto rvalue = RValue(*this, loc, formalRValueType,
+ emitLoad(loc, accessAddr, origFormalType,
+ formalRValueType,
+ getTypeLowering(formalRValueType),
+ C, shouldTake, guaranteedValid));
+ return propagateRValuePastAccess(std::move(rvalue));
+ }
+
+ // For local decls, use the address we allocated or the value if we have it.
+ auto It = VarLocs.find(var);
+ if (It != VarLocs.end()) {
+ // Mutable lvalue and address-only 'let's are LValues.
+ assert(!It->second.value->getType().isAddress() &&
+ "LValue cases should be handled above");
+
+ SILValue Scalar = It->second.value;
+
+ // For weak and unowned types, convert the reference to the right
+ // pointer.
+ if (Scalar->getType().is<ReferenceStorageType>()) {
+ Scalar = emitConversionToSemanticRValue(loc, Scalar,
+ getTypeLowering(formalRValueType));
+ // emitConversionToSemanticRValue always produces a +1 strong result.
+ return RValue(*this, loc, formalRValueType,
+ emitManagedRValueWithCleanup(Scalar));
+ }
+
+ // This is a let, so we can make guarantees, so begin the borrow scope.
+ ManagedValue Result = emitManagedBeginBorrow(loc, Scalar);
+
+ // If the client can't handle a +0 result, retain it to get a +1.
+ // This is a 'let', so we can make guarantees.
+ return RValue(*this, loc, formalRValueType,
+ C.isGuaranteedPlusZeroOk()
+ ? Result : Result.copyUnmanaged(*this, loc));
+ }
+
+ assert(var->getGetter() && "Unknown rvalue case");
+
+ SILDeclRef getter = SGM.getGetterDeclRef(var);
+
+ ArgumentSource selfSource;
+
+ // Global properties have no base or subscript. Static properties
+ // use the metatype as their base.
+ // FIXME: This has to be dynamically looked up for classes, and
+ // dynamically instantiated for generics.
+ if (var->isStatic()) {
+ auto baseTy = cast<NominalTypeDecl>(var->getDeclContext())
+ ->getDeclaredInterfaceType();
+ assert(!baseTy->is<BoundGenericType>() &&
+ "generic static stored properties not implemented");
+ assert((baseTy->getStructOrBoundGenericStruct() ||
+ baseTy->getEnumOrBoundGenericEnum()) &&
+ "static stored properties for classes/protocols not implemented");
+ auto baseMeta = MetatypeType::get(baseTy)->getCanonicalType();
+
+ auto metatype = B.createMetatype(loc,
+ getLoweredLoadableType(baseMeta));
+ auto metatypeMV = ManagedValue::forUnmanaged(metatype);
+ auto metatypeRV = RValue(*this, loc, baseMeta, metatypeMV);
+ selfSource = ArgumentSource(loc, std::move(metatypeRV));
+ }
+
+ bool isDirectAccessorUse =
+ (semantics == AccessSemantics::DirectToImplementation);
+ return emitGetAccessor(loc, getter,
+ SGM.getNonMemberVarDeclSubstitutions(var),
+ std::move(selfSource),
+ /*isSuper=*/false, isDirectAccessorUse,
+ RValue(), C);
+}
LValue SILGenLValue::visitDiscardAssignmentExpr(DiscardAssignmentExpr *e,
AccessKind accessKind,
diff --git a/lib/SILGen/SILGenMaterializeForSet.cpp b/lib/SILGen/SILGenMaterializeForSet.cpp
index 2d4b300..2948e1f 100644
--- a/lib/SILGen/SILGenMaterializeForSet.cpp
+++ b/lib/SILGen/SILGenMaterializeForSet.cpp
@@ -952,7 +952,8 @@
public:
DeallocateValueBuffer(SILType valueType, SILValue buffer)
: Buffer(buffer), ValueType(valueType) {}
- void emit(SILGenFunction &SGF, CleanupLocation loc) override {
+ void emit(SILGenFunction &SGF, CleanupLocation loc,
+ ForUnwind_t forUnwind) override {
SGF.B.createDeallocValueBuffer(loc, ValueType, Buffer);
}
void dump(SILGenFunction &) const override {
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 3d884bb..ca398e1 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -570,7 +570,7 @@
instanceType = metatypeType.getInstanceType();
auto layout = instanceType.getExistentialLayout();
- if (layout.superclass) {
+ if (layout.explicitSuperclass) {
CanType openedType = ArchetypeType::getAnyOpened(inputSubstType);
SILType loweredOpenedType = SGF.getLoweredType(openedType);
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index 5c358fb..ad65c96 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -45,7 +45,8 @@
CleanupWriteBackToInOut(VarDecl *var, SILValue inoutAddr)
: var(var), inoutAddr(inoutAddr) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
// Assign from the local variable to the inout address with an
// 'autogenerated' copyaddr.
l.markAutoGenerated();
@@ -61,7 +62,8 @@
SILValue box;
public:
StrongReleaseCleanup(SILValue box) : box(box) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l,
+ ForUnwind_t forUnwind) override {
SGF.B.emitDestroyValueOperation(l, box);
}
@@ -105,6 +107,7 @@
== parent->getParent()->mapTypeIntoContext(
SGF.getSILType(parameterInfo))
&& "argument does not have same type as specified by parameter info");
+ (void)parameterInfo;
ManagedValue mv = SGF.B.createInputFunctionArgument(
argType, loc.getAsASTNode<ValueDecl>());
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index dce2e32..54069ba 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -426,7 +426,7 @@
SourceLoc deferLoc;
public:
DeferEscapeCheckerCleanup(SourceLoc deferLoc) : deferLoc(deferLoc) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
assert(false && "Sema didn't catch exit out of a defer?");
}
void dump(SILGenFunction &) const override {
@@ -446,7 +446,7 @@
public:
DeferCleanup(SourceLoc deferLoc, Expr *call)
: deferLoc(deferLoc), call(call) {}
- void emit(SILGenFunction &SGF, CleanupLocation l) override {
+ void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
SGF.Cleanups.pushCleanup<DeferEscapeCheckerCleanup>(deferLoc);
auto TheCleanup = SGF.Cleanups.getTopCleanup();
@@ -1010,5 +1010,5 @@
}
// Branch to the cleanup destination.
- Cleanups.emitBranchAndCleanups(ThrowDest, loc, exn);
+ Cleanups.emitBranchAndCleanups(ThrowDest, loc, exn, IsForUnwind);
}
diff --git a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
index 7264c14..da5c56d 100644
--- a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
@@ -81,6 +81,7 @@
bool isValid() const { return bool(site); }
};
+LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<<(raw_ostream &os, const AddressCapture &capture) {
os << *capture.site.getInstruction() << " captures Arg #"
<< capture.calleeArgIdx;
diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp
index 40688d1..a765859 100644
--- a/lib/SILOptimizer/PassManager/PassManager.cpp
+++ b/lib/SILOptimizer/PassManager/PassManager.cpp
@@ -516,6 +516,7 @@
SILTransform *Tr = Transformations[Idx];
assert((isa<SILFunctionTransform>(Tr) || isa<SILModuleTransform>(Tr)) &&
"Unexpected pass kind!");
+ (void)Tr;
unsigned FirstFuncTrans = Idx;
while (Idx < NumTransforms && isa<SILFunctionTransform>(Transformations[Idx]))
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 2ac6fc2..abc8a5e 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -393,6 +393,7 @@
ConvertCalleeTy->getExtInfo().withNoEscape(false));
assert(Use->get()->getType().castTo<SILFunctionType>() ==
EscapingCalleeTy);
+ (void)EscapingCalleeTy;
Uses.append(CFI->getUses().begin(), CFI->getUses().end());
continue;
}
diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp
index ba043ed..457adc6 100644
--- a/lib/SILOptimizer/Transforms/Outliner.cpp
+++ b/lib/SILOptimizer/Transforms/Outliner.cpp
@@ -1141,7 +1141,7 @@
llvm::DenseMap<CanType, SILDeclRef> BridgeFromObjectiveCache;
public:
- /// Try matching an outlineable pattern from the current current instruction.
+ /// Try matching an outlineable pattern from the current instruction.
OutlinePattern *tryToMatch(SILBasicBlock::iterator CurInst) {
if (BridgedPropertyPattern.matchInstSequence(CurInst))
return &BridgedPropertyPattern;
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 4349af2..d1fa971 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -4501,27 +4501,42 @@
.diagnose();
}
-static bool isRawRepresentableMismatch(Type fromType, Type toType,
- KnownProtocolKind kind,
- const ConstraintSystem &CS) {
+namespace {
+enum class RawRepresentableMismatch {
+ NotApplicable,
+ Convertible,
+ ExactMatch
+};
+}
+
+static RawRepresentableMismatch
+checkRawRepresentableMismatch(Type fromType, Type toType,
+ KnownProtocolKind kind,
+ const ConstraintSystem &CS) {
toType = toType->lookThroughAllOptionalTypes();
fromType = fromType->lookThroughAllOptionalTypes();
// First check if this is an attempt to convert from something to
// raw representable.
if (conformsToKnownProtocol(fromType, kind, CS)) {
- if (isRawRepresentable(toType, kind, CS))
- return true;
+ if (auto rawType = isRawRepresentable(toType, kind, CS)) {
+ if (rawType->isEqual(fromType))
+ return RawRepresentableMismatch::ExactMatch;
+ return RawRepresentableMismatch::Convertible;
+ }
}
// Otherwise, it might be an attempt to convert from raw representable
// to its raw value.
- if (isRawRepresentable(fromType, kind, CS)) {
- if (conformsToKnownProtocol(toType, kind, CS))
- return true;
+ if (auto rawType = isRawRepresentable(fromType, kind, CS)) {
+ if (conformsToKnownProtocol(toType, kind, CS)) {
+ if (rawType->isEqual(toType))
+ return RawRepresentableMismatch::ExactMatch;
+ return RawRepresentableMismatch::Convertible;
+ }
}
- return false;
+ return RawRepresentableMismatch::NotApplicable;
}
static bool diagnoseRawRepresentableMismatch(CalleeCandidateInfo &CCI,
@@ -4546,13 +4561,17 @@
if (!argType || argType->hasTypeVariable() || argType->hasUnresolvedType())
return false;
- ArrayRef<KnownProtocolKind> rawRepresentableProtocols = {
+ KnownProtocolKind rawRepresentableProtocols[] = {
KnownProtocolKind::ExpressibleByStringLiteral,
KnownProtocolKind::ExpressibleByIntegerLiteral};
const auto &CS = CCI.CS;
auto arguments = decomposeArgType(argType, argLabels);
- auto *tupleArgs = dyn_cast<TupleExpr>(argExpr);
+
+ auto bestMatchKind = RawRepresentableMismatch::NotApplicable;
+ const UncurriedCandidate *bestMatchCandidate = nullptr;
+ KnownProtocolKind bestMatchProtocol;
+ size_t bestMatchIndex;
for (auto &candidate : CCI.candidates) {
auto *decl = candidate.getDecl();
@@ -4563,6 +4582,7 @@
continue;
auto parameters = candidate.getParameters();
+ // FIXME: Default arguments?
if (parameters.size() != arguments.size())
continue;
@@ -4573,24 +4593,38 @@
for (auto kind : rawRepresentableProtocols) {
// If trying to convert from raw type to raw representable,
// or vice versa from raw representable (e.g. enum) to raw type.
- if (!isRawRepresentableMismatch(argType, paramType, kind, CS))
- continue;
-
- auto *expr = argExpr;
- if (tupleArgs)
- expr = tupleArgs->getElement(i);
-
- auto diag =
- CS.TC.diagnose(expr->getLoc(), diag::cannot_convert_argument_value,
- argType, paramType);
-
- tryRawRepresentableFixIts(diag, CS, argType, paramType, kind, expr);
- return true;
+ auto matchKind = checkRawRepresentableMismatch(argType, paramType, kind,
+ CS);
+ if (matchKind > bestMatchKind) {
+ bestMatchKind = matchKind;
+ bestMatchProtocol = kind;
+ bestMatchCandidate = &candidate;
+ bestMatchIndex = i;
+ }
}
}
}
- return false;
+ if (bestMatchKind == RawRepresentableMismatch::NotApplicable)
+ return false;
+
+ const Expr *expr = argExpr;
+ if (auto *tupleArgs = dyn_cast<TupleExpr>(argExpr))
+ expr = tupleArgs->getElement(bestMatchIndex);
+ expr = expr->getValueProvidingExpr();
+
+ auto parameters = bestMatchCandidate->getParameters();
+ auto paramType = parameters[bestMatchIndex].getType();
+ auto singleArgType = arguments[bestMatchIndex].getType();
+
+ auto diag = CS.TC.diagnose(expr->getLoc(),
+ diag::cannot_convert_argument_value,
+ singleArgType, paramType);
+
+ tryRawRepresentableFixIts(diag, CS, singleArgType, paramType,
+ bestMatchProtocol, expr);
+ return true;
+
}
// Extract expression for failed argument number
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 66d97d4..b74d292 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1387,10 +1387,10 @@
}
}
- if (layout.superclass) {
+ if (layout.explicitSuperclass) {
auto subKind = std::min(ConstraintKind::Subtype, kind);
- auto result = matchTypes(type1, layout.superclass, subKind, subflags,
- locator);
+ auto result = matchTypes(type1, layout.explicitSuperclass, subKind,
+ subflags, locator);
if (result.isFailure())
return result;
}
@@ -1398,6 +1398,14 @@
for (auto *proto : layout.getProtocols()) {
auto *protoDecl = proto->getDecl();
+ if (auto superclass = protoDecl->getSuperclass()) {
+ auto subKind = std::min(ConstraintKind::Subtype, kind);
+ auto result = matchTypes(type1, superclass, subKind,
+ subflags, locator);
+ if (result.isFailure())
+ return result;
+ }
+
switch (simplifyConformsToConstraint(type1, protoDecl, kind, locator,
subflags)) {
case SolutionKind::Solved:
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index e3367ae..58b2af2 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -808,6 +808,7 @@
IsImplicit));
}
+LLVM_ATTRIBUTE_UNUSED
static bool isSynthesizedComputedProperty(AbstractStorageDecl *storage) {
return (storage->getAttrs().hasAttribute<LazyAttr>() ||
storage->getAttrs().hasAttribute<NSManagedAttr>());
diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp
index 5ad9840..3397329 100644
--- a/lib/Sema/TypeCheckAccess.cpp
+++ b/lib/Sema/TypeCheckAccess.cpp
@@ -956,7 +956,7 @@
return false;
Type ty = inherited.getType();
if (ty->is<ProtocolCompositionType>())
- if (auto superclass = ty->getExistentialLayout().superclass)
+ if (auto superclass = ty->getExistentialLayout().explicitSuperclass)
ty = superclass;
return ty->getAnyNominal() == superclassDecl;
});
@@ -1476,7 +1476,7 @@
return false;
Type ty = inherited.getType();
if (ty->is<ProtocolCompositionType>())
- if (auto superclass = ty->getExistentialLayout().superclass)
+ if (auto superclass = ty->getExistentialLayout().explicitSuperclass)
ty = superclass;
return ty->getAnyNominal() == superclassDecl;
});
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index ef7a897..da318aa 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -304,8 +304,8 @@
/// needs whitespace. If so, emit specific diagnostics for it and return true,
/// otherwise return false.
static bool diagnoseOperatorJuxtaposition(UnresolvedDeclRefExpr *UDRE,
- DeclContext *DC,
- TypeChecker &TC) {
+ DeclContext *DC,
+ TypeChecker &TC) {
Identifier name = UDRE->getName().getBaseIdentifier();
StringRef nameStr = name.str();
if (!name.isOperator() || nameStr.size() < 2)
@@ -403,6 +403,32 @@
}
}
+
+static bool diagnoseRangeOperatorMisspell(UnresolvedDeclRefExpr *UDRE,
+ TypeChecker &TC) {
+ auto name = UDRE->getName().getBaseIdentifier();
+ if (!name.isOperator())
+ return false;
+
+ auto corrected = StringRef();
+ if (name.str() == ".." || name.str() == "...." ||
+ name.str() == ".…" || name.str() == "…" || name.str() == "….")
+ corrected = "...";
+ else if (name.str() == "...<" || name.str() == "....<" ||
+ name.str() == "…<")
+ corrected = "..<";
+
+ if (!corrected.empty()) {
+ TC.diagnose(UDRE->getLoc(), diag::use_unresolved_identifier_corrected,
+ name, true, corrected)
+ .highlight(UDRE->getSourceRange())
+ .fixItReplace(UDRE->getSourceRange(), corrected);
+
+ return true;
+ }
+ return false;
+}
+
static bool findNonMembers(TypeChecker &TC,
ArrayRef<LookupResultEntry> lookupResults,
DeclRefKind refKind, bool breakOnMember,
@@ -455,7 +481,7 @@
}
/// Bind an UnresolvedDeclRefExpr by performing name lookup and
-/// returning the resultant expression. Context is the DeclContext used
+/// returning the resultant expression. Context is the DeclContext used
/// for the lookup.
Expr *TypeChecker::
resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC) {
@@ -473,10 +499,11 @@
auto Lookup = lookupUnqualified(DC, Name, Loc, lookupOptions);
if (!Lookup) {
- // If we failed lookup of an operator, check to see it to see if it is
- // because two operators are juxtaposed e.g. (x*-4) that needs whitespace.
- // If so, emit specific diagnostics for it.
- if (diagnoseOperatorJuxtaposition(UDRE, DC, *this)) {
+ // If we failed lookup of an operator, check to see if this is a range
+ // operator misspelling. Otherwise try to diagnose a juxtaposition
+ // e.g. (x*-4) that needs whitespace.
+ if (diagnoseRangeOperatorMisspell(UDRE, *this) ||
+ diagnoseOperatorJuxtaposition(UDRE, DC, *this)) {
return new (Context) ErrorExpr(UDRE->getSourceRange());
}
@@ -520,9 +547,8 @@
strlen(buffer)))
!= ~0U) {
int length = (buffer - simpleName.get()) - offset;
- char expectedCodepoint;
- if ((expectedCodepoint =
- confusable::tryConvertConfusableCharacterToASCII(codepoint))) {
+ if (auto expectedCodepoint =
+ confusable::tryConvertConfusableCharacterToASCII(codepoint)) {
isConfused = true;
expectedIdentifier += expectedCodepoint;
} else {
@@ -544,7 +570,8 @@
if (auto typo = corrections.claimUniqueCorrection()) {
auto diag = diagnose(Loc, diag::use_unresolved_identifier_corrected,
- Name, Name.isOperator(), typo->CorrectedName);
+ Name, Name.isOperator(),
+ typo->CorrectedName.getBaseIdentifier().str());
diag.highlight(UDRE->getSourceRange());
typo->addFixits(diag);
} else {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index b80ff7d..df67867 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -202,34 +202,6 @@
} // namespace llvm
-/// Determine whether the given declaration can inherit a class.
-static bool canInheritClass(Decl *decl) {
- // Classes can inherit from a class.
- if (isa<ClassDecl>(decl))
- return true;
-
- // Generic type parameters can inherit a class.
- if (isa<GenericTypeParamDecl>(decl))
- return true;
-
- // Associated types can inherit a class.
- if (isa<AssociatedTypeDecl>(decl))
- return true;
-
- return false;
-}
-
-// Add implicit conformances to the given declaration.
-static void addImplicitConformances(
- TypeChecker &tc, Decl *decl,
- llvm::SmallSetVector<ProtocolDecl *, 4> &allProtocols) {
- if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
- SmallVector<ProtocolDecl *, 2> protocols;
- nominal->getImplicitProtocols(protocols);
- allProtocols.insert(protocols.begin(), protocols.end());
- }
-}
-
/// Check that the declaration attributes are ok.
static void validateAttributes(TypeChecker &TC, Decl *D);
@@ -388,9 +360,7 @@
// Check all of the types listed in the inheritance clause.
Type superclassTy;
SourceRange superclassRange;
- llvm::SmallSetVector<ProtocolDecl *, 4> allProtocols;
llvm::SmallDenseMap<CanType, std::pair<unsigned, SourceRange>> inheritedTypes;
- addImplicitConformances(*this, decl, allProtocols);
for (unsigned i = 0, n = inheritedClause.size(); i != n; ++i) {
auto &inherited = inheritedClause[i];
@@ -406,20 +376,6 @@
if (inheritedTy->hasError())
continue;
- // Retrieve the interface type for this inherited type.
- //
- // If we have a generic parameter, mapTypeOutOfContext() might not
- // work yet, if we're calling this while building the generic
- // signature. However, we're also not storing inheritedTy back
- // anywhere, so it's OK to leave it as an archetype.
- //
- // FIXME: Ideally, we wouldn't have code paths that take a mix
- // of archetypes and interface types. Other than generic parameters,
- // the only time we get an interface type here is with invalid
- // circular cases. That should be diagnosed elsewhere.
- if (inheritedTy->hasArchetype() && !isa<GenericTypeParamDecl>(decl))
- inheritedTy = inheritedTy->mapTypeOutOfContext();
-
// Check whether we inherited from the same type twice.
CanType inheritedCanTy = inheritedTy->getCanonicalType();
auto knownType = inheritedTypes.find(inheritedCanTy);
@@ -460,14 +416,13 @@
// Protocols, generic parameters and associated types can inherit
// from subclass existentials, which are "exploded" into their
// corresponding requirements.
+ //
+ // Classes can only inherit from subclass existentials that do not
+ // have a superclass term.
if (isa<ProtocolDecl>(decl) ||
isa<AbstractTypeParamDecl>(decl) ||
(!layout.hasExplicitAnyObject &&
- !layout.superclass)) {
- for (auto proto : layout.getProtocols()) {
- auto *protoDecl = proto->getDecl();
- allProtocols.insert(protoDecl);
- }
+ !layout.explicitSuperclass)) {
continue;
}
@@ -475,13 +430,8 @@
// do not contain an explicit AnyObject member.
if (isa<ClassDecl>(decl) &&
!layout.hasExplicitAnyObject) {
- for (auto proto : layout.getProtocols()) {
- auto *protoDecl = proto->getDecl();
- allProtocols.insert(protoDecl);
- }
-
// Superclass inheritance is handled below.
- inheritedTy = layout.superclass;
+ inheritedTy = layout.explicitSuperclass;
if (!inheritedTy)
continue;
}
@@ -526,10 +476,6 @@
// Record the raw type.
superclassTy = inheritedTy;
superclassRange = inherited.getSourceRange();
-
- // Add the RawRepresentable conformance implied by the raw type.
- allProtocols.insert(getProtocol(decl->getLoc(),
- KnownProtocolKind::RawRepresentable));
continue;
}
@@ -550,7 +496,7 @@
// If the declaration we're looking at doesn't allow a superclass,
// complain.
- if (!canInheritClass(decl)) {
+ if (isa<StructDecl>(decl) || isa<ExtensionDecl>(decl)) {
diagnose(decl->getLoc(),
isa<ExtensionDecl>(decl)
? diag::extension_class_inheritance
@@ -565,7 +511,7 @@
}
// If this is not the first entry in the inheritance clause, complain.
- if (i > 0) {
+ if (isa<ClassDecl>(decl) && i > 0) {
auto removeRange = getRemovalRange(i);
diagnose(inherited.getSourceRange().Start,
diag::superclass_not_first, inheritedTy)
@@ -584,33 +530,13 @@
// We can't inherit from a non-class, non-protocol type.
diagnose(decl->getLoc(),
- canInheritClass(decl)
- ? diag::inheritance_from_non_protocol_or_class
- : diag::inheritance_from_non_protocol,
+ (isa<StructDecl>(decl) || isa<ExtensionDecl>(decl))
+ ? diag::inheritance_from_non_protocol
+ : diag::inheritance_from_non_protocol_or_class,
inheritedTy);
// FIXME: Note pointing to the declaration 'inheritedTy' references?
inherited.setInvalidType(Context);
}
-
- if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
- // Check for circular inheritance.
- // FIXME: The diagnostics here should be improved.
- bool diagnosedCircularity = false;
- for (unsigned i = 0, n = allProtocols.size(); i != n; /*in loop*/) {
- if (allProtocols[i] == proto || allProtocols[i]->inheritsFrom(proto)) {
- if (!diagnosedCircularity) {
- diagnose(proto, diag::circular_protocol_def, proto->getName());
- diagnosedCircularity = true;
- }
-
- allProtocols.remove(allProtocols[i]);
- --n;
- continue;
- }
-
- ++i;
- }
- }
}
/// Retrieve the set of protocols the given protocol inherits.
@@ -618,8 +544,21 @@
getInheritedForCycleCheck(TypeChecker &tc,
ProtocolDecl *proto,
ProtocolDecl **scratch) {
- tc.resolveInheritedProtocols(proto);
- return proto->getInheritedProtocols();
+ TinyPtrVector<ProtocolDecl *> result;
+
+ for (unsigned index : indices(proto->getInherited())) {
+ if (auto type = proto->getInheritedType(index)) {
+ if (type->isExistentialType()) {
+ auto layout = type->getExistentialLayout();
+ for (auto protoTy : layout.getProtocols()) {
+ auto *protoDecl = protoTy->getDecl();
+ result.push_back(protoDecl);
+ }
+ }
+ }
+ }
+
+ return result;
}
/// Retrieve the superclass of the given class.
@@ -3532,14 +3471,6 @@
checkCircularity(TC, PD, diag::circular_protocol_def,
DescriptiveDeclKind::Protocol, path);
- // Make sure the parent protocols have been fully validated.
- for (auto inherited : PD->getLocalProtocols()) {
- TC.validateDecl(inherited);
- for (auto *member : inherited->getMembers())
- if (auto *requirement = dyn_cast<ValueDecl>(member))
- TC.validateDecl(requirement);
- }
-
if (auto *SF = PD->getParentSourceFile()) {
if (auto *tracker = SF->getReferencedNameTracker()) {
bool isNonPrivate =
@@ -3590,6 +3521,9 @@
canRequirementSig->print(llvm::errs());
llvm::errs() << "\n";
}
+
+ // Explicitly calculate this bit.
+ (void) PD->existentialTypeSupported(&TC);
}
void visitVarDecl(VarDecl *VD) {
@@ -6456,6 +6390,9 @@
//
// Returns whether the target conforms to the protocol.
auto evaluateTargetConformanceTo = [&](ProtocolDecl *protocol) {
+ if (!protocol)
+ return false;
+
auto targetType = target->getDeclaredInterfaceType();
if (auto ref = conformsToProtocol(
targetType, protocol, target,
@@ -6493,12 +6430,11 @@
}
} else {
auto argumentNames = member.getArgumentNames();
- if (argumentNames.size() != 1)
+ if (member.isCompoundName() && argumentNames.size() != 1)
return;
- auto argumentName = argumentNames.front();
if (baseName == DeclBaseName::createConstructor() &&
- argumentName == Context.Id_from) {
+ (member.isSimpleName() || argumentNames.front() == Context.Id_from)) {
// init(from:) may be synthesized as part of derived conformance to the
// Decodable protocol.
// If the target should conform to the Decodable protocol, check the
@@ -6507,7 +6443,8 @@
(void)evaluateTargetConformanceTo(decodableProto);
} else if (!baseName.isSpecial() &&
baseName.getIdentifier() == Context.Id_encode &&
- argumentName == Context.Id_to) {
+ (member.isSimpleName() ||
+ argumentNames.front() == Context.Id_to)) {
// encode(to:) may be synthesized as part of derived conformance to the
// Encodable protocol.
// If the target should conform to the Encodable protocol, check the
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index 177533a..7cf2352 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -70,9 +70,7 @@
auto abstractStorage = dyn_cast<AbstractStorageDecl>(member);
assert((method || abstractStorage) && "Not a method or abstractStorage?");
- SubscriptDecl *subscript = nullptr;
- if (abstractStorage)
- subscript = dyn_cast<SubscriptDecl>(abstractStorage);
+ SubscriptDecl *subscript = dyn_cast_or_null<SubscriptDecl>(abstractStorage);
if (!member->hasInterfaceType()) {
auto lazyResolver = ctx.getLazyResolver();
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index ad1d913..0e65a4a 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -220,8 +220,8 @@
// pull out the superclass instead, and use that below.
if (foundInType->isExistentialType()) {
auto layout = foundInType->getExistentialLayout();
- if (layout.superclass) {
- conformingType = layout.superclass;
+ if (auto superclass = layout.getSuperclass()) {
+ conformingType = superclass;
} else {
// Non-subclass existential: don't need to look for further
// conformance or witness.
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 22015c1..4dad072 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -1497,6 +1497,7 @@
} else {
auto parenTy = dyn_cast<ParenType>(elementType.getPointer());
assert(parenTy && "Associated value type is neither paren nor tuple?");
+ (void)parenTy;
auto *subPattern = new (Context) AnyPattern(SourceLoc());
elements.push_back(TuplePatternElt(Identifier(), SourceLoc(),
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 367d8e7..056bf7e 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2783,6 +2783,21 @@
case CheckKind::Access:
case CheckKind::AccessOfSetter: {
+ // Swift 4.2 relaxed some rules for protocol witness matching.
+ //
+ // This meant that it was possible for an optional protocol requirement
+ // to have a witness where previously in Swift 4.1 it did not.
+ //
+ // Since witnesses must be as visible as the protocol, this caused a
+ // source compatibility break if the witness was not sufficiently
+ // visible.
+ //
+ // Work around this by discarding the witness if its not sufficiently
+ // visible.
+ if (!TC.Context.isSwiftVersionAtLeast(5))
+ if (requirement->getAttrs().hasAttribute<OptionalAttr>())
+ return ResolveWitnessResult::Missing;
+
// Avoid relying on the lifetime of 'this'.
const DeclContext *DC = this->DC;
diagnoseOrDefer(requirement, false,
@@ -3796,8 +3811,8 @@
// First, if we have a superclass constraint, the class may conform
// concretely.
- if (layout.superclass) {
- if (auto result = conformsToProtocol(layout.superclass, Proto,
+ if (layout.explicitSuperclass) {
+ if (auto result = conformsToProtocol(layout.explicitSuperclass, Proto,
DC, options)) {
return result;
}
@@ -3806,11 +3821,24 @@
// Next, check if the existential contains the protocol in question.
for (auto P : layout.getProtocols()) {
auto *PD = P->getDecl();
+
// If we found the protocol we're looking for, return an abstract
// conformance to it.
- if (PD == Proto || PD->inheritsFrom(Proto)) {
+ if (PD == Proto)
return ProtocolConformanceRef(Proto);
+
+ // If the protocol has a superclass constraint, we might conform
+ // concretely.
+ if (auto superclass = PD->getSuperclass()) {
+ if (auto result = conformsToProtocol(superclass, Proto,
+ DC, options)) {
+ return result;
+ }
}
+
+ // Now check refined protocols.
+ if (PD->inheritsFrom(Proto))
+ return ProtocolConformanceRef(Proto);
}
return None;
diff --git a/lib/Sema/TypeCheckRequestFunctions.cpp b/lib/Sema/TypeCheckRequestFunctions.cpp
index f973d65..7584fc9 100644
--- a/lib/Sema/TypeCheckRequestFunctions.cpp
+++ b/lib/Sema/TypeCheckRequestFunctions.cpp
@@ -103,7 +103,7 @@
// If we found an existential with a superclass bound, return it.
if (inheritedType->isExistentialType()) {
if (auto superclassType =
- inheritedType->getExistentialLayout().superclass) {
+ inheritedType->getExistentialLayout().explicitSuperclass) {
if (superclassType->getClassOrBoundGenericClass()) {
if (superclassType->hasArchetype())
return superclassType->mapTypeOutOfContext();
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index a9f49a4..2e3ffd6 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -502,13 +502,6 @@
}
}
- /// Convenience declaration to make the intersection operation look more
- /// symmetric.
- static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
- const DeclContext *DC) {
- return a.intersect(b, TC, DC);
- }
-
// Returns the intersection of this space with another. The intersection
// is the largest shared subspace occupied by both arguments.
Space intersect(const Space &other, TypeChecker &TC,
@@ -530,7 +523,7 @@
std::transform(
other.getSpaces().begin(), other.getSpaces().end(),
std::back_inserter(intersectedCases),
- [&](const Space &s) { return intersect(*this, s, TC, DC); });
+ [&](const Space &s) { return this->intersect(s, TC, DC); });
return Space::forDisjunct(intersectedCases);
}
@@ -540,7 +533,7 @@
PAIRCASE (SpaceKind::Disjunct, SpaceKind::BooleanConstant):
PAIRCASE (SpaceKind::Disjunct, SpaceKind::UnknownCase): {
// (S1 || ... || Sn) & S iff (S & S1) && ... && (S & Sn)
- return intersect(other, *this, TC, DC);
+ return other.intersect(*this, TC, DC);
}
PAIRCASE (SpaceKind::Type, SpaceKind::Type): {
// Optimization: The intersection of equal types is that type.
@@ -548,10 +541,10 @@
return other;
} else if (canDecompose(this->getType(), DC)) {
auto decomposition = decompose(TC, DC, this->getType());
- return intersect(decomposition, other, TC, DC);
+ return decomposition.intersect(other, TC, DC);
} else if (canDecompose(other.getType(), DC)) {
auto decomposition = decompose(TC, DC, other.getType());
- return intersect(*this, decomposition, TC, DC);
+ return this->intersect(decomposition, TC, DC);
} else {
return other;
}
@@ -559,7 +552,7 @@
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
if (canDecompose(this->getType(), DC)) {
auto decomposition = decompose(TC, DC, this->getType());
- return intersect(decomposition, other, TC, DC);
+ return decomposition.intersect(other, TC, DC);
} else {
return other;
}
@@ -580,7 +573,7 @@
std::transform(this->getSpaces().begin(), this->getSpaces().end(),
std::back_inserter(newSubSpaces),
[&](const Space &subSpace) {
- return intersect(subSpace, other, TC, DC);
+ return subSpace.intersect(other, TC, DC);
});
return Space::forConstructor(this->getType(), this->getHead(),
this->canDowngradeToWarning(),
@@ -605,7 +598,7 @@
auto j = other.getSpaces().begin();
for (; i != this->getSpaces().end() && j != other.getSpaces().end();
++i, ++j) {
- auto result = intersect(*i, *j, TC, DC);
+ auto result = i->intersect(*j, TC, DC);
// If at least one of the constructor sub-spaces is empty,
// it makes the whole space empty as well.
if (result.isEmpty()) {
@@ -619,7 +612,7 @@
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Type):
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Constructor):
- return intersect(other, *this, TC, DC);
+ return other.intersect(*this, TC, DC);
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::UnknownCase):
if (other.isAllowedButNotRequired())
return other;
@@ -635,7 +628,7 @@
if (canDecompose(other.getType(), DC)) {
auto decomposition = decompose(TC, DC, other.getType());
- return intersect(*this, decomposition, TC, DC);
+ return this->intersect(decomposition, TC, DC);
}
return Space();
}
@@ -645,7 +638,7 @@
return Space();
PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
- return intersect(other, *this, TC, DC);
+ return other.intersect(*this, TC, DC);
}
PAIRCASE (SpaceKind::Empty, SpaceKind::BooleanConstant):
@@ -689,10 +682,10 @@
return Space();
} else if (canDecompose(this->getType(), DC)) {
auto decomposition = decompose(TC, DC, this->getType());
- return intersect(decomposition, other, TC, DC);
+ return decomposition.intersect(other, TC, DC);
} else if (canDecompose(other.getType(), DC)) {
auto decomposition = decompose(TC, DC, other.getType());
- return intersect(*this, decomposition, TC, DC);
+ return this->intersect(decomposition, TC, DC);
}
return Space();
}
@@ -783,7 +776,7 @@
auto &s2 = *j;
// If the intersection of each subspace is ever empty then the
// two spaces are disjoint and their difference is the first space.
- if (intersect(s1, s2, TC, DC).isEmpty()) {
+ if (s1.intersect(s2, TC, DC).isEmpty()) {
return *this;
}
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index cbfa4eb..9415621 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -944,22 +944,6 @@
tc.diagnose(comp->getIdLoc(), diag::no_module_type,
comp->getIdentifier(), moduleType->getModule()->getName());
} else {
- // Situation where class tries to inherit from itself, such
- // would produce an assertion when trying to lookup members of the class.
- //
- // FIXME: Handle this in a more principled way, since there are many
- // similar checks.
- if (auto superClass = parentType->getSuperclass()) {
- if (superClass->isEqual(parentType)) {
- auto decl = parentType->getAnyNominal();
- if (decl) {
- tc.diagnose(decl->getLoc(), diag::circular_class_inheritance,
- decl->getName());
- return ErrorType::get(tc.Context);
- }
- }
- }
-
LookupResult memberLookup;
// Let's try to lookup given identifier as a member of the parent type,
// this allows for more precise diagnostic, which distinguishes between
@@ -2993,8 +2977,8 @@
if (ty->isExistentialType()) {
auto layout = ty->getExistentialLayout();
- if (layout.superclass)
- if (checkSuperclass(tyR->getStartLoc(), layout.superclass))
+ if (auto superclass = layout.explicitSuperclass)
+ if (checkSuperclass(tyR->getStartLoc(), superclass))
continue;
if (!layout.getProtocols().empty())
HasProtocol = true;
@@ -3919,11 +3903,12 @@
auto layout = T->getExistentialLayout();
// See if the superclass is not @objc.
- if (layout.superclass &&
- !layout.superclass->getClassOrBoundGenericClass()->isObjC()) {
- diagnose(TypeRange.Start, diag::not_objc_class_constraint,
- layout.superclass);
- return;
+ if (auto superclass = layout.explicitSuperclass) {
+ if (!superclass->getClassOrBoundGenericClass()->isObjC()) {
+ diagnose(TypeRange.Start, diag::not_objc_class_constraint,
+ superclass);
+ return;
+ }
}
// Find a protocol that is not @objc.
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index bd6b9af..df0f7a4 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1428,6 +1428,7 @@
assert(expectedType == getSILType(Ty, (SILValueCategory)TyCategory) &&
"Type of a global variable does not match GlobalAddr.");
(void)Ty;
+ (void)expectedType;
if (OpCode == SILInstructionKind::GlobalAddrInst) {
ResultVal = Builder.createGlobalAddr(Loc, g);
} else {
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index e6f1e7c..50264ba 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -2433,6 +2433,7 @@
// FIXME: Resilience: could write out vtable for fragile classes.
const DeclContext *assocDC = SILMod->getAssociatedContext();
assert(assocDC && "cannot serialize SIL without an associated DeclContext");
+ (void)assocDC;
for (const SILVTable &vt : SILMod->getVTables()) {
if ((ShouldSerializeAll || vt.isSerialized()) &&
SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(vt.getClass()))
diff --git a/stdlib/private/StdlibUnittest/GetOSVersion.mm b/stdlib/private/StdlibUnittest/GetOSVersion.mm
index 085ed92..e487546 100644
--- a/stdlib/private/StdlibUnittest/GetOSVersion.mm
+++ b/stdlib/private/StdlibUnittest/GetOSVersion.mm
@@ -15,7 +15,7 @@
#include "swift/Runtime/Config.h"
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY extern "C"
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
const char *
getSystemVersionPlistProperty(const char *PropertyName) {
// This function is implemented in Objective-C because Swift does not support
diff --git a/stdlib/private/StdlibUnittest/InterceptTraps.cpp b/stdlib/private/StdlibUnittest/InterceptTraps.cpp
index b1fdd08..e8f7987 100644
--- a/stdlib/private/StdlibUnittest/InterceptTraps.cpp
+++ b/stdlib/private/StdlibUnittest/InterceptTraps.cpp
@@ -33,7 +33,7 @@
_exit(0);
}
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY extern "C"
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
void installTrapInterceptor() {
// Disable buffering on stdout so that everything is printed before crashing.
setbuf(stdout, 0);
diff --git a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp
index 1373304..ce47606 100644
--- a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp
+++ b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp
@@ -12,6 +12,6 @@
#include "swift/Runtime/Config.h"
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY extern "C"
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
void *getPointer(void *x) { return x; }
diff --git a/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm b/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm
index 3426c62..c2d9bf0 100644
--- a/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm
+++ b/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm
@@ -13,7 +13,7 @@
#include <Foundation/Foundation.h>
#include "swift/Runtime/Config.h"
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY
extern "C" void
NSArray_getObjects(NSArray SWIFT_NS_RELEASES_ARGUMENT *_Nonnull nsArray,
id *objects, NSUInteger rangeLocation,
@@ -22,7 +22,7 @@
SWIFT_CC_PLUSONE_GUARD([nsArray release]);
}
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY
extern "C" void
NSDictionary_getObjects(NSDictionary *_Nonnull nsDictionary,
id *objects, id *keys) {
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index 85fd10f..8bd108b 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -198,7 +198,6 @@
var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: range.count, alignment: MemoryLayout<UInt>.alignment)
defer { buffer.deallocate() }
- let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
var enumerated = 0
d.enumerateBytes { (ptr, byteRange, stop) in
if byteRange.upperBound - _offset < range.lowerBound {
diff --git a/stdlib/public/core/FloatingPoint.swift.gyb b/stdlib/public/core/FloatingPoint.swift.gyb
index 2fb08da..60be846 100644
--- a/stdlib/public/core/FloatingPoint.swift.gyb
+++ b/stdlib/public/core/FloatingPoint.swift.gyb
@@ -2185,7 +2185,9 @@
sign: source.sign,
exponentBitPattern: Self.nan.exponentBitPattern,
significandBitPattern: payload | Self.nan.significandBitPattern)
- return payload_ == payload ? (value, true) : (value, false)
+ // We define exactness by equality after roundtripping; since NaN is never
+ // equal to itself, it can never be converted exactly.
+ return (value, false)
}
let exponent = source.exponent
@@ -2299,8 +2301,7 @@
/// exactly.
///
/// If the given floating-point value cannot be represented exactly, the
- /// result is `nil`. A value that is NaN ("not a number") cannot be
- /// represented exactly if its payload cannot be encoded exactly.
+ /// result is `nil`.
///
/// - Parameter value: A floating-point value to be converted.
@inlinable // FIXME(sil-serialize-all)
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 70b3580..8c4b7ba 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -3390,6 +3390,7 @@
size_t numRequirements =
protocol->NumRequirements + WitnessTableFirstRequirementOffset;
assert(numPatternWitnesses <= numRequirements);
+ (void)numRequirements;
// Number of bytes for any private storage used by the conformance itself.
size_t privateSizeInWords = genericTable->WitnessTablePrivateSizeInWords;
diff --git a/stdlib/public/runtime/ReflectionMirror.mm b/stdlib/public/runtime/ReflectionMirror.mm
index b562138..9b8e190 100644
--- a/stdlib/public/runtime/ReflectionMirror.mm
+++ b/stdlib/public/runtime/ReflectionMirror.mm
@@ -257,11 +257,21 @@
// Implementation for structs.
struct StructImpl : ReflectionMirrorImpl {
+ bool isReflectable() {
+ const auto *Struct = static_cast<const StructMetadata *>(type);
+ const auto &Description = Struct->getDescription();
+ return Description->getTypeContextDescriptorFlags().isReflectable();
+ }
+
char displayStyle() {
return 's';
}
intptr_t count() {
+ if (!isReflectable()) {
+ return 0;
+ }
+
auto *Struct = static_cast<const StructMetadata *>(type);
return Struct->getDescription()->NumFields;
}
@@ -399,11 +409,20 @@
// Implementation for classes.
struct ClassImpl : ReflectionMirrorImpl {
+ bool isReflectable() {
+ const auto *Class = static_cast<const ClassMetadata *>(type);
+ const auto &Description = Class->getDescription();
+ return Description->getTypeContextDescriptorFlags().isReflectable();
+ }
+
char displayStyle() {
return 'c';
}
intptr_t count() {
+ if (!isReflectable())
+ return 0;
+
auto *Clas = static_cast<const ClassMetadata*>(type);
auto count = Clas->getDescription()->NumFields;
diff --git a/stdlib/public/stubs/UnicodeNormalization.cpp b/stdlib/public/stubs/UnicodeNormalization.cpp
index 99d2c21..abc4638 100644
--- a/stdlib/public/stubs/UnicodeNormalization.cpp
+++ b/stdlib/public/stubs/UnicodeNormalization.cpp
@@ -78,31 +78,6 @@
#include <mutex>
#include <assert.h>
-static const UCollator *MakeRootCollator() {
- UErrorCode ErrorCode = U_ZERO_ERROR;
- UCollator *root = ucol_open("", &ErrorCode);
- if (U_FAILURE(ErrorCode)) {
- swift::crash("ucol_open: Failure setting up default collation.");
- }
- ucol_setAttribute(root, UCOL_NORMALIZATION_MODE, UCOL_ON, &ErrorCode);
- ucol_setAttribute(root, UCOL_STRENGTH, UCOL_TERTIARY, &ErrorCode);
- ucol_setAttribute(root, UCOL_NUMERIC_COLLATION, UCOL_OFF, &ErrorCode);
- ucol_setAttribute(root, UCOL_CASE_LEVEL, UCOL_OFF, &ErrorCode);
- if (U_FAILURE(ErrorCode)) {
- swift::crash("ucol_setAttribute: Failure setting up default collation.");
- }
- return root;
-}
-
-// According to this thread in the ICU mailing list, it should be safe
-// to assume the UCollator object is thread safe so long as you're only
-// passing it to functions that take a const pointer to it. So, we make it
-// const here to make sure we don't misuse it.
-// http://sourceforge.net/p/icu/mailman/message/27427062/
-static const UCollator *GetRootCollator() {
- return SWIFT_LAZY_CONSTANT(MakeRootCollator());
-}
-
/// Convert the unicode string to uppercase. This function will return the
/// required buffer length as a result. If this length does not match the
/// 'DestinationCapacity' this function must be called again with a buffer of
diff --git a/test/ClangImporter/Inputs/objc_init_generics.h b/test/ClangImporter/Inputs/objc_init_generics.h
new file mode 100644
index 0000000..624c79e
--- /dev/null
+++ b/test/ClangImporter/Inputs/objc_init_generics.h
@@ -0,0 +1,10 @@
+@import Foundation;
+
+@interface MyIntermediateClass : NSObject
+- (nonnull instancetype)initWithDouble:(double)value NS_DESIGNATED_INITIALIZER;
+@end
+
+@interface MyGenericClass<__covariant T> : MyIntermediateClass
+- (nonnull instancetype)initWithValue:(nonnull T)value;
+@end
+
diff --git a/test/ClangImporter/objc_init_generics.swift b/test/ClangImporter/objc_init_generics.swift
new file mode 100644
index 0000000..349eed1
--- /dev/null
+++ b/test/ClangImporter/objc_init_generics.swift
@@ -0,0 +1,17 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules -import-objc-header %S/Inputs/objc_init_generics.h %s -verify
+
+// REQUIRES: objc_interop
+
+// expected-no-diagnostics
+
+import Foundation
+
+class MyConcreteClass: MyGenericClass<NSObject> {
+ // Make sure we don't complain about this "override", because MyGenericClass
+ // was getting an init() that was distinct from its superclass's init() due
+ // to a bug in the Clang importer.
+ init() {
+ super.init(value: NSObject())
+ }
+}
+
diff --git a/test/Compatibility/anyobject_class.swift b/test/Compatibility/anyobject_class.swift
index 1d26d16..8c89eac 100644
--- a/test/Compatibility/anyobject_class.swift
+++ b/test/Compatibility/anyobject_class.swift
@@ -1,5 +1,5 @@
// RUN: %target-typecheck-verify-swift -swift-version 4
-// RUN: not %target-swift-frontend -tyepcheck -swift-version 5
+// RUN: not %target-swift-frontend -typecheck -swift-version 5
protocol P : class, AnyObject { } // expected-warning{{redundant inheritance from 'AnyObject' and Swift 3 'class' keyword}}{{14-21=}}
// expected-warning@-1{{redundant constraint 'Self' : 'AnyObject'}}
diff --git a/test/Compatibility/optional_visibility.swift b/test/Compatibility/optional_visibility.swift
new file mode 100644
index 0000000..f2fa30c
--- /dev/null
+++ b/test/Compatibility/optional_visibility.swift
@@ -0,0 +1,13 @@
+// RUN: %target-typecheck-verify-swift -enable-objc-interop -swift-version 4
+
+@objc protocol Opt {
+ @objc optional func f(callback: @escaping () -> ())
+}
+
+class Conforms : Opt {
+ private func f(callback: () -> ()) {} // expected-note {{'f' declared here}}
+}
+
+func g(x: Conforms) {
+ _ = x.f(callback: {}) // expected-error {{'f' is inaccessible due to 'private' protection level}}
+}
diff --git a/test/Driver/emit_public_type_metadata_accessors.swift b/test/Driver/emit_public_type_metadata_accessors.swift
deleted file mode 100644
index 123c136..0000000
--- a/test/Driver/emit_public_type_metadata_accessors.swift
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: %target-build-swift %s -emit-public-type-metadata-accessors 2>&1 | %FileCheck %s
-
-// CHECK: the option '-emit-public-type-metadata-accessors' is no longer needed and is deprecated; consider removing it
diff --git a/test/Generics/superclass_constraint.swift b/test/Generics/superclass_constraint.swift
index ecbea04..33c373a 100644
--- a/test/Generics/superclass_constraint.swift
+++ b/test/Generics/superclass_constraint.swift
@@ -92,12 +92,11 @@
// expected-warning@-3{{redundant conformance constraint 'T': 'P4'}}
// expected-note@-4{{conformance constraint 'T': 'P4' implied here}}
-protocol P5: A { } // expected-error{{non-class type 'P5' cannot inherit from class 'A'}}
+protocol P5: A { }
protocol P6: A, Other { } // expected-error {{protocol 'P6' cannot be a subclass of both 'Other' and 'A'}}
-// expected-error@-1{{non-class type 'P6' cannot inherit from class 'A'}}
-// expected-error@-2{{non-class type 'P6' cannot inherit from class 'Other'}}
-// expected-note@-3{{superclass constraint 'Self' : 'A' written here}}
+// expected-error@-1{{multiple inheritance from classes 'A' and 'Other'}}
+// expected-note@-2 {{superclass constraint 'Self' : 'A' written here}}
func takeA(_: A) { }
func takeP5<T: P5>(_ t: T) {
diff --git a/test/IDE/print_ast_tc_decls_errors.swift b/test/IDE/print_ast_tc_decls_errors.swift
index 2affaa9..d2b85f5 100644
--- a/test/IDE/print_ast_tc_decls_errors.swift
+++ b/test/IDE/print_ast_tc_decls_errors.swift
@@ -149,15 +149,15 @@
// NO-TYREPR: {{^}}protocol ProtocolWithInheritance2 : <<error type>>, <<error type>> {{{$}}
// TYREPR: {{^}}protocol ProtocolWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {{{$}}
-protocol ProtocolWithInheritance3 : FooClass {} // expected-error {{non-class type 'ProtocolWithInheritance3' cannot inherit from class 'FooClass'}}
-// NO-TYREPR: {{^}}protocol ProtocolWithInheritance3 : <<error type>> {{{$}}
+protocol ProtocolWithInheritance3 : FooClass {}
+// NO-TYREPR: {{^}}protocol ProtocolWithInheritance3 : FooClass {{{$}}
// TYREPR: {{^}}protocol ProtocolWithInheritance3 : FooClass {{{$}}
-protocol ProtocolWithInheritance4 : FooClass, FooProtocol {} // expected-error {{non-class type 'ProtocolWithInheritance4' cannot inherit from class 'FooClass'}}
-// NO-TYREPR: {{^}}protocol ProtocolWithInheritance4 : <<error type>>, FooProtocol {{{$}}
+protocol ProtocolWithInheritance4 : FooClass, FooProtocol {}
+// NO-TYREPR: {{^}}protocol ProtocolWithInheritance4 : FooClass, FooProtocol {{{$}}
// TYREPR: {{^}}protocol ProtocolWithInheritance4 : FooClass, FooProtocol {{{$}}
-protocol ProtocolWithInheritance5 : FooClass, BarClass {} // expected-error {{non-class type 'ProtocolWithInheritance5' cannot inherit from class 'FooClass'}} expected-error {{non-class type 'ProtocolWithInheritance5' cannot inherit from class 'BarClass'}} expected-error{{protocol 'ProtocolWithInheritance5' cannot be a subclass of both 'BarClass' and 'FooClass'}} // expected-note{{superclass constraint 'Self' : 'FooClass' written here}}
+protocol ProtocolWithInheritance5 : FooClass, BarClass {} // expected-error{{multiple inheritance from classes 'FooClass' and 'BarClass'}} expected-error{{protocol 'ProtocolWithInheritance5' cannot be a subclass of both 'BarClass' and 'FooClass'}} // expected-note{{superclass constraint 'Self' : 'FooClass' written here}}
// NO-TYREPR: {{^}}protocol ProtocolWithInheritance5 : <<error type>>, <<error type>> {{{$}}
// TYREPR: {{^}}protocol ProtocolWithInheritance5 : FooClass, BarClass {{{$}}
diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift
index b68eca2..06b1e88 100644
--- a/test/IRGen/abitypes.swift
+++ b/test/IRGen/abitypes.swift
@@ -89,6 +89,7 @@
// armv7-ios: [[RESULT:%.*]] = call float bitcast (void ()* @objc_msgSend to float (i8*, i8*, [4 x i32])*)(i8* [[SELFCAST]], i8* [[SEL]], [4 x i32] [[LOADED]])
// armv7s-ios: define hidden swiftcc float @"$S8abitypes3FooC17getXFromRectSwift{{[_0-9a-zA-Z]*}}F"(float, float, float, float, [[SELF:%.*]]* swiftself) {{.*}} {
+ // armv7s-ios: [[DEBUGVAR:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4
// armv7s-ios: [[COERCED:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4
// armv7s-ios: [[SEL:%.*]] = load i8*, i8** @"\01L_selector(getXFromRect:)", align 4
// armv7s-ios: [[CAST:%.*]] = bitcast [[MYRECT]]* [[COERCED]] to [4 x i32]*
diff --git a/test/IRGen/resilience_bypass.swift b/test/IRGen/resilience_bypass.swift
index e8492e7..4a17e95 100644
--- a/test/IRGen/resilience_bypass.swift
+++ b/test/IRGen/resilience_bypass.swift
@@ -4,13 +4,37 @@
// RUN: %target-swift-frontend -emit-module -emit-module-path=%t/second.swiftmodule -module-name=second %S/Inputs/resilience_bypass/second.swift -I %t
// RUN: %target-swift-frontend -emit-ir -enable-resilience-bypass %s -I %t | %FileCheck %s -DINT=i%target-ptrsize
+import first
import second
// CHECK: define{{( dllexport| protected)?}} swiftcc [[INT]] @"$S17resilience_bypass7getSizeSiyF"() {{.*}} {
// CHECK-NEXT: entry:
+
+// FIXME: The metadata accessor call is not necessary
+// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$S6second1EOMa"
+// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
+
// CHECK-NEXT: ret [[INT]] {{5|9}}
// CHECK-NEXT: }
public func getSize() -> Int {
return MemoryLayout<E>.size
}
+
+public func makeE(_ s: S) -> E {
+ return .b(s)
+}
+
+// CHECK: define{{( dllexport| protected)?}} swiftcc void @"$S17resilience_bypass7makeAnyyyp5first1SVF"(
+// CHECK-NEXT: entry:
+
+// Make sure we form the existential using the result of the metadata accessor, instead of
+// directly using the address of the metadata global.
+//
+// FIXME: The metadata global should have hidden linkage to rule out this kind of bug.
+
+// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$S6second1EOMa"
+
+public func makeAny(_ s: S) -> Any {
+ return makeE(s)
+}
diff --git a/test/Interpreter/enforce_exclusive_access.swift b/test/Interpreter/enforce_exclusive_access.swift
index 3ddcb2c..7453be5 100644
--- a/test/Interpreter/enforce_exclusive_access.swift
+++ b/test/Interpreter/enforce_exclusive_access.swift
@@ -3,6 +3,7 @@
//
// RUN: %target-run %t/a.out
// REQUIRES: executable_test
+// REQUIRES: rdar41660554
// Tests for traps at run time when enforcing exclusive access.
diff --git a/test/Migrator/Inputs/Cities.swift b/test/Migrator/Inputs/Cities.swift
index edc531a..652cab9 100644
--- a/test/Migrator/Inputs/Cities.swift
+++ b/test/Migrator/Inputs/Cities.swift
@@ -77,7 +77,8 @@
}
public struct AwesomeCityAttribute: RawRepresentable {
- public init?(rawValue: String) { self.rawValue = rawValue }
+ public init(rawValue: String) { self.rawValue = rawValue }
+ public init(_ rawValue: String) { self.rawValue = rawValue }
public var rawValue: String
public typealias RawValue = String
}
@@ -86,6 +87,7 @@
public struct Attribute: RawRepresentable {
public static let KnownAttr = Wrapper.Attribute(rawValue: "")
public init(rawValue: String) { self.rawValue = rawValue }
+ public init(_ rawValue: String) { self.rawValue = rawValue }
public var rawValue: String
public typealias RawValue = String
}
diff --git a/test/Migrator/string-representable.swift b/test/Migrator/string-representable.swift
index 2178340..e9d31b2 100644
--- a/test/Migrator/string-representable.swift
+++ b/test/Migrator/string-representable.swift
@@ -49,11 +49,15 @@
func revert(_ a: AwesomeCityAttribute, b: Wrapper.Attribute) {
_ = AwesomeCityAttribute(rawValue: "somevalue")
_ = AwesomeCityAttribute.init(rawValue: "somevalue")
+ _ = AwesomeCityAttribute("somevalue")
+ _ = AwesomeCityAttribute.init("somevalue")
_ = a.rawValue
_ = Wrapper.Attribute(rawValue: "somevalue")
_ = Wrapper.Attribute.init(rawValue: "somevalue")
_ = b.rawValue
_ = Wrapper.Attribute.KnownAttr.rawValue
+ _ = Wrapper.Attribute("somevalue")
+ _ = Wrapper.Attribute.init("somevalue")
}
diff --git a/test/Migrator/string-representable.swift.expected b/test/Migrator/string-representable.swift.expected
index 9108b47..318e369 100644
--- a/test/Migrator/string-representable.swift.expected
+++ b/test/Migrator/string-representable.swift.expected
@@ -49,11 +49,15 @@
func revert(_ a: AwesomeCityAttribute, b: Wrapper.Attribute) {
_ = "somevalue"
_ = "somevalue"
+ _ = "somevalue"
+ _ = "somevalue"
_ = a
_ = "somevalue"
_ = "somevalue"
_ = b
_ = NewAttributeWrapper.NewKnownAttr
+ _ = "somevalue"
+ _ = "somevalue"
}
diff --git a/test/Parse/invalid.swift b/test/Parse/invalid.swift
index d76269b..428a5be 100644
--- a/test/Parse/invalid.swift
+++ b/test/Parse/invalid.swift
@@ -140,7 +140,7 @@
}
let x: () = ()
-!() // expected-error {{missing argument for parameter #1 in call}}
+!() // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
!(()) // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
!(x) // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
!x // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
diff --git a/test/Sema/enum_raw_representable.swift b/test/Sema/enum_raw_representable.swift
index a92d185..27820c8 100644
--- a/test/Sema/enum_raw_representable.swift
+++ b/test/Sema/enum_raw_representable.swift
@@ -120,7 +120,7 @@
// expected-error@-1 {{reference to member 'baz' cannot be resolved without a contextual type}}
rdar32431165_1("")
-// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{15-15=E_32431165(rawValue: }} {{19-19=)}}
+// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{16-16=E_32431165(rawValue: }} {{18-18=)}}
rdar32431165_1(42, "")
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{20-20=E_32431165(rawValue: }} {{22-22=)}}
@@ -129,7 +129,7 @@
func rdar32431165_2(_: Int, _: String) {}
rdar32431165_2(E_32431165.bar)
-// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{15-15=}} {{31-31=.rawValue}}
+// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{16-16=}} {{30-30=.rawValue}}
rdar32431165_2(42, E_32431165.bar)
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{20-20=}} {{34-34=.rawValue}}
@@ -145,6 +145,29 @@
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{11-11=}} {{17-17=.rawValue}}
}
+func sr8150_helper1(_: Int) {}
+func sr8150_helper1(_: Double) {}
+
+func sr8150_helper2(_: Double) {}
+func sr8150_helper2(_: Int) {}
+
+func sr8150_helper3(_: Foo) {}
+func sr8150_helper3(_: Bar) {}
+
+func sr8150_helper4(_: Bar) {}
+func sr8150_helper4(_: Foo) {}
+
+func sr8150(bar: Bar) {
+ sr8150_helper1(bar)
+ // expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{18-18=}} {{21-21=.rawValue}}
+ sr8150_helper2(bar)
+ // expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{18-18=}} {{21-21=.rawValue}}
+ sr8150_helper3(0.0)
+ // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Bar'}} {{18-18=Bar(rawValue: }} {{21-21=)}}
+ sr8150_helper4(0.0)
+ // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Bar'}} {{18-18=Bar(rawValue: }} {{21-21=)}}
+}
+
struct NotEquatable { }
diff --git a/test/attr/attr_dynamic_infer.swift b/test/attr/attr_dynamic_infer.swift
index cd0c9c3..3264184 100644
--- a/test/attr/attr_dynamic_infer.swift
+++ b/test/attr/attr_dynamic_infer.swift
@@ -1,16 +1,16 @@
-// RUN: %target-swift-ide-test -print-ast-typechecked -source-filename=%s -print-implicit-attrs -disable-objc-attr-requires-foundation-module -swift-version 3 | %FileCheck %s
+// RUN: %target-swift-ide-test -print-ast-typechecked -source-filename=%s -print-implicit-attrs -disable-objc-attr-requires-foundation-module | %FileCheck %s
@objc class Super {
- func baseFoo() {}
+ @objc dynamic func baseFoo() {}
}
// CHECK: extension Super {
extension Super {
// CHECK: @objc dynamic func foo
- func foo() { }
+ @objc func foo() { }
// CHECK: @objc dynamic var prop: Super
- var prop: Super {
+ @objc var prop: Super {
// CHECK: @objc dynamic get
get { return Super() }
// CHECK: @objc dynamic set
@@ -18,7 +18,7 @@
}
// CHECK: @objc dynamic subscript(sup: Super) -> Super
- subscript(sup: Super) -> Super {
+ @objc subscript(sup: Super) -> Super {
// CHECK: @objc dynamic get
get { return sup }
// CHECK: @objc dynamic set
@@ -60,10 +60,10 @@
extension FinalTests {
// CHECK: @objc final func foo
- final func foo() { }
+ @objc final func foo() { }
// CHECK: @objc final var prop: Super
- final var prop: Super {
+ @objc final var prop: Super {
// CHECK: @objc final get
get { return Super() }
// CHECK: @objc final set
@@ -71,7 +71,7 @@
}
// CHECK: @objc final subscript(sup: Super) -> Super
- final subscript(sup: Super) -> Super {
+ @objc final subscript(sup: Super) -> Super {
// CHECK: @objc final get
get { return sup }
// CHECK: @objc final set
@@ -79,9 +79,9 @@
}
// CHECK: @objc static var x
- static var x: Int = 0
+ @objc static var x: Int = 0
// CHECK: @objc static func bar
- static func bar() { }
+ @objc static func bar() { }
}
diff --git a/test/decl/class/override.swift b/test/decl/class/override.swift
index 1fa1df1..b5b1962 100644
--- a/test/decl/class/override.swift
+++ b/test/decl/class/override.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -parse-as-library -enable-objc-interop -swift-version 3
+// RUN: %target-typecheck-verify-swift -parse-as-library -enable-objc-interop
class A {
func ret_sametype() -> Int { return 0 }
@@ -161,23 +161,23 @@
}
@objc class IUOTestBaseClass {
- func none() {}
+ @objc func none() {}
- func oneA(_: AnyObject) {}
- func oneB(x: AnyObject) {}
- func oneC(_ x: AnyObject) {}
+ @objc func oneA(_: AnyObject) {}
+ @objc func oneB(x: AnyObject) {}
+ @objc func oneC(_ x: AnyObject) {}
- func manyA(_: AnyObject, _: AnyObject) {}
- func manyB(_ a: AnyObject, b: AnyObject) {}
- func manyC(var a: AnyObject, // expected-error {{'var' as a parameter attribute is not allowed}}
- var b: AnyObject) {} // expected-error {{'var' as a parameter attribute is not allowed}}
+ @objc func manyA(_: AnyObject, _: AnyObject) {}
+ @objc func manyB(_ a: AnyObject, b: AnyObject) {}
+ @objc func manyC(var a: AnyObject, // expected-error {{'var' as a parameter attribute is not allowed}}
+ var b: AnyObject) {} // expected-error {{'var' as a parameter attribute is not allowed}}
- func result() -> AnyObject? { return nil }
- func both(_ x: AnyObject) -> AnyObject? { return x }
+ @objc func result() -> AnyObject? { return nil }
+ @objc func both(_ x: AnyObject) -> AnyObject? { return x }
- init(_: AnyObject) {}
- init(one: AnyObject) {}
- init(a: AnyObject, b: AnyObject) {}
+ @objc init(_: AnyObject) {}
+ @objc init(one: AnyObject) {}
+ @objc init(a: AnyObject, b: AnyObject) {}
}
class IUOTestSubclass : IUOTestBaseClass {
diff --git a/test/decl/func/operator.swift b/test/decl/func/operator.swift
index 9d87916..3c7bc1b 100644
--- a/test/decl/func/operator.swift
+++ b/test/decl/func/operator.swift
@@ -355,3 +355,13 @@
if x == x && x = x { } // expected-error{{expression is not assignable: '&&' returns immutable value}}
}
}
+
+_ = 1..<1 // OK
+_ = 1…1 // expected-error {{use of unresolved operator '…'; did you mean '...'?}} {{6-9=...}}
+_ = 1….1 // expected-error {{use of unresolved operator '…'; did you mean '...'?}} {{6-9=...}}
+_ = 1.…1 // expected-error {{use of unresolved operator '.…'; did you mean '...'?}} {{6-10=...}}
+_ = 1…<1 // expected-error {{use of unresolved operator '…<'; did you mean '..<'?}} {{6-10=..<}}
+_ = 1..1 // expected-error {{use of unresolved operator '..'; did you mean '...'?}} {{6-8=...}}
+_ = 1....1 // expected-error {{use of unresolved operator '....'; did you mean '...'?}} {{6-10=...}}
+_ = 1...<1 // expected-error {{use of unresolved operator '...<'; did you mean '..<'?}} {{6-10=..<}}
+_ = 1....<1 // expected-error {{use of unresolved operator '....<'; did you mean '..<'?}} {{6-11=..<}}
diff --git a/test/decl/inherit/inherit.swift b/test/decl/inherit/inherit.swift
index a675255..10e193e 100644
--- a/test/decl/inherit/inherit.swift
+++ b/test/decl/inherit/inherit.swift
@@ -34,7 +34,7 @@
struct S : A { } // expected-error{{non-class type 'S' cannot inherit from class 'A'}}
// Protocol inheriting a class
-protocol Q : A { } // expected-error{{non-class type 'Q' cannot inherit from class 'A'}}
+protocol Q : A { }
// Extension inheriting a class
extension C : A { } // expected-error{{extension of type 'C' cannot inherit from class 'A'}}
@@ -44,14 +44,12 @@
// Protocol composition in inheritance clauses
struct S3 : P, P & Q { } // expected-error {{redundant conformance of 'S3' to protocol 'P'}}
- // expected-error @-1 {{'Q' requires that 'S3' inherit from 'A'}}
- // expected-note @-2 {{requirement specified as 'Self' : 'A' [with Self = S3]}}
- // expected-note @-3 {{'S3' declares conformance to protocol 'P' here}}
+ // expected-error @-1 {{non-class type 'S3' cannot conform to class protocol 'Q'}}
+ // expected-note @-2 {{'S3' declares conformance to protocol 'P' here}}
struct S4 : P, P { } // expected-error {{duplicate inheritance from 'P'}}
struct S6 : P & { } // expected-error {{expected identifier for type name}}
struct S7 : protocol<P, Q> { } // expected-error {{'protocol<...>' composition syntax has been removed; join the protocols using '&'}}
- // expected-error @-1 {{'Q' requires that 'S7' inherit from 'A'}}
- // expected-note @-2 {{requirement specified as 'Self' : 'A' [with Self = S7]}}
+ // expected-error @-1 {{non-class type 'S7' cannot conform to class protocol 'Q'}}
class GenericBase<T> {}
diff --git a/test/decl/nested/protocol.swift b/test/decl/nested/protocol.swift
index d886754..4bb32f0 100644
--- a/test/decl/nested/protocol.swift
+++ b/test/decl/nested/protocol.swift
@@ -66,12 +66,10 @@
class OuterClass {
protocol InnerProtocol : OuterClass { }
- // expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OuterClass'}}
- // expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
+ // expected-error@-1{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
}
class OtherGenericClass<T> {
protocol InnerProtocol : OtherGenericClass { }
- // expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OtherGenericClass<T>'}}
- // expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
+ // expected-error@-1{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
}
diff --git a/test/decl/nested/type_in_function.swift b/test/decl/nested/type_in_function.swift
index 509dcf8..97adaef 100644
--- a/test/decl/nested/type_in_function.swift
+++ b/test/decl/nested/type_in_function.swift
@@ -128,9 +128,10 @@
func genericFunction<T>(t: T) {
class First : Second<T>.UnknownType { }
// expected-error@-1 {{type 'First' cannot be nested in generic function 'genericFunction(t:)'}}
+ // expected-error@-2 {{'UnknownType' is not a member type of 'Second<T>'}}
class Second<T> : Second { }
// expected-error@-1 {{type 'Second' cannot be nested in generic function 'genericFunction(t:)'}}
- // expected-error@-2 2 {{'Second' inherits from itself}}
+ // expected-error@-2 {{'Second' inherits from itself}}
}
// Spurious "Self or associated type requirements" diagnostic.
diff --git a/test/decl/protocol/protocols.swift b/test/decl/protocol/protocols.swift
index 2e7dc74..a785ae5 100644
--- a/test/decl/protocol/protocols.swift
+++ b/test/decl/protocol/protocols.swift
@@ -39,7 +39,7 @@
}
protocol Bogus : Int {}
-// expected-error@-1{{inheritance from non-protocol type 'Int'}}
+// expected-error@-1{{inheritance from non-protocol, non-class type 'Int'}}
// expected-error@-2{{type 'Self' constrained to non-protocol, non-class type 'Int'}}
// Explicit conformance checks (successful).
@@ -98,15 +98,13 @@
// Circular protocols
-protocol CircleMiddle : CircleStart { func circle_middle() } // expected-error 2 {{protocol 'CircleMiddle' refines itself}}
+protocol CircleMiddle : CircleStart { func circle_middle() } // expected-error {{protocol 'CircleMiddle' refines itself}}
protocol CircleStart : CircleEnd { func circle_start() }
// expected-note@-1{{protocol 'CircleStart' declared here}}
-// expected-error@-2{{protocol 'CircleStart' refines itself}}
protocol CircleEnd : CircleMiddle { func circle_end()} // expected-note{{protocol 'CircleEnd' declared here}}
-// expected-error@-1{{protocol 'CircleEnd' refines itself}}
protocol CircleEntry : CircleTrivial { }
-protocol CircleTrivial : CircleTrivial { } // expected-error 2{{protocol 'CircleTrivial' refines itself}}
+protocol CircleTrivial : CircleTrivial { } // expected-error {{protocol 'CircleTrivial' refines itself}}
struct Circle {
func circle_start() {}
diff --git a/test/decl/protocol/req/optional_visibility.swift b/test/decl/protocol/req/optional_visibility.swift
new file mode 100644
index 0000000..13c5dca
--- /dev/null
+++ b/test/decl/protocol/req/optional_visibility.swift
@@ -0,0 +1,15 @@
+// RUN: %target-typecheck-verify-swift -enable-objc-interop -swift-version 5
+
+@objc protocol Opt {
+ @objc optional func f(callback: @escaping () -> ())
+}
+
+class Conforms : Opt {
+ private func f(callback: () -> ()) {}
+ // expected-error@-1 {{method 'f(callback:)' must be declared internal because it matches a requirement in internal protocol 'Opt'}}
+ // expected-note@-2 {{mark the instance method as 'internal' to satisfy the requirement}}
+}
+
+func g(x: Conforms) {
+ _ = x.f(callback: {})
+}
diff --git a/test/decl/protocol/special/coding/class_codable_inherited.swift b/test/decl/protocol/special/coding/class_codable_inherited.swift
new file mode 100644
index 0000000..c19d32c
--- /dev/null
+++ b/test/decl/protocol/special/coding/class_codable_inherited.swift
@@ -0,0 +1,25 @@
+// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+
+class SR8083_Base: Codable {
+ var thing: String { return "Abstract" }
+}
+
+class SR8083_Sub: SR8083_Base {
+ override var thing: String { return "Yo" }
+}
+
+func sr8083(decoder: Decoder) throws {
+ _ = try SR8083_Sub(from: decoder)
+}
+
+// CHECK-LABEL: sil_vtable SR8083_Base {
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfc // SR8083_Base.init()
+// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfC
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfc // SR8083_Base.init(from:)
+// CHECK: {{^}$}}
+
+// CHECK-LABEL: sil_vtable SR8083_Sub {
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfc [override] // SR8083_Sub.init()
+// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfC [override] // SR8083_Sub.__allocating_init(from:)
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfc [override] // SR8083_Sub.init(from:)
+// CHECK: {{^}$}}
diff --git a/test/lit.cfg b/test/lit.cfg
index 21d6cb0..10a0f0d 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -120,7 +120,7 @@
elif run_os == 'tvos':
return "simctl spawn 'Apple TV 4K'"
elif run_os == 'watchos':
- return "simctl spawn 'Apple Watch - 42mm'"
+ return "simctl spawn 'Apple Watch Series 3 - 38mm'"
else:
lit_config.fatal("Unknown simulator OS %r" % run_os)
diff --git a/test/stdlib/Reflection_objc.swift b/test/stdlib/Reflection_objc.swift
index 414221c..3ce8008 100644
--- a/test/stdlib/Reflection_objc.swift
+++ b/test/stdlib/Reflection_objc.swift
@@ -14,6 +14,7 @@
import Swift
import Foundation
+import simd
#if os(macOS)
import AppKit
@@ -284,6 +285,11 @@
// CHECK-NEXT: HasStringQLO overboard
// CHECK-NEXT: CanaryBase overboard
+// simd types get no reflection info, so should have no mirror children
+let x = float4(0)
+print("float4 has \(Mirror(reflecting: x).children.count) children")
+// CHECK-NEXT: float4 has 0 children
+
// CHECK-LABEL: and now our song is done
print("and now our song is done")
diff --git a/test/type/subclass_composition.swift b/test/type/subclass_composition.swift
index c1beafc..9fa66df 100644
--- a/test/type/subclass_composition.swift
+++ b/test/type/subclass_composition.swift
@@ -449,10 +449,10 @@
protocol ProtoConstraintsSelfToClass where Self : Base<Int> {}
-protocol ProtoRefinesClass : Base<Int> {} // FIXME expected-error {{}}
+protocol ProtoRefinesClass : Base<Int> {}
protocol ProtoRefinesClassAndProtocolAlias : BaseIntAndP2 {}
protocol ProtoRefinesClassAndProtocolDirect : Base<Int> & P2 {}
-protocol ProtoRefinesClassAndProtocolExpanded : Base<Int>, P2 {} // FIXME expected-error {{}}
+protocol ProtoRefinesClassAndProtocolExpanded : Base<Int>, P2 {}
class ClassConformsToClassProtocolBad1 : ProtoConstraintsSelfToClass {}
// expected-error@-1 {{'ProtoConstraintsSelfToClass' requires that 'ClassConformsToClassProtocolBad1' inherit from 'Base<Int>'}}
diff --git a/utils/bug_reducer/README.md b/utils/bug_reducer/README.md
index 23b8615..4ca63cc 100644
--- a/utils/bug_reducer/README.md
+++ b/utils/bug_reducer/README.md
@@ -62,7 +62,7 @@
Then the bug_reducer will first attempt to reduce the passes. Then, it will
attempt to reduce the test case by splitting the module and only optimizing part
-of it. The output will be look something like:
+of it. The output will look something like:
*** Successfully Reduced file!
*** Final File: ${FINAL_SIB_FILE}
diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
index 1da8583..9b30b77 100644
--- a/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
+++ b/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
@@ -1,4 +1,9 @@
-// RUN: %target-swift-frontend %s -typecheck -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify
+
+// Note: this used to type check successfully in Swift 3. In Swift 4, it produces
+// an error, so probably this test isn't testing anything useful anymore, since
+// we already exercise many such cases in test/Constraints/tuple_arguments.swift.
+// However, there's no harm in keeping it around in case it exposes other bugs later.
public enum R<V> {
case value(V)
@@ -14,7 +19,7 @@
public func test() -> P<I, [O]> {
return P<I, [O]> { input in
var output: [O] = []
- _ = R<([O], I)>.value(output, input)
+ _ = R<([O], I)>.value(output, input) // expected-error {{enum element 'value' expects a single parameter of type '([O], I)'}}
return R<([O], I)>.value((output, input))
}
}
diff --git a/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift b/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift
index 3a86462..7bb9057 100644
--- a/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift
+++ b/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
// rdar://problem/19792730
@@ -6,17 +6,17 @@
Expected : Sequence,
Actual : Sequence,
T : Comparable
+>(expected: Expected, actual: Actual)
where
Expected.Iterator.Element == Actual.Iterator.Element,
- Expected.Iterator.Element == T
->(expected: Expected, actual: Actual) {}
+ Expected.Iterator.Element == T {}
public func foo<
Expected : Sequence,
Actual : Sequence,
T : Comparable
+>(expected: Expected, actual: Actual)
where
Expected.Iterator.Element == Actual.Iterator.Element,
- Expected.Iterator.Element == (T, T)
->(expected: Expected, actual: Actual) {}
+ Expected.Iterator.Element == (T, T) {}
diff --git a/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift b/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift
index 019c7aa..e71078e 100644
--- a/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift
+++ b/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
// rdar://problem/19792768
@@ -6,10 +6,10 @@
Expected : Sequence,
Actual : Sequence,
T : Comparable
+>(_ expected: Expected, _ actual: Actual)
where
Expected.Iterator.Element == Actual.Iterator.Element,
- Expected.Iterator.Element == (T, T)
->(_ expected: Expected, _ actual: Actual) {}
+ Expected.Iterator.Element == (T, T) {}
func f() {
foo(
diff --git a/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift b/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift
index 397b483..5496017 100644
--- a/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift
+++ b/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
protocol FooProtocol {
associatedtype Element
@@ -10,9 +10,9 @@
mutating func extend<
C : FooProtocol
+ >(elements: C)
where
C.Element == Element
- >(elements: C)
}
struct FooImpl<T> : FooProtocol {
@@ -27,8 +27,8 @@
mutating func extend<
C : FooProtocol
+ >(elements: C)
where
- C.Element == T
- >(elements: C) {}
+ C.Element == T {}
}
diff --git a/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift b/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift
index df46428..dddc8ff 100644
--- a/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift
+++ b/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
protocol SourceTargetTransformable {
associatedtype Source
@@ -15,13 +15,13 @@
SourceIterator: IteratorProtocol,
TransformerIterator: IteratorProtocol,
Transformable: SourceTargetTransformable
- where
- Transformable.Source == Source,
- Transformable.Target == Target,
- SourceIterator.Element == Source,
- TransformerIterator.Element == Transformable.Transformer
>
- : IteratorProtocol {
+ : IteratorProtocol
+ where
+ Transformable.Source == Source,
+ Transformable.Target == Target,
+ SourceIterator.Element == Source,
+ TransformerIterator.Element == Transformable.Transformer {
typealias Element = Target
var sourceIterator: SourceIterator
@@ -46,10 +46,10 @@
SourceSequence: Sequence,
TransformerSequence: Sequence,
Transformable: SourceTargetTransformable
+ >: Sequence
where
SourceSequence.Iterator.Element == Transformable.Source,
- TransformerSequence.Iterator.Element == Transformable.Transformer
- >: Sequence {
+ TransformerSequence.Iterator.Element == Transformable.Transformer {
typealias Source = SourceSequence.Iterator.Element
typealias Target = Transformable.Target
diff --git a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
index 8d2f13c..10346cf 100644
--- a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
+++ b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
import StdlibUnittest
@@ -389,15 +389,16 @@
}
public func expectCustomizable<
- T : Wrapper where
- T : LoggingType,
- T.Base : Wrapper, T.Base : LoggingType,
- T.Log == T.Base.Log
+ T : Wrapper
>(_: T, _ counters: TypeIndexed<Int>,
stackTrace: SourceLocStack? = nil,
file: String = #file, line: UInt = #line,
collectMoreInfo: (()->String)? = nil
-) {
+)
+ where
+ T : LoggingType,
+ T.Base : Wrapper, T.Base : LoggingType,
+ T.Log == T.Base.Log {
expectNotEqual(
0, counters[T.self], collectMoreInfo?() ?? "",
stackTrace: stackTrace ?? SourceLocStack(), file: file, line: line)
@@ -408,15 +409,16 @@
}
public func expectNotCustomizable<
- T : Wrapper where
- T : LoggingType,
- T.Base : Wrapper, T.Base : LoggingType,
- T.Log == T.Base.Log
+ T : Wrapper
>(_: T, _ counters: TypeIndexed<Int>,
stackTrace: SourceLocStack? = nil,
file: String = #file, line: UInt = #line,
collectMoreInfo: (()->String)? = nil
-) {
+)
+ where
+ T : LoggingType,
+ T.Base : Wrapper, T.Base : LoggingType,
+ T.Log == T.Base.Log {
expectNotEqual(
0, counters[T.self], collectMoreInfo?() ?? "",
stackTrace: stackTrace ?? SourceLocStack(), file: file, line: line)
diff --git a/validation-test/compiler_crashers_2_fixed/0053-sr490.swift b/validation-test/compiler_crashers_2_fixed/0053-sr490.swift
index 0c0c6bc..e861bea 100644
--- a/validation-test/compiler_crashers_2_fixed/0053-sr490.swift
+++ b/validation-test/compiler_crashers_2_fixed/0053-sr490.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
enum Value {
case IntValue(Int)
@@ -13,7 +13,7 @@
protocol RawProducable {
var rawValueForType : Int16 { get }
- init<T: Storable where T.Representation == Self>(value: T)
+ init<T: Storable>(value: T) where T.Representation == Self
}
extension Int : Storable {
diff --git a/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift b/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift
index 311a456..f222e36 100644
--- a/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift
+++ b/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
-// RUN: %target-swift-frontend %s -emit-ir -O -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
+// RUN: %target-swift-frontend %s -emit-ir -O
// REQUIRES: objc_interop
@@ -47,16 +47,14 @@
}
let classesPtr = memory.assumingMemoryBound(to: Optional<AnyClass>.self)
- let classes = AutoreleasingUnsafeMutablePointer<AnyClass?>(classesPtr)
+ let classes = AutoreleasingUnsafeMutablePointer<AnyClass>(classesPtr)
numClasses = objc_getClassList(classes, numClasses)
for i in 0 ..< Int(numClasses) {
// Go through the classes, find out if the class is kind of aClass
// and then add it to the list
- guard let cl = classes[i] else {
- continue
- }
+ let cl = classes[i]
if XUClassKindOfClass(cl, wantedSuperclass: aClass) && cl != aClass {
result.append(cl as! T.Type)
diff --git a/validation-test/compiler_crashers_2_fixed/0165-rdar40722855.swift b/validation-test/compiler_crashers_2_fixed/0165-rdar40722855.swift
new file mode 100644
index 0000000..30e1905
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0165-rdar40722855.swift
@@ -0,0 +1,24 @@
+// RUN: %target-typecheck-verify-swift
+
+postfix operator %
+postfix func % (_: Any) {}
+
+prefix operator ~
+prefix func ~ (_: Any) {}
+
+func foo(_: String) -> Void {}
+func foo(_: Int) -> Void {}
+
+_ = foo("answer")% // Ok
+_ = ~foo(42) // Ok
+
+class A {
+ func bar(_: Int) {}
+}
+
+extension A {
+ func bar(_ qux: String) {
+ bar(qux)% // Ok
+ ~bar(qux) // Ok
+ }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0166-rdar30168645.swift b/validation-test/compiler_crashers_2_fixed/0166-rdar30168645.swift
new file mode 100644
index 0000000..201d19a
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0166-rdar30168645.swift
@@ -0,0 +1,7 @@
+// RUN: %target-swift-frontend %s -emit-ir
+
+protocol P {}
+
+class Base<T: P> {}
+
+class Derived: Base<Derived>, P {}
diff --git a/validation-test/compiler_crashers_2_fixed/0167-rdar39059582.swift b/validation-test/compiler_crashers_2_fixed/0167-rdar39059582.swift
new file mode 100644
index 0000000..74acc48
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0167-rdar39059582.swift
@@ -0,0 +1,17 @@
+// RUN: %target-swift-frontend %s -emit-ir
+
+protocol X {
+ associatedtype R : Y
+}
+
+protocol Y {
+ associatedtype Q : X where Q.R == Self
+}
+
+struct B : Y {
+ typealias Q = L<B>
+}
+
+struct L<V : Y> : X {
+ typealias R = V
+}
diff --git a/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift b/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift
index 9c9c20f..dd456bf 100644
--- a/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift
+++ b/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift
@@ -5,14 +5,14 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
// Test case submitted to project by https://github.com/tmu (Teemu Kurppa)
// rdar://18118173
class a<T : Hashable> {
var b = [T : Bool]()
- init<S : Sequence where S.Iterator.Element == T>(_ c: S) {
+ init<S : Sequence>(_ c: S) where S.Iterator.Element == T {
c.map { self.b[$0] = true }
}
}
diff --git a/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift b/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift
index 7eec361..50f1480 100644
--- a/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift
+++ b/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift
@@ -6,9 +6,9 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
// Issue found by https://github.com/jansabbe (Jan Sabbe)
-class A<B : Collection where B : AnyObject> {
+class A<B : Collection> where B : AnyObject {
}
diff --git a/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift
index 4059c59..057b5c5 100644
--- a/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift
+++ b/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift
@@ -5,13 +5,12 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -typecheck -verify -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify
// Test case submitted to project by https://github.com/tmu (Teemu Kurppa)
// rdar://18175202
-func d<b: Sequence, e where Optional<e> == b.Iterator.Element>(c : b) -> e? {
- // expected-warning@-1 {{'where' clause next to generic parameters}}
+func d<b: Sequence, e>(c : b) -> e? where Optional<e> == b.Iterator.Element {
for mx : e? in c { // expected-warning {{immutable value 'mx' was never used}}
}
}
diff --git a/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift
index e3410fa..6e6fffb 100644
--- a/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift
+++ b/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift
@@ -6,10 +6,9 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -typecheck -verify -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify
// Issue found by https://github.com/julasamer (julasamer)
-struct c<d, e: b where d.c == e> { // expected-error {{use of undeclared type 'b'}} expected-error {{'c' is not a member type of 'd'}}
- // expected-warning@-1 {{'where' clause next to generic parameters is deprecated}}
+struct c<d, e: b> where d.c == e { // expected-error {{use of undeclared type 'b'}} expected-error {{'c' is not a member type of 'd'}}
}
diff --git a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
index dd315c5..64c07ba 100644
--- a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
+++ b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
@@ -6,7 +6,7 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -typecheck -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck
// Issue found by https://github.com/austinzheng (Austin Zheng)
@@ -16,7 +16,7 @@
}
func foo() -> A<(String, String?)> {
- _ = A<(String, String?)>.Just("abc", "def")
- _ = A.Just("abc", "def")
- return A.Just("abc", "def")
+ _ = A<(String, String?)>.Just(("abc", "def"))
+ _ = A.Just(("abc", "def"))
+ return A.Just(("abc", "def"))
}
diff --git a/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift b/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift
index 336c601..6f76a91 100644
--- a/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift
+++ b/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift
@@ -5,7 +5,7 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
protocol A {
associatedtype B
}
@@ -14,9 +14,9 @@
}
protocol E {
associatedtype F
- func g<T where F == T.B>(_: C<T>)
+ func g<T>(_: C<T>) where F == T.B
}
struct H: E {
typealias F = Void
- func g<T where F == T.B>(_: C<T>) {}
+ func g<T>(_: C<T>) where F == T.B {}
}
diff --git a/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift b/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift
index 15f1ff5..d5b8f5e 100644
--- a/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift
+++ b/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift
@@ -7,11 +7,11 @@
// Credits: https://twitter.com/kiliankoe/status/752090953977036800
-// RUN: %target-swift-frontend %s -typecheck -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck
protocol P {
}
struct A<T> {
- func a<B where T: P>(b: B) -> B {
+ func a<B>(b: B) -> B where T: P {
return b
}
}
diff --git a/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift b/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift
index d7b668a..7b961c3 100644
--- a/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift
+++ b/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift
@@ -5,15 +5,15 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
protocol A{associatedtype B
}
struct C<T:A>{
}
protocol E{associatedtype F
-func g<T where F==T.B>(_:C<T>)
+func g<T>(_:C<T>) where F==T.B
}
struct H:E{
typealias F = Void
-func g<T where F==T.B>(_:C<T>){}
+func g<T>(_:C<T>) where F==T.B{}
}
diff --git a/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift b/validation-test/compiler_crashers_fixed/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
similarity index 81%
rename from validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
rename to validation-test/compiler_crashers_fixed/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
index fdd416e..c0504d8 100644
--- a/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
+++ b/validation-test/compiler_crashers_fixed/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.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
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-// REQUIRES: rdar38932729
+// RUN: not %target-swift-frontend %s -emit-ir
protocol A:A&CLong