diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index ec61d2abb836a..d1e2825f5f1af 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -630,3 +630,9 @@ macro(add_swift_tool_symlink name dest component) add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE) llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE COMPONENT ${component}) endmacro() + +# Declare that files in this library are built with LLVM's support +# libraries available. +macro(set_swift_llvm_is_available) + add_compile_options(-DSWIFT_LLVM_SUPPORT_IS_AVAILABLE) +endmacro() diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h index 0ac4ab8943c42..9fbb260dc66ad 100644 --- a/include/swift/ABI/Metadata.h +++ b/include/swift/ABI/Metadata.h @@ -38,7 +38,7 @@ #include "swift/Basic/RelativePointer.h" #include "swift/Demangling/Demangle.h" #include "swift/Demangling/ManglingMacros.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include "../../../stdlib/public/SwiftShims/HeapObject.h" #if SWIFT_OBJC_INTEROP #include @@ -4664,7 +4664,7 @@ int32_t TargetTypeContextDescriptor::getGenericArgumentOffset() const { return llvm::cast>(this) ->getGenericArgumentOffset(); default: - swift_runtime_unreachable("Not a type context descriptor."); + swift_unreachable("Not a type context descriptor."); } } @@ -4682,7 +4682,7 @@ TargetTypeContextDescriptor::getFullGenericContextHeader() const { return llvm::cast>(this) ->getFullGenericContextHeader(); default: - swift_runtime_unreachable("Not a type context descriptor."); + swift_unreachable("Not a type context descriptor."); } } @@ -4699,7 +4699,7 @@ TargetTypeContextDescriptor::getGenericParams() const { case ContextDescriptorKind::OpaqueType: return llvm::cast>(this)->getGenericParams(); default: - swift_runtime_unreachable("Not a type context descriptor."); + swift_unreachable("Not a type context descriptor."); } } @@ -4717,7 +4717,7 @@ TargetTypeContextDescriptor::getForeignMetadataInitialization() const { return llvm::cast>(this) ->getForeignMetadataInitialization(); default: - swift_runtime_unreachable("Not a type context descriptor."); + swift_unreachable("Not a type context descriptor."); } } @@ -4735,7 +4735,7 @@ TargetTypeContextDescriptor::getSingletonMetadataInitialization() const return llvm::cast>(this) ->getSingletonMetadataInitialization(); default: - swift_runtime_unreachable("Not a enum, struct or class type descriptor."); + swift_unreachable("Not a enum, struct or class type descriptor."); } } @@ -4753,7 +4753,7 @@ TargetTypeContextDescriptor::getCanonicicalMetadataPrespecializations() return llvm::cast>(this) ->getCanonicicalMetadataPrespecializations(); default: - swift_runtime_unreachable("Not a type context descriptor."); + swift_unreachable("Not a type context descriptor."); } } diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h index e45629dce240a..bd044c5e36361 100644 --- a/include/swift/ABI/MetadataValues.h +++ b/include/swift/ABI/MetadataValues.h @@ -20,10 +20,10 @@ #define SWIFT_ABI_METADATAVALUES_H #include "swift/ABI/KeyPath.h" +#include "swift/ABI/ProtocolDispatchStrategy.h" #include "swift/AST/Ownership.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/FlagSet.h" -#include "swift/Runtime/Unreachable.h" #include #include @@ -410,20 +410,6 @@ enum class SpecialProtocol: uint8_t { Error = 1, }; -/// Identifiers for protocol method dispatch strategies. -enum class ProtocolDispatchStrategy: uint8_t { - /// Uses ObjC method dispatch. - /// - /// This must be 0 for ABI compatibility with Objective-C protocol_t records. - ObjC = 0, - - /// Uses Swift protocol witness table dispatch. - /// - /// To invoke methods of this protocol, a pointer to a protocol witness table - /// corresponding to the protocol conformance must be available. - Swift = 1, -}; - /// Flags for protocol descriptors. class ProtocolDescriptorFlags { typedef uint32_t int_type; @@ -486,18 +472,7 @@ class ProtocolDescriptorFlags { /// Does the protocol require a witness table for method dispatch? bool needsWitnessTable() const { - return needsWitnessTable(getDispatchStrategy()); - } - - static bool needsWitnessTable(ProtocolDispatchStrategy strategy) { - switch (strategy) { - case ProtocolDispatchStrategy::ObjC: - return false; - case ProtocolDispatchStrategy::Swift: - return true; - } - - swift_runtime_unreachable("Unhandled ProtocolDispatchStrategy in switch."); + return swift::protocolRequiresWitnessTable(getDispatchStrategy()); } /// Return the identifier if this is a special runtime-known protocol. diff --git a/include/swift/ABI/ProtocolDispatchStrategy.h b/include/swift/ABI/ProtocolDispatchStrategy.h new file mode 100644 index 0000000000000..eb89c8f138f4a --- /dev/null +++ b/include/swift/ABI/ProtocolDispatchStrategy.h @@ -0,0 +1,54 @@ +//===--- ProtocolDispatchStrategy.h - ---------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This header declares the ProtocolDispatchStrategy enum and some +// related operations. It's split out because we would otherwise need +// to include MetadataValues.h in some relatively central headers.s +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_ABI_PROTOCOLDISPATCHSTRATEGY_H +#define SWIFT_ABI_PROTOCOLDISPATCHSTRATEGY_H + +#include "swift/Basic/Unreachable.h" + +namespace swift { + +/// Identifiers for protocol method dispatch strategies. +enum class ProtocolDispatchStrategy: uint8_t { + /// Uses ObjC method dispatch. + /// + /// This must be 0 for ABI compatibility with Objective-C protocol_t records. + ObjC = 0, + + /// Uses Swift protocol witness table dispatch. + /// + /// To invoke methods of this protocol, a pointer to a protocol witness table + /// corresponding to the protocol conformance must be available. + Swift = 1, +}; + +/// Does a protocol using the given strategy require a witness table? +inline bool protocolRequiresWitnessTable(ProtocolDispatchStrategy strategy) { + switch (strategy) { + case ProtocolDispatchStrategy::ObjC: + return false; + case ProtocolDispatchStrategy::Swift: + return true; + } + + swift_unreachable("Unhandled ProtocolDispatchStrategy in switch."); +} + +} + +#endif diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h index f4247df1468c3..c6f6c2a46cfdc 100644 --- a/include/swift/AST/ASTScope.h +++ b/include/swift/AST/ASTScope.h @@ -1023,10 +1023,8 @@ class AbstractPatternEntryScope : public ASTScopeImpl { public: PatternBindingDecl *const decl; const unsigned patternEntryIndex; - const bool isLocalBinding; - AbstractPatternEntryScope(PatternBindingDecl *, unsigned entryIndex, - bool); + AbstractPatternEntryScope(PatternBindingDecl *, unsigned entryIndex); virtual ~AbstractPatternEntryScope() {} const PatternBindingEntry &getPatternEntry() const; @@ -1041,10 +1039,14 @@ class AbstractPatternEntryScope : public ASTScopeImpl { }; class PatternEntryDeclScope final : public AbstractPatternEntryScope { + const bool isLocalBinding; + Optional endLoc; + public: PatternEntryDeclScope(PatternBindingDecl *pbDecl, unsigned entryIndex, - bool isLocalBinding) - : AbstractPatternEntryScope(pbDecl, entryIndex, isLocalBinding) {} + bool isLocalBinding, Optional endLoc) + : AbstractPatternEntryScope(pbDecl, entryIndex), + isLocalBinding(isLocalBinding), endLoc(endLoc) {} virtual ~PatternEntryDeclScope() {} protected: @@ -1070,9 +1072,8 @@ class PatternEntryInitializerScope final : public AbstractPatternEntryScope { Expr *initAsWrittenWhenCreated; public: - PatternEntryInitializerScope(PatternBindingDecl *pbDecl, unsigned entryIndex, - bool isLocalBinding) - : AbstractPatternEntryScope(pbDecl, entryIndex, isLocalBinding), + PatternEntryInitializerScope(PatternBindingDecl *pbDecl, unsigned entryIndex) + : AbstractPatternEntryScope(pbDecl, entryIndex), initAsWrittenWhenCreated(pbDecl->getOriginalInit(entryIndex)) {} virtual ~PatternEntryInitializerScope() {} @@ -1400,7 +1401,8 @@ class WhileStmtScope final : public LabeledConditionalStmtScope { class GuardStmtScope final : public LabeledConditionalStmtScope { public: GuardStmt *const stmt; - GuardStmtScope(GuardStmt *e) : stmt(e) {} + SourceLoc endLoc; + GuardStmtScope(GuardStmt *e, SourceLoc endLoc) : stmt(e), endLoc(endLoc) {} virtual ~GuardStmtScope() {} protected: @@ -1413,6 +1415,8 @@ class GuardStmtScope final : public LabeledConditionalStmtScope { public: std::string getClassName() const override; LabeledConditionalStmt *getLabeledConditionalStmt() const override; + SourceRange + getSourceRangeOfThisASTNode(bool omitAssertions = false) const override; }; /// A scope after a guard statement that follows lookups into the conditions @@ -1427,9 +1431,11 @@ class LookupParentDiversionScope final : public ASTScopeImpl { public: ASTScopeImpl *const lookupParent; const SourceLoc startLoc; + const SourceLoc endLoc; - LookupParentDiversionScope(ASTScopeImpl *lookupParent, SourceLoc startLoc) - : lookupParent(lookupParent), startLoc(startLoc) {} + LookupParentDiversionScope(ASTScopeImpl *lookupParent, + SourceLoc startLoc, SourceLoc endLoc) + : lookupParent(lookupParent), startLoc(startLoc), endLoc(endLoc) {} SourceRange getSourceRangeOfThisASTNode(bool omitAssertions = false) const override; diff --git a/include/swift/Basic/Compiler.h b/include/swift/Basic/Compiler.h index b422175695ade..1958e762b2b83 100644 --- a/include/swift/Basic/Compiler.h +++ b/include/swift/Basic/Compiler.h @@ -34,10 +34,59 @@ #define SWIFT_ASSUME(x) #endif +/// Attributes. + #if __has_attribute(constructor) #define SWIFT_CONSTRUCTOR __attribute__((constructor)) #else #define SWIFT_CONSTRUCTOR #endif +/// \macro SWIFT_GNUC_PREREQ +/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't +/// available. +#ifndef SWIFT_GNUC_PREREQ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define SWIFT_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_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) +# else +# define SWIFT_GNUC_PREREQ(maj, min, patch) 0 +# endif +#endif + + +/// SWIFT_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, +/// mark a method "not for inlining". +#if __has_attribute(noinline) || SWIFT_GNUC_PREREQ(3, 4, 0) +#define SWIFT_ATTRIBUTE_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define SWIFT_ATTRIBUTE_NOINLINE __declspec(noinline) +#else +#define SWIFT_ATTRIBUTE_NOINLINE +#endif + +/// SWIFT_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_GNUC_PREREQ(4, 0, 0) +#define SWIFT_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) +#elif defined(_MSC_VER) +#define SWIFT_ATTRIBUTE_ALWAYS_INLINE __forceinline +#else +#define SWIFT_ATTRIBUTE_ALWAYS_INLINE +#endif + +#ifdef __GNUC__ +#define SWIFT_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define SWIFT_ATTRIBUTE_NORETURN __declspec(noreturn) +#else +#define SWIFT_ATTRIBUTE_NORETURN +#endif + #endif // SWIFT_BASIC_COMPILER_H diff --git a/include/swift/Runtime/Unreachable.h b/include/swift/Basic/Unreachable.h similarity index 53% rename from include/swift/Runtime/Unreachable.h rename to include/swift/Basic/Unreachable.h index 4147d4ce80d23..8d0ed35b5a49d 100644 --- a/include/swift/Runtime/Unreachable.h +++ b/include/swift/Basic/Unreachable.h @@ -1,4 +1,4 @@ -//===--- Unreachable.h - Implements swift_runtime_unreachable ---*- C++ -*-===// +//===--- Unreachable.h - Implements swift_unreachable ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // @@ -10,13 +10,25 @@ // //===----------------------------------------------------------------------===// // -// This file defines swift_runtime_unreachable, an LLVM-independent -// implementation of llvm_unreachable. +// This file defines swift_unreachable, which provides the +// functionality of llvm_unreachable without necessarily depending on +// the LLVM support libraries. // //===----------------------------------------------------------------------===// -#ifndef SWIFT_RUNTIME_UNREACHABLE_H -#define SWIFT_RUNTIME_UNREACHABLE_H +#ifndef SWIFT_BASIC_UNREACHABLE_H +#define SWIFT_BASIC_UNREACHABLE_H + +#ifdef SWIFT_LLVM_SUPPORT_IS_AVAILABLE + +// The implementation when LLVM is available. + +#include "llvm/Support/ErrorHandling.h" +#define swift_unreachable llvm_unreachable + +#else + +// The implementation when LLVM is not available. #include #include @@ -24,10 +36,12 @@ #include "swift/Runtime/Config.h" SWIFT_RUNTIME_ATTRIBUTE_NORETURN -inline static void swift_runtime_unreachable(const char *msg) { +inline static void swift_unreachable(const char *msg) { assert(false && msg); (void)msg; abort(); } -#endif // SWIFT_RUNTIME_UNREACHABLE_H +#endif + +#endif diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index fb33edf878252..296076adbf225 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -24,7 +24,7 @@ #include "swift/Demangling/Demangler.h" #include "swift/Demangling/NamespaceMacros.h" #include "swift/Runtime/Portability.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include "swift/Strings.h" #include "llvm/ADT/ArrayRef.h" #include diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 7c80c7c03e68e..3c412e153c7dc 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1102,7 +1102,11 @@ def scan_clang_dependencies : Flag<["-"], "scan-clang-dependencies">, def disable_parser_lookup : Flag<["-"], "disable-parser-lookup">, Flags<[FrontendOption]>, - HelpText<"Disable parser lookup & use ast scope lookup only (experimental)">; + HelpText<"Disable parser lookup & use ASTScope lookup only (experimental)">; + +def enable_parser_lookup : Flag<["-"], "enable-parser-lookup">, + Flags<[FrontendOption]>, + HelpText<"Enable parser lookup">; def enable_request_based_incremental_dependencies : Flag<["-"], "enable-request-based-incremental-dependencies">, diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h index 9e26669aa8f38..e52185c0b8ebe 100644 --- a/include/swift/Reflection/ReflectionContext.h +++ b/include/swift/Reflection/ReflectionContext.h @@ -33,7 +33,7 @@ #include "swift/Reflection/TypeLowering.h" #include "swift/Reflection/TypeRef.h" #include "swift/Reflection/TypeRefBuilder.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include #include @@ -1302,7 +1302,7 @@ class ReflectionContext return true; } - swift_runtime_unreachable("Unhandled MetadataSourceKind in switch."); + swift_unreachable("Unhandled MetadataSourceKind in switch."); } /// Read metadata for a captured generic type from a closure context. diff --git a/include/swift/Reflection/TypeRef.h b/include/swift/Reflection/TypeRef.h index fb03cbc9e2e82..3d38e47128f85 100644 --- a/include/swift/Reflection/TypeRef.h +++ b/include/swift/Reflection/TypeRef.h @@ -22,7 +22,7 @@ #include "llvm/Support/Casting.h" #include "swift/ABI/MetadataValues.h" #include "swift/Remote/MetadataReader.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" namespace swift { namespace reflection { @@ -856,7 +856,7 @@ class TypeRefVisitor { #include "swift/Reflection/TypeRefs.def" } - swift_runtime_unreachable("Unhandled TypeRefKind in switch."); + swift_unreachable("Unhandled TypeRefKind in switch."); } }; diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index 0090ae0746ed6..589bef52d8a68 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -28,7 +28,7 @@ #include "swift/ABI/TypeIdentity.h" #include "swift/Runtime/ExistentialContainer.h" #include "swift/Runtime/HeapObject.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include #include @@ -923,7 +923,7 @@ class MetadataReader { } } - swift_runtime_unreachable("Unhandled MetadataKind in switch"); + swift_unreachable("Unhandled MetadataKind in switch"); } TypeLookupErrorOr @@ -1295,7 +1295,7 @@ class MetadataReader { } } - swift_runtime_unreachable("Unhandled IsaEncodingKind in switch."); + swift_unreachable("Unhandled IsaEncodingKind in switch."); } /// Read the offset of the generic parameters of a class from the nominal diff --git a/include/swift/Runtime/Config.h b/include/swift/Runtime/Config.h index 372328a145d5d..da49b452f3b6e 100644 --- a/include/swift/Runtime/Config.h +++ b/include/swift/Runtime/Config.h @@ -17,71 +17,29 @@ #ifndef SWIFT_RUNTIME_CONFIG_H #define SWIFT_RUNTIME_CONFIG_H +#include "swift/Basic/Compiler.h" #include "swift/Runtime/CMakeConfig.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)) && \ +#if (__has_attribute(visibility) || SWIFT_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 +#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE SWIFT_ATTRIBUTE_NOINLINE +#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE SWIFT_ATTRIBUTE_ALWAYS_INLINE +#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_ATTRIBUTE_NORETURN /// 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) +#if __has_builtin(__builtin_trap) || SWIFT_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 diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h index f14e8d16f1554..f82fee34bc805 100644 --- a/include/swift/Runtime/Debug.h +++ b/include/swift/Runtime/Debug.h @@ -18,7 +18,7 @@ #define SWIFT_RUNTIME_DEBUG_HELPERS_H #include "swift/Runtime/Config.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include #include #include @@ -79,7 +79,7 @@ static inline void crash(const char *message) { CRSetCrashLogMessage(message); SWIFT_RUNTIME_BUILTIN_TRAP; - swift_runtime_unreachable("Expected compiler to crash."); + swift_unreachable("Expected compiler to crash."); } // swift::fatalError() halts with a crash log message, diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h index ed135eccf8e2f..98ff7ec7624df 100644 --- a/include/swift/SIL/TypeLowering.h +++ b/include/swift/SIL/TypeLowering.h @@ -13,7 +13,7 @@ #ifndef SWIFT_SIL_TYPELOWERING_H #define SWIFT_SIL_TYPELOWERING_H -#include "swift/ABI/MetadataValues.h" +#include "swift/ABI/ProtocolDispatchStrategy.h" #include "swift/AST/CaptureInfo.h" #include "swift/AST/Module.h" #include "swift/SIL/AbstractionPattern.h" @@ -792,8 +792,7 @@ class TypeConverter { /// True if a protocol uses witness tables for dynamic dispatch. static bool protocolRequiresWitnessTable(ProtocolDecl *P) { - return ProtocolDescriptorFlags::needsWitnessTable - (getProtocolDispatchStrategy(P)); + return swift::protocolRequiresWitnessTable(getProtocolDispatchStrategy(P)); } /// True if a type is passed indirectly at +0 when used as the "self" diff --git a/lib/AST/ASTScopeCreation.cpp b/lib/AST/ASTScopeCreation.cpp index aa82c8014afc2..b7324c68013c7 100644 --- a/lib/AST/ASTScopeCreation.cpp +++ b/lib/AST/ASTScopeCreation.cpp @@ -213,14 +213,17 @@ class ScopeCreator final { /// Given an array of ASTNodes or Decl pointers, add them /// Return the resultant insertionPoint + /// + /// \param endLoc The end location for any "scopes until the end" that + /// we introduce here, such as PatternEntryDeclScope and GuardStmtScope ASTScopeImpl * addSiblingsToScopeTree(ASTScopeImpl *const insertionPoint, - ASTScopeImpl *const organicInsertionPoint, - ArrayRef nodesOrDeclsToAdd) { + ArrayRef nodesOrDeclsToAdd, + Optional endLoc) { auto *ip = insertionPoint; - for (auto nd : sortBySourceRange(cull(nodesOrDeclsToAdd))) { + for (auto nd : nodesOrDeclsToAdd) { auto *const newIP = - addToScopeTreeAndReturnInsertionPoint(nd, ip).getPtrOr(ip); + addToScopeTreeAndReturnInsertionPoint(nd, ip, endLoc).getPtrOr(ip); ip = newIP; } return ip; @@ -229,12 +232,16 @@ class ScopeCreator final { public: /// For each of searching, call this unless the insertion point is needed void addToScopeTree(ASTNode n, ASTScopeImpl *parent) { - (void)addToScopeTreeAndReturnInsertionPoint(n, parent); + (void)addToScopeTreeAndReturnInsertionPoint(n, parent, None); } /// Return new insertion point if the scope was not a duplicate /// For ease of searching, don't call unless insertion point is needed + /// + /// \param endLoc The end location for any "scopes until the end" that + /// we introduce here, such as PatternEntryDeclScope and GuardStmtScope NullablePtr - addToScopeTreeAndReturnInsertionPoint(ASTNode, ASTScopeImpl *parent); + addToScopeTreeAndReturnInsertionPoint(ASTNode, ASTScopeImpl *parent, + Optional endLoc); bool isWorthTryingToCreateScopeFor(ASTNode n) const { if (!n) @@ -419,9 +426,18 @@ class ScopeCreator final { void addChildrenForKnownAttributes(ValueDecl *decl, ASTScopeImpl *parent); -public: + /// Add PatternEntryDeclScopes for each pattern binding entry. + /// + /// Returns the new insertion point. + /// + /// \param endLoc Must be valid iff the pattern binding is in a local + /// scope, in which case this is the last source location where the + /// pattern bindings are going to be visible. + NullablePtr + addPatternBindingToScopeTree(PatternBindingDecl *patternBinding, + ASTScopeImpl *parent, + Optional endLoc); -private: /// Remove VarDecls because we'll find them when we expand the /// PatternBindingDecls. Remove EnunCases /// because they overlap EnumElements and AST includes the elements in the @@ -463,7 +479,6 @@ class ScopeCreator final { return -1 == signum; } -public: SWIFT_DEBUG_DUMP { print(llvm::errs()); } void print(raw_ostream &out) const { @@ -545,7 +560,10 @@ class NodeAdder : public ASTVisitor, NullablePtr, NullablePtr, void, void, void, ASTScopeImpl *, ScopeCreator &> { + Optional endLoc; + public: + explicit NodeAdder(Optional endLoc) : endLoc(endLoc) {} #pragma mark ASTNodes that do not create scopes @@ -637,7 +655,9 @@ class NodeAdder // the deferred nodes. NullablePtr visitGuardStmt(GuardStmt *e, ASTScopeImpl *p, ScopeCreator &scopeCreator) { - return scopeCreator.ifUniqueConstructExpandAndInsert(p, e); + ASTScopeAssert(endLoc.hasValue(), "GuardStmt outside of a BraceStmt?"); + return scopeCreator.ifUniqueConstructExpandAndInsert( + p, e, *endLoc); } NullablePtr visitTopLevelCodeDecl(TopLevelCodeDecl *d, ASTScopeImpl *p, @@ -698,28 +718,8 @@ class NodeAdder visitPatternBindingDecl(PatternBindingDecl *patternBinding, ASTScopeImpl *parentScope, ScopeCreator &scopeCreator) { - if (auto *var = patternBinding->getSingleVar()) - scopeCreator.addChildrenForKnownAttributes(var, parentScope); - - auto *insertionPoint = parentScope; - for (auto i : range(patternBinding->getNumPatternEntries())) { - bool isLocalBinding = false; - if (auto *varDecl = patternBinding->getAnchoringVarDecl(i)) { - isLocalBinding = varDecl->getDeclContext()->isLocalContext(); - } - - insertionPoint = - scopeCreator - .ifUniqueConstructExpandAndInsert( - insertionPoint, patternBinding, i, isLocalBinding) - .getPtrOr(insertionPoint); - - ASTScopeAssert(isLocalBinding || insertionPoint == parentScope, - "Bindings at the top-level or members of types should " - "not change the insertion point"); - } - - return insertionPoint; + return scopeCreator.addPatternBindingToScopeTree( + patternBinding, parentScope, endLoc); } NullablePtr visitEnumElementDecl(EnumElementDecl *eed, @@ -773,15 +773,18 @@ class NodeAdder // NodeAdder NullablePtr ScopeCreator::addToScopeTreeAndReturnInsertionPoint(ASTNode n, - ASTScopeImpl *parent) { + ASTScopeImpl *parent, + Optional endLoc) { if (!isWorthTryingToCreateScopeFor(n)) return parent; + + NodeAdder adder(endLoc); if (auto *p = n.dyn_cast()) - return NodeAdder().visit(p, parent, *this); + return adder.visit(p, parent, *this); if (auto *p = n.dyn_cast()) - return NodeAdder().visit(p, parent, *this); + return adder.visit(p, parent, *this); auto *p = n.get(); - return NodeAdder().visit(p, parent, *this); + return adder.visit(p, parent, *this); } void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder( @@ -831,6 +834,41 @@ void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl, } } +NullablePtr +ScopeCreator::addPatternBindingToScopeTree(PatternBindingDecl *patternBinding, + ASTScopeImpl *parentScope, + Optional endLoc) { + if (auto *var = patternBinding->getSingleVar()) + addChildrenForKnownAttributes(var, parentScope); + + auto *insertionPoint = parentScope; + for (auto i : range(patternBinding->getNumPatternEntries())) { + bool isLocalBinding = false; + if (auto *varDecl = patternBinding->getAnchoringVarDecl(i)) { + isLocalBinding = varDecl->getDeclContext()->isLocalContext(); + } + + Optional endLocForBinding = None; + if (isLocalBinding) { + endLocForBinding = endLoc; + ASTScopeAssert(endLoc.hasValue() && endLoc->isValid(), + "PatternBindingDecl in local context outside of BraceStmt?"); + } + + insertionPoint = + ifUniqueConstructExpandAndInsert( + insertionPoint, patternBinding, i, + isLocalBinding, endLocForBinding) + .getPtrOr(insertionPoint); + + ASTScopeAssert(isLocalBinding || insertionPoint == parentScope, + "Bindings at the top-level or members of types should " + "not change the insertion point"); + } + + return insertionPoint; +} + #pragma mark creation helpers void ASTScopeImpl::addChild(ASTScopeImpl *child, ASTContext &ctx) { @@ -950,7 +988,10 @@ ASTSourceFileScope::expandAScopeThatCreatesANewInsertionPoint( // Assume that decls are only added at the end, in source order std::vector newNodes(decls.begin(), decls.end()); insertionPoint = - scopeCreator.addSiblingsToScopeTree(insertionPoint, this, newNodes); + scopeCreator.addSiblingsToScopeTree(insertionPoint, + scopeCreator.sortBySourceRange( + scopeCreator.cull(newNodes)), + None); // Too slow to perform all the time: // ASTScopeAssert(scopeCreator->containsAllDeclContextsFromAST(), // "ASTScope tree missed some DeclContexts or made some up"); @@ -991,7 +1032,7 @@ PatternEntryDeclScope::expandAScopeThatCreatesANewInsertionPoint( "Original inits are always after the '='"); scopeCreator .constructExpandAndInsertUncheckable( - this, decl, patternEntryIndex, isLocalBinding); + this, decl, patternEntryIndex); } // Add accessors for the variables in this pattern. @@ -1050,7 +1091,7 @@ GuardStmtScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator & auto *const lookupParentDiversionScope = scopeCreator .constructExpandAndInsertUncheckable( - this, conditionLookupParent, stmt->getEndLoc()); + this, conditionLookupParent, stmt->getEndLoc(), endLoc); return {lookupParentDiversionScope, "Succeeding code must be in scope of guard variables"}; } @@ -1068,7 +1109,11 @@ BraceStmtScope::expandAScopeThatCreatesANewInsertionPoint( // TODO: remove the sort after fixing parser to create brace statement // elements in source order auto *insertionPoint = - scopeCreator.addSiblingsToScopeTree(this, this, stmt->getElements()); + scopeCreator.addSiblingsToScopeTree(this, + scopeCreator.sortBySourceRange( + scopeCreator.cull( + stmt->getElements())), + stmt->getEndLoc()); if (auto *s = scopeCreator.getASTContext().Stats) ++s->getFrontendCounters().NumBraceStmtASTScopeExpansions; return { @@ -1082,7 +1127,7 @@ TopLevelCodeScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator & if (auto *body = scopeCreator - .addToScopeTreeAndReturnInsertionPoint(decl->getBody(), this) + .addToScopeTreeAndReturnInsertionPoint(decl->getBody(), this, None) .getPtrOrNull()) return {body, "So next top level code scope and put its decls in its body " "under a guard statement scope (etc) from the last top level " @@ -1377,10 +1422,8 @@ ASTScopeImpl *LabeledConditionalStmtScope::createNestedConditionalClauseScopes( } AbstractPatternEntryScope::AbstractPatternEntryScope( - PatternBindingDecl *declBeingScoped, unsigned entryIndex, - bool isLocalBinding) - : decl(declBeingScoped), patternEntryIndex(entryIndex), - isLocalBinding(isLocalBinding) { + PatternBindingDecl *declBeingScoped, unsigned entryIndex) + : decl(declBeingScoped), patternEntryIndex(entryIndex) { ASTScopeAssert(entryIndex < declBeingScoped->getPatternList().size(), "out of bounds"); } @@ -1414,7 +1457,8 @@ void GenericTypeOrExtensionScope::expandBody(ScopeCreator &) {} void IterableTypeScope::expandBody(ScopeCreator &scopeCreator) { auto nodes = asNodeVector(getIterableDeclContext().get()->getMembers()); - scopeCreator.addSiblingsToScopeTree(this, this, nodes); + nodes = scopeCreator.sortBySourceRange(scopeCreator.cull(nodes)); + scopeCreator.addSiblingsToScopeTree(this, nodes, None); if (auto *s = scopeCreator.getASTContext().Stats) ++s->getFrontendCounters().NumIterableTypeBodyASTScopeExpansions; } diff --git a/lib/AST/ASTScopeSourceRange.cpp b/lib/AST/ASTScopeSourceRange.cpp index 48a59b2f3ac59..1d93bdd762b84 100644 --- a/lib/AST/ASTScopeSourceRange.cpp +++ b/lib/AST/ASTScopeSourceRange.cpp @@ -248,7 +248,13 @@ SourceRange DefaultArgumentInitializerScope::getSourceRangeOfThisASTNode( SourceRange PatternEntryDeclScope::getSourceRangeOfThisASTNode( const bool omitAssertions) const { - return getPatternEntry().getSourceRange(); + SourceRange range = getPatternEntry().getSourceRange(); + if (endLoc.hasValue()) { + ASTScopeAssert(endLoc->isValid(), + "BraceStmt ends before pattern binding entry?"); + range.End = *endLoc; + } + return range; } SourceRange PatternEntryInitializerScope::getSourceRangeOfThisASTNode( @@ -445,9 +451,14 @@ SourceRange AttachedPropertyWrapperScope::getSourceRangeOfThisASTNode( return sourceRangeWhenCreated; } +SourceRange GuardStmtScope::getSourceRangeOfThisASTNode( + const bool omitAssertions) const { + return SourceRange(getStmt()->getStartLoc(), endLoc); +} + SourceRange LookupParentDiversionScope::getSourceRangeOfThisASTNode( const bool omitAssertions) const { - return SourceRange(startLoc); + return SourceRange(startLoc, endLoc); } #pragma mark source range caching diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index 6762297a9f098..e9e4ab76ccb30 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -9,6 +9,8 @@ else() ) endif() +set_swift_llvm_is_available() + add_swift_host_library(swiftAST STATIC AbstractSourceFileDepGraphFactory.cpp AccessRequests.cpp diff --git a/lib/ASTSectionImporter/CMakeLists.txt b/lib/ASTSectionImporter/CMakeLists.txt index 0bd9f991fc45e..1a8b262e2a2c0 100644 --- a/lib/ASTSectionImporter/CMakeLists.txt +++ b/lib/ASTSectionImporter/CMakeLists.txt @@ -1,3 +1,5 @@ +set_swift_llvm_is_available() + add_swift_host_library(swiftASTSectionImporter STATIC ASTSectionImporter.cpp LLVM_LINK_COMPONENTS core) diff --git a/lib/ClangImporter/CMakeLists.txt b/lib/ClangImporter/CMakeLists.txt index a9076c210e033..21294ee6da4ef 100644 --- a/lib/ClangImporter/CMakeLists.txt +++ b/lib/ClangImporter/CMakeLists.txt @@ -4,6 +4,8 @@ set(SWIFT_GYB_FLAGS add_gyb_target(generated_sorted_cf_database SortedCFDatabase.def.gyb) +set_swift_llvm_is_available() + add_swift_host_library(swiftClangImporter STATIC CFTypeInfo.cpp ClangAdapter.cpp diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 380c3c6dc8a0c..d210da923bce6 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -1,3 +1,5 @@ +set_swift_llvm_is_available() + set(swiftDriver_sources Action.cpp Compilation.cpp diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 2ff01dd73b4fa..b3dce353410b2 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -269,6 +269,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_print_educational_notes); inputArgs.AddLastArg(arguments, options::OPT_diagnostic_style); inputArgs.AddLastArg(arguments, options::OPT_disable_parser_lookup); + inputArgs.AddLastArg(arguments, options::OPT_enable_parser_lookup); inputArgs.AddLastArg(arguments, options::OPT_enable_experimental_concise_pound_file); inputArgs.AddLastArg( diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt index 08988f9a078ee..2c8c24f9e4dd9 100644 --- a/lib/Frontend/CMakeLists.txt +++ b/lib/Frontend/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftFrontend STATIC ArgsToFrontendInputsConverter.cpp ArgsToFrontendOptionsConverter.cpp diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3d0f6a6180bb1..d02bc2222b758 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -425,7 +425,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, = A->getOption().matches(OPT_enable_target_os_checking); } - Opts.DisableParserLookup |= Args.hasArg(OPT_disable_parser_lookup); + Opts.DisableParserLookup |= Args.hasFlag(OPT_disable_parser_lookup, + OPT_enable_parser_lookup, + /*default*/ false); Opts.EnableNewOperatorLookup = Args.hasFlag(OPT_enable_new_operator_lookup, OPT_disable_new_operator_lookup, /*default*/ false); diff --git a/lib/FrontendTool/CMakeLists.txt b/lib/FrontendTool/CMakeLists.txt index 0e08c752eb30d..26b37f661b82b 100644 --- a/lib/FrontendTool/CMakeLists.txt +++ b/lib/FrontendTool/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftFrontendTool STATIC FrontendTool.cpp ImportedModules.cpp diff --git a/lib/IDE/CMakeLists.txt b/lib/IDE/CMakeLists.txt index d028e874d39b7..48ebc21981d30 100644 --- a/lib/IDE/CMakeLists.txt +++ b/lib/IDE/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftIDE STATIC CodeCompletion.cpp CodeCompletionCache.cpp diff --git a/lib/IRGen/CMakeLists.txt b/lib/IRGen/CMakeLists.txt index 7cfe61b987e86..777096b39e6e0 100644 --- a/lib/IRGen/CMakeLists.txt +++ b/lib/IRGen/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftIRGen STATIC AllocStackHoisting.cpp ClassLayout.cpp diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 7fe0c9ffffdcb..1c58d8206d624 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -16,6 +16,7 @@ #define DEBUG_TYPE "irgen" #include "IRGenModule.h" +#include "swift/ABI/MetadataValues.h" #include "swift/AST/DiagnosticsIRGen.h" #include "swift/AST/IRGenOptions.h" #include "swift/AST/IRGenRequests.h" diff --git a/lib/LLVMPasses/CMakeLists.txt b/lib/LLVMPasses/CMakeLists.txt index 80edee61d1236..f5a3ee28b7562 100644 --- a/lib/LLVMPasses/CMakeLists.txt +++ b/lib/LLVMPasses/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftLLVMPasses STATIC LLVMSwiftAA.cpp LLVMSwiftRCIdentity.cpp diff --git a/lib/Migrator/CMakeLists.txt b/lib/Migrator/CMakeLists.txt index 3e37ff2ca48a9..473ad151f0640 100644 --- a/lib/Migrator/CMakeLists.txt +++ b/lib/Migrator/CMakeLists.txt @@ -47,6 +47,8 @@ swift_install_in_component(FILES ${datafiles} DESTINATION "lib/swift/migrator" COMPONENT compiler) +set_swift_llvm_is_available() + add_swift_host_library(swiftMigrator STATIC APIDiffMigratorPass.cpp EditorAdapter.cpp diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt index 7158bdce8b24e..550af6bf5954a 100644 --- a/lib/Parse/CMakeLists.txt +++ b/lib/Parse/CMakeLists.txt @@ -1,3 +1,5 @@ +set_swift_llvm_is_available() + if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) set(SWIFT_GYB_FLAGS --line-directive "^\"#line %(line)d \\\"%(file)s\\\"^\"") else() diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 1c8019aaf9464..e05b08cd4ece8 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -2208,20 +2208,23 @@ Expr *Parser::parseExprIdentifier() { // lookups, so disable this check when parsing for SwiftSyntax. if (!InPoundIfEnvironment && !Context.LangOpts.ParseForSyntaxTreeOnly) { D = lookupInScope(name); - // FIXME: We want this to work: "var x = { x() }", but for now it's better - // to disallow it than to crash. - if (D) { - for (auto activeVar : DisabledVars) { - if (activeVar == D) { - diagnose(loc.getBaseNameLoc(), DisabledVarReason); - return new (Context) ErrorExpr(loc.getSourceRange()); + + if (!Context.LangOpts.DisableParserLookup) { + // FIXME: We want this to work: "var x = { x() }", but for now it's better + // to disallow it than to crash. + if (D) { + for (auto activeVar : DisabledVars) { + if (activeVar == D) { + diagnose(loc.getBaseNameLoc(), DisabledVarReason); + return new (Context) ErrorExpr(loc.getSourceRange()); + } } - } - } else { - for (auto activeVar : DisabledVars) { - if (activeVar->getName() == name.getFullName()) { - diagnose(loc.getBaseNameLoc(), DisabledVarReason); - return new (Context) ErrorExpr(loc.getSourceRange()); + } else { + for (auto activeVar : DisabledVars) { + if (activeVar->getName() == name.getFullName()) { + diagnose(loc.getBaseNameLoc(), DisabledVarReason); + return new (Context) ErrorExpr(loc.getSourceRange()); + } } } } diff --git a/lib/PrintAsObjC/CMakeLists.txt b/lib/PrintAsObjC/CMakeLists.txt index ae667af64ac31..66044fa3fc7ff 100644 --- a/lib/PrintAsObjC/CMakeLists.txt +++ b/lib/PrintAsObjC/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftPrintAsObjC STATIC DeclAndTypePrinter.cpp ModuleContentsWriter.cpp diff --git a/lib/SIL/CMakeLists.txt b/lib/SIL/CMakeLists.txt index 74ca0507393d3..96a6b852ad8b0 100644 --- a/lib/SIL/CMakeLists.txt +++ b/lib/SIL/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftSIL STATIC SIL.cpp) target_link_libraries(swiftSIL PUBLIC diff --git a/lib/SILGen/CMakeLists.txt b/lib/SILGen/CMakeLists.txt index c144b14bf69ee..c4daab77fd3e6 100644 --- a/lib/SILGen/CMakeLists.txt +++ b/lib/SILGen/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftSILGen STATIC ArgumentSource.cpp Cleanup.cpp diff --git a/lib/SILOptimizer/CMakeLists.txt b/lib/SILOptimizer/CMakeLists.txt index ec1440d2b06a1..c9ddd901ab5dc 100644 --- a/lib/SILOptimizer/CMakeLists.txt +++ b/lib/SILOptimizer/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftSILOptimizer STATIC SILOptimizer.cpp) target_link_libraries(swiftSILOptimizer PRIVATE diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 633a64b014896..e71cb7ff910bc 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftSema STATIC BuilderTransform.cpp CSApply.cpp diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 751d893323e44..5d15df3ada4f4 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -3440,6 +3440,8 @@ namespace { // Generate constraints for each of the entries in the capture list. if (auto captureList = dyn_cast(expr)) { + TypeChecker::diagnoseDuplicateCaptureVars(captureList); + auto &CS = CG.getConstraintSystem(); for (const auto &capture : captureList->getCaptureList()) { SolutionApplicationTarget target(capture.Init); diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 5092bf7c99b92..9e44995acd561 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -1334,6 +1334,14 @@ void TypeChecker::diagnoseDuplicateBoundVars(Pattern *pattern) { diagnoseDuplicateDecls(boundVars); } +void TypeChecker::diagnoseDuplicateCaptureVars(CaptureListExpr *expr) { + SmallVector captureListVars; + for (auto &capture : expr->getCaptureList()) + captureListVars.push_back(capture.Var); + + diagnoseDuplicateDecls(captureListVars); +} + namespace { class DeclChecker : public DeclVisitor { public: diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index b30e9810a614f..6d21f393431d5 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -502,6 +502,8 @@ void checkParameterList(ParameterList *params); void diagnoseDuplicateBoundVars(Pattern *pattern); +void diagnoseDuplicateCaptureVars(CaptureListExpr *expr); + Type checkReferenceOwnershipAttr(VarDecl *D, Type interfaceType, ReferenceOwnershipAttr *attr); diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt index 55a20aef848ea..1e7c14b1ce161 100644 --- a/lib/Serialization/CMakeLists.txt +++ b/lib/Serialization/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftSerialization STATIC Deserialization.cpp DeserializeSIL.cpp diff --git a/lib/SyntaxParse/CMakeLists.txt b/lib/SyntaxParse/CMakeLists.txt index b1b1c562988aa..230f230ebd68f 100644 --- a/lib/SyntaxParse/CMakeLists.txt +++ b/lib/SyntaxParse/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftSyntaxParse STATIC RawSyntaxTokenCache.cpp SyntaxTreeCreator.cpp) diff --git a/lib/TBDGen/CMakeLists.txt b/lib/TBDGen/CMakeLists.txt index 06181211d4a67..60796eab5e73c 100644 --- a/lib/TBDGen/CMakeLists.txt +++ b/lib/TBDGen/CMakeLists.txt @@ -1,3 +1,4 @@ +set_swift_llvm_is_available() add_swift_host_library(swiftTBDGen STATIC TBDGen.cpp TBDGenRequests.cpp diff --git a/stdlib/public/Platform/winsdk.modulemap b/stdlib/public/Platform/winsdk.modulemap index b7d099dc595e2..5307e9b89362a 100644 --- a/stdlib/public/Platform/winsdk.modulemap +++ b/stdlib/public/Platform/winsdk.modulemap @@ -172,13 +172,6 @@ module WinSDK [system] { link "NetAPI32.Lib" } - module DbgHelp { - header "DbgHelp.h" - export * - - link "DbgHelp.Lib" - } - module DWM { header "dwmapi.h" export * @@ -252,6 +245,20 @@ module WinSDK [system] { link "shcore.lib" } + module System { + module DbgHelp { + header "DbgHelp.h" + export * + + link "DbgHelp.Lib" + } + + module IOCTL { + header "winioctl.h" + export * + } + } + module OLE32 { header "oaidl.h" export * diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp index 729765edd1893..09bc0b6b258b4 100644 --- a/stdlib/public/Reflection/TypeLowering.cpp +++ b/stdlib/public/Reflection/TypeLowering.cpp @@ -23,7 +23,7 @@ #include "swift/Reflection/TypeLowering.h" #include "swift/Reflection/TypeRef.h" #include "swift/Reflection/TypeRefBuilder.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #ifdef DEBUG_TYPE_LOWERING #define DEBUG_LOG(expr) expr; @@ -212,7 +212,7 @@ class PrintTypeInfo { } } - swift_runtime_unreachable("Bad TypeInfo kind"); + swift_unreachable("Bad TypeInfo kind"); } }; @@ -2007,7 +2007,7 @@ class LowerType return nullptr; } - swift_runtime_unreachable("Unhandled FieldDescriptorKind in switch."); + swift_unreachable("Unhandled FieldDescriptorKind in switch."); } const TypeInfo *visitNominalTypeRef(const NominalTypeRef *N) { @@ -2039,7 +2039,7 @@ class LowerType return TC.getTypeInfo(TC.getThinFunctionTypeRef(), ExternalTypeInfo); } - swift_runtime_unreachable("Unhandled FunctionMetadataConvention in switch."); + swift_unreachable("Unhandled FunctionMetadataConvention in switch."); } const TypeInfo * @@ -2060,7 +2060,7 @@ class LowerType return TC.getTypeInfo(TC.getAnyMetatypeTypeRef(), ExternalTypeInfo); } - swift_runtime_unreachable("Unhandled MetatypeRepresentation in switch."); + swift_unreachable("Unhandled MetatypeRepresentation in switch."); } const TypeInfo * @@ -2256,7 +2256,7 @@ const TypeInfo *TypeConverter::getClassInstanceTypeInfo( return nullptr; } - swift_runtime_unreachable("Unhandled FieldDescriptorKind in switch."); + swift_unreachable("Unhandled FieldDescriptorKind in switch."); } } // namespace reflection diff --git a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp index 9d5afad1cf41f..0af1e53b3f9d7 100644 --- a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp +++ b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp @@ -23,7 +23,7 @@ unsigned long long swift_reflection_classIsSwiftMask = 2; #include "swift/Reflection/ReflectionContext.h" #include "swift/Reflection/TypeLowering.h" #include "swift/Remote/CMemoryReader.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #if defined(__APPLE__) && defined(__MACH__) #include @@ -406,7 +406,7 @@ swift_layout_kind_t getTypeInfoKind(const TypeInfo &TI) { } } - swift_runtime_unreachable("Unhandled TypeInfoKind in switch"); + swift_unreachable("Unhandled TypeInfoKind in switch"); } static swift_typeinfo_t convertTypeInfo(const TypeInfo *TI) { diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index 99e08243588bb..487bc05fb871a 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -35,7 +35,7 @@ # define SWIFT_CASTING_SUPPORTS_MUTEX 1 # include "swift/Runtime/Mutex.h" #endif -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #if SWIFT_OBJC_INTEROP @@ -1016,7 +1016,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest, } } - swift_runtime_unreachable("Unhandled ExistentialTypeRepresentation in switch."); + swift_unreachable("Unhandled ExistentialTypeRepresentation in switch."); } /******************************************************************************/ @@ -1214,7 +1214,7 @@ swift_dynamicCastMetatypeImpl(const Metadata *sourceType, return nullptr; } - swift_runtime_unreachable("Unhandled MetadataKind in switch."); + swift_unreachable("Unhandled MetadataKind in switch."); } static const Metadata * @@ -1424,7 +1424,7 @@ static bool _dynamicCastToUnknownClassFromExistential(OpaqueValue *dest, } } - swift_runtime_unreachable( + swift_unreachable( "Unhandled ExistentialTypeRepresentation in switch."); } diff --git a/stdlib/public/runtime/DynamicCast.cpp b/stdlib/public/runtime/DynamicCast.cpp index f19af13ab6311..e7f624ba8c555 100644 --- a/stdlib/public/runtime/DynamicCast.cpp +++ b/stdlib/public/runtime/DynamicCast.cpp @@ -1806,7 +1806,7 @@ static tryCastFunctionType *selectCasterForDest(const Metadata *destType) { case ExistentialTypeRepresentation::Error: // => Error existential return tryCastToErrorExistential; } - swift_runtime_unreachable( + swift_unreachable( "Unknown existential type representation in dynamic cast dispatch"); } case MetadataKind::Metatype: @@ -1821,14 +1821,14 @@ static tryCastFunctionType *selectCasterForDest(const Metadata *destType) { // These are internal details of runtime-only structures, // so will never appear in compiler-generated types. // As such, they don't need support here. - swift_runtime_unreachable( + swift_unreachable( "Unexpected MetadataKind in dynamic cast dispatch"); return nullptr; default: // If you see this message, then there is a new MetadataKind that I didn't // know about when I wrote this code. Please figure out what it is, how to // handle it, and add a case for it. - swift_runtime_unreachable( + swift_unreachable( "Unknown MetadataKind in dynamic cast dispatch"); } } diff --git a/stdlib/public/runtime/Exclusivity.cpp b/stdlib/public/runtime/Exclusivity.cpp index 73628b7cdaae4..7750fbae41e8b 100644 --- a/stdlib/public/runtime/Exclusivity.cpp +++ b/stdlib/public/runtime/Exclusivity.cpp @@ -219,7 +219,7 @@ class AccessSet { } } - swift_runtime_unreachable("access not found in set"); + swift_unreachable("access not found in set"); } #ifndef NDEBUG diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp index 56fd8670c640f..5fc6dafd8baac 100644 --- a/stdlib/public/runtime/Metadata.cpp +++ b/stdlib/public/runtime/Metadata.cpp @@ -194,7 +194,7 @@ computeMetadataBoundsForSuperclass(const void *ref, #endif } } - swift_runtime_unreachable("unsupported superclass reference kind"); + swift_unreachable("unsupported superclass reference kind"); } static ClassMetadataBounds computeMetadataBoundsFromSuperclass( @@ -3716,7 +3716,7 @@ getExistentialValueWitnesses(ProtocolClassConstraint classConstraint, return getOpaqueExistentialValueWitnesses(numWitnessTables); } - swift_runtime_unreachable("Unhandled ProtocolClassConstraint in switch."); + swift_unreachable("Unhandled ProtocolClassConstraint in switch."); } template<> ExistentialTypeRepresentation @@ -3761,7 +3761,7 @@ ExistentialTypeMetadata::mayTakeValue(const OpaqueValue *container) const { } } - swift_runtime_unreachable( + swift_unreachable( "Unhandled ExistentialTypeRepresentation in switch."); } @@ -3810,7 +3810,7 @@ ExistentialTypeMetadata::projectValue(const OpaqueValue *container) const { } } - swift_runtime_unreachable( + swift_unreachable( "Unhandled ExistentialTypeRepresentation in switch."); } @@ -3835,7 +3835,7 @@ ExistentialTypeMetadata::getDynamicType(const OpaqueValue *container) const { } } - swift_runtime_unreachable( + swift_unreachable( "Unhandled ExistentialTypeRepresentation in switch."); } @@ -4030,7 +4030,7 @@ class ForeignMetadataCacheEntry return Value; } void setValue(ValueType value) { - swift_runtime_unreachable("should never be called"); + swift_unreachable("should never be called"); } public: @@ -4094,7 +4094,7 @@ class ForeignMetadataCacheEntry } AllocationResult allocate(Metadata *candidate) { - swift_runtime_unreachable( + swift_unreachable( "always flags allocation complete during construction"); } @@ -4555,7 +4555,7 @@ static void initProtocolWitness(void **slot, void *witness, reqt); return; } - swift_runtime_unreachable("bad witness kind"); + swift_unreachable("bad witness kind"); #else *slot = witness; #endif @@ -4588,7 +4588,7 @@ static void copyProtocolWitness(void **dest, void * const *src, swift_ptrauth_copy(dest, src, reqt.Flags.getExtraDiscriminator()); return; } - swift_runtime_unreachable("bad witness kind"); + swift_unreachable("bad witness kind"); #else *dest = *src; #endif @@ -5141,7 +5141,7 @@ static const WitnessTable *swift_getAssociatedConformanceWitnessSlowImpl( return assocWitnessTable; } - swift_runtime_unreachable("Invalid mangled associate conformance"); + swift_unreachable("Invalid mangled associate conformance"); } const WitnessTable *swift::swift_getAssociatedConformanceWitness( @@ -5234,7 +5234,7 @@ static Result performOnMetadataCache(const Metadata *metadata, case TypeContextDescriptorFlags::SingletonMetadataInitialization: return std::move(callbacks).forSingletonMetadata(description); } - swift_runtime_unreachable("bad metadata initialization kind"); + swift_unreachable("bad metadata initialization kind"); } auto &generics = description->getFullGenericContextHeader(); @@ -5280,7 +5280,7 @@ bool swift::addToMetadataQueue(MetadataCompletionQueueEntry *queueEntry, } bool forOtherMetadata(const Metadata *metadata) && { - swift_runtime_unreachable("metadata should always be complete"); + swift_unreachable("metadata should always be complete"); } } callbacks = { queueEntry, dependency }; @@ -5312,7 +5312,7 @@ void swift::resumeMetadataCompletion(MetadataCompletionQueueEntry *queueEntry) { } void forOtherMetadata(const Metadata *metadata) && { - swift_runtime_unreachable("metadata should always be complete"); + swift_unreachable("metadata should always be complete"); } } callbacks = { queueEntry }; diff --git a/stdlib/public/runtime/MetadataCache.h b/stdlib/public/runtime/MetadataCache.h index d6f188f971e3c..0c9a186f8b574 100644 --- a/stdlib/public/runtime/MetadataCache.h +++ b/stdlib/public/runtime/MetadataCache.h @@ -366,7 +366,7 @@ class SimpleLockingCacheEntryBase { template Status beginInitialization(ConcurrencyControl &concurrency, ArgTys &&...args) { - swift_runtime_unreachable("beginAllocation always short-circuits"); + swift_unreachable("beginAllocation always short-circuits"); } }; @@ -592,7 +592,7 @@ inline bool satisfies(PrivateMetadataState state, MetadataState requirement) { case MetadataState::Complete: return state >= PrivateMetadataState::Complete; } - swift_runtime_unreachable("unsupported requirement kind"); + swift_unreachable("unsupported requirement kind"); } class PrivateMetadataTrackingInfo { @@ -642,7 +642,7 @@ class PrivateMetadataTrackingInfo { MetadataState getAccomplishedRequestState() const { switch (getState()) { case PrivateMetadataState::Allocating: - swift_runtime_unreachable("cannot call on allocating state"); + swift_unreachable("cannot call on allocating state"); case PrivateMetadataState::Abstract: return MetadataState::Abstract; case PrivateMetadataState::LayoutComplete: @@ -652,7 +652,7 @@ class PrivateMetadataTrackingInfo { case PrivateMetadataState::Complete: return MetadataState::Complete; } - swift_runtime_unreachable("bad state"); + swift_unreachable("bad state"); } bool satisfies(MetadataState requirement) { @@ -678,7 +678,7 @@ class PrivateMetadataTrackingInfo { // Otherwise, if it's a non-blocking request, we do not need to block. return (request.isBlocking() && !satisfies(request.getState())); } - swift_runtime_unreachable("bad state"); + swift_unreachable("bad state"); } constexpr RawType getRawValue() const { return Data; } @@ -1124,9 +1124,9 @@ class MetadataCacheEntryBase return; case LSK::Complete: - swift_runtime_unreachable("preparing to enqueue when already complete?"); + swift_unreachable("preparing to enqueue when already complete?"); } - swift_runtime_unreachable("bad kind"); + swift_unreachable("bad kind"); } /// Claim all the satisfied completion queue entries, given that @@ -1288,7 +1288,7 @@ class MetadataCacheEntryBase switch (LockedStorageKind) { case LSK::Complete: - swift_runtime_unreachable("enqueuing on complete cache entry?"); + swift_unreachable("enqueuing on complete cache entry?"); case LSK::AllocatingThread: LockedStorageKind = LSK::CompletionQueue; @@ -1340,7 +1340,7 @@ class MetadataCacheEntryBase // Check for an existing dependency. switch (LockedStorageKind) { case LSK::Complete: - swift_runtime_unreachable("dependency on complete cache entry?"); + swift_unreachable("dependency on complete cache entry?"); case LSK::AllocatingThread: case LSK::CompletionQueue: diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index fef3ff3f82e76..f271908ee1d50 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -88,10 +88,10 @@ static uintptr_t resolveSymbolicReferenceOffset(SymbolicReferenceKind kind, return (uintptr_t)contextPtr; } case SymbolicReferenceKind::AccessorFunctionReference: { - swift_runtime_unreachable("should not be indirectly referenced"); + swift_unreachable("should not be indirectly referenced"); } } - swift_runtime_unreachable("unknown symbolic reference kind"); + swift_unreachable("unknown symbolic reference kind"); } else { return ptr; } @@ -176,7 +176,7 @@ _buildDemanglingForSymbolicReference(SymbolicReferenceKind kind, (uintptr_t)resolvedReference); } - swift_runtime_unreachable("invalid symbolic reference kind"); + swift_unreachable("invalid symbolic reference kind"); } NodePointer @@ -1168,7 +1168,7 @@ findAssociatedTypeByName(const ProtocolDescriptor *protocol, StringRef name) { ++currentAssocTypeIdx; } - swift_runtime_unreachable("associated type names don't line up"); + swift_unreachable("associated type names don't line up"); } namespace { diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp index c434011faea85..f3fa79c578a72 100644 --- a/stdlib/public/runtime/ProtocolConformance.cpp +++ b/stdlib/public/runtime/ProtocolConformance.cpp @@ -20,7 +20,7 @@ #include "swift/Runtime/Concurrent.h" #include "swift/Runtime/HeapObject.h" #include "swift/Runtime/Metadata.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include "CompatibilityOverride.h" #include "ImageInspection.h" #include "Private.h" @@ -116,7 +116,7 @@ const ClassMetadata *TypeReference::getObjCClass(TypeReferenceKind kind) const { return nullptr; } - swift_runtime_unreachable("Unhandled TypeReferenceKind in switch."); + swift_unreachable("Unhandled TypeReferenceKind in switch."); } #endif @@ -155,7 +155,7 @@ ProtocolConformanceDescriptor::getCanonicalTypeMetadata() const { } } - swift_runtime_unreachable("Unhandled TypeReferenceKind in switch."); + swift_unreachable("Unhandled TypeReferenceKind in switch."); } template<> diff --git a/stdlib/public/runtime/ReflectionMirror.cpp b/stdlib/public/runtime/ReflectionMirror.cpp index 5fbad4fb3c136..ca7d6601c4cec 100644 --- a/stdlib/public/runtime/ReflectionMirror.cpp +++ b/stdlib/public/runtime/ReflectionMirror.cpp @@ -17,7 +17,7 @@ #include "swift/Runtime/HeapObject.h" #include "swift/Runtime/Metadata.h" #include "swift/Runtime/Enum.h" -#include "swift/Runtime/Unreachable.h" +#include "swift/Basic/Unreachable.h" #include "swift/Demangling/Demangle.h" #include "swift/Runtime/Debug.h" #include "swift/Runtime/Portability.h" diff --git a/stdlib/toolchain/Compatibility51/ProtocolConformance.cpp b/stdlib/toolchain/Compatibility51/ProtocolConformance.cpp index 4f22fd2bfda2d..09bd46ea02700 100644 --- a/stdlib/toolchain/Compatibility51/ProtocolConformance.cpp +++ b/stdlib/toolchain/Compatibility51/ProtocolConformance.cpp @@ -231,7 +231,7 @@ override_getCanonicalTypeMetadata(const ProtocolConformanceDescriptor *conf) { } } - swift_runtime_unreachable("Unhandled TypeReferenceKind in switch."); + swift_unreachable("Unhandled TypeReferenceKind in switch."); } class ConformanceCandidate { diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift index ec557012b835a..2d9a1d7d2742e 100644 --- a/test/Constraints/tuple.swift +++ b/test/Constraints/tuple.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup // Test various tuple constraints. @@ -305,6 +305,8 @@ if case (foo: let x, foo: let y) = zeroTuple { print(x+y) } // expected-error {{ // expected-warning@-1 {{'if' condition is always true}} enum BishBash { case bar(foo: Int, foo: String) } +// expected-error@-1 {{invalid redeclaration of 'foo'}} +// expected-note@-2 {{'foo' previously declared here}} let enumLabelDup: BishBash = .bar(foo: 0, foo: "") // expected-error {{cannot create a tuple with a duplicate element label}} func dupLabelClosure(_ fn: () -> Void) {} diff --git a/test/Constraints/tuple_parser_lookup.swift b/test/Constraints/tuple_parser_lookup.swift new file mode 100644 index 0000000000000..a3acaf4f356e4 --- /dev/null +++ b/test/Constraints/tuple_parser_lookup.swift @@ -0,0 +1,337 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +// Test various tuple constraints. + +func f0(x: Int, y: Float) {} + +var i : Int +var j : Int +var f : Float + +func f1(y: Float, rest: Int...) {} + +func f2(_: (_ x: Int, _ y: Int) -> Int) {} +func f2xy(x: Int, y: Int) -> Int {} +func f2ab(a: Int, b: Int) -> Int {} +func f2yx(y: Int, x: Int) -> Int {} + +func f3(_ x: (_ x: Int, _ y: Int) -> ()) {} +func f3a(_ x: Int, y: Int) {} +func f3b(_: Int) {} + +func f4(_ rest: Int...) {} +func f5(_ x: (Int, Int)) {} + +func f6(_: (i: Int, j: Int), k: Int = 15) {} + +//===----------------------------------------------------------------------===// +// Conversions and shuffles +//===----------------------------------------------------------------------===// + +func foo(a : [(some: Int, (key: Int, value: String))]) -> String { + for (i , (j, k)) in a { + if i == j { return k } + } +} + +func rdar28207648() -> [(Int, CustomStringConvertible)] { + let v : [(Int, Int)] = [] + return v as [(Int, CustomStringConvertible)] +} + +class rdar28207648Base {} +class rdar28207648Derived : rdar28207648Base {} + +func rdar28207648(x: (Int, rdar28207648Derived)) -> (Int, rdar28207648Base) { + return x as (Int, rdar28207648Base) +} + +public typealias Success = (response: T, data: V?) + +public enum Result { + case success(Success) + case error(Error) +} + + +let a = Success(response: 3, data: 3) +let success: Result = .success(a) + +// Variadic functions. +f4() +f4(1) +f4(1, 2, 3) + +f2(f2xy) +f2(f2ab) +f2(f2yx) + +f3(f3a) +f3(f3b) // expected-error{{cannot convert value of type '(Int) -> ()' to expected argument type '(Int, Int) -> ()'}} + +func getIntFloat() -> (int: Int, float: Float) {} +var values = getIntFloat() +func wantFloat(_: Float) {} +wantFloat(values.float) + +var e : (x: Int..., y: Int) // expected-error{{cannot create a variadic tuple}} + +typealias Interval = (a:Int, b:Int) +func takeInterval(_ x: Interval) {} +takeInterval(Interval(1, 2)) + +f5((1,1)) + +// Tuples with existentials +var any : Any = () +any = (1, 2) +any = (label: 4) // expected-error {{cannot create a single-element tuple with an element label}} + +// Scalars don't have .0/.1/etc +i = j.0 // expected-error{{value of type 'Int' has no member '0'}} +any.1 // expected-error{{value of type 'Any' has no member '1'}} +// expected-note@-1{{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} +any = (5.0, 6.0) as (Float, Float) +_ = (any as! (Float, Float)).1 + +// Fun with tuples +protocol PosixErrorReturn { + static func errorReturnValue() -> Self +} + +extension Int : PosixErrorReturn { + static func errorReturnValue() -> Int { return -1 } +} + +func posixCantFail + (_ f: @escaping (A) -> T) -> (_ args:A) -> T +{ + return { args in + let result = f(args) + assert(result != T.errorReturnValue()) + return result + } +} + +func open(_ name: String, oflag: Int) -> Int { } + +var foo: Int = 0 + +var fd = posixCantFail(open)(("foo", 0)) + +// Tuples and lvalues +class C { + init() {} + func f(_: C) {} +} + +func testLValue(_ c: C) { + var c = c + c.f(c) + + let x = c + c = x +} + + +// Crash in TypeChecker::coercePatternToType +func invalidPatternCrash(_ k : Int) { + switch k { + case (k, cph_: k) as UInt8: // expected-error {{tuple pattern cannot match values of the non-tuple type 'UInt8'}} expected-warning {{cast from 'Int' to unrelated type 'UInt8' always fails}} + break + } +} + +// Tuple to tuple conversion with IdentityExpr / AnyTryExpr hang +class Paws { + init() throws {} +} + +func scruff() -> (AnyObject?, Error?) { + do { + return try (Paws(), nil) + } catch { + return (nil, error) + } +} + +// Test variadics with trailing closures. +func variadicWithTrailingClosure(_ x: Int..., y: Int = 2, fn: (Int, Int) -> Int) { +} + +variadicWithTrailingClosure(1, 2, 3) { $0 + $1 } +variadicWithTrailingClosure(1) { $0 + $1 } +variadicWithTrailingClosure() { $0 + $1 } +variadicWithTrailingClosure { $0 + $1 } + +variadicWithTrailingClosure(1, 2, 3, y: 0) { $0 + $1 } +variadicWithTrailingClosure(1, y: 0) { $0 + $1 } +variadicWithTrailingClosure(y: 0) { $0 + $1 } + +variadicWithTrailingClosure(1, 2, 3, y: 0, fn: +) +variadicWithTrailingClosure(1, y: 0, fn: +) +variadicWithTrailingClosure(y: 0, fn: +) + +variadicWithTrailingClosure(1, 2, 3, fn: +) +variadicWithTrailingClosure(1, fn: +) +variadicWithTrailingClosure(fn: +) + + +// QoI: Terrible diagnostic in tuple assignment +func gcd_23700031(_ a: T, b: T) { + var a = a + var b = b + (a, b) = (b, a % b) // expected-error {{binary operator '%' cannot be applied to two 'T' operands}} +} + +// +// Don't ignore tuple labels in same-type constraints or stronger. +protocol Kingdom { + associatedtype King +} +struct Victory { + init(_ king: K) where K.King == General {} // expected-note {{where 'General' = '(x: Int, y: Int)', 'K.King' = 'MagicKingdom<(Int, Int)>.King' (aka '(Int, Int)')}} +} +struct MagicKingdom : Kingdom { + typealias King = K +} +func magify(_ t: T) -> MagicKingdom { return MagicKingdom() } +func foo(_ pair: (Int, Int)) -> Victory<(x: Int, y: Int)> { + return Victory(magify(pair)) // expected-error {{initializer 'init(_:)' requires the types '(x: Int, y: Int)' and 'MagicKingdom<(Int, Int)>.King' (aka '(Int, Int)') be equivalent}} +} + + +// https://bugs.swift.org/browse/SR-596 +// Compiler crashes when accessing a non-existent property of a closure parameter +func call(_ f: (C) -> Void) {} +func makeRequest() { + call { obj in + print(obj.invalidProperty) // expected-error {{value of type 'C' has no member 'invalidProperty'}} + } +} + +// QoI: Misleading error message when expression result can't be inferred from closure +struct r25271859 { +} + +extension r25271859 { + func map(f: (T) -> U) -> r25271859 { + } + + func andThen(f: (T) -> r25271859) { // expected-note {{in call to function 'andThen(f:)'}} + } +} + +func f(a : r25271859<(Float, Int)>) { + a.map { $0.0 } // expected-error {{generic parameter 'U' could not be inferred}} (This is related to how solver is setup with multiple statements) + .andThen { _ in + print("hello") // comment this out and it runs, leave any form of print in and it doesn't + return r25271859() + } +} + +// LValue to rvalue conversions. + +func takesRValue(_: (Int, (Int, Int))) {} +func takesAny(_: Any) {} + +var x = 0 +var y = 0 + +let _ = (x, (y, 0)) +takesRValue((x, (y, 0))) +takesAny((x, (y, 0))) + +// SR-2600 - Closure cannot infer tuple parameter names +typealias Closure = ((a: A, b: B)) -> String + +func invoke(a: A, b: B, _ closure: Closure) { + print(closure((a, b))) +} + +invoke(a: 1, b: "B") { $0.b } + +invoke(a: 1, b: "B") { $0.1 } + +invoke(a: 1, b: "B") { (c: (a: Int, b: String)) in + return c.b +} + +invoke(a: 1, b: "B") { c in + return c.b +} + +// Crash with one-element tuple with labeled element +class Dinner {} + +func microwave() -> Dinner? { + let d: Dinner? = nil + return (n: d) // expected-error{{cannot convert return expression of type '(n: Dinner?)' to return type 'Dinner?'}} +} + +func microwave() -> Dinner { + let d: Dinner? = nil + return (n: d) // expected-error{{cannot convert return expression of type '(n: Dinner?)' to return type 'Dinner'}} +} + +// Tuple conversion with an optional +func f(b: Bool) -> (a: Int, b: String)? { + let x = 3 + let y = "" + return b ? (x, y) : nil +} + +// Single element tuple expressions +func singleElementTuple() { + let _ = (label: 123) // expected-error {{cannot create a single-element tuple with an element label}} {{12-19=}} + let _ = (label: 123).label // expected-error {{cannot create a single-element tuple with an element label}} {{12-19=}} + let _ = ((label: 123)) // expected-error {{cannot create a single-element tuple with an element label}} {{13-20=}} + let _ = ((label: 123)).label // expected-error {{cannot create a single-element tuple with an element label}} {{13-20=}} +} + +// Tuples with duplicate labels + +let dupLabel1: (foo: Int, foo: Int) = (foo: 1, foo: 2) // expected-error 2{{cannot create a tuple with a duplicate element label}} + +func dupLabel2(x a: Int, x b: Int) -> (y: Int, y: Int) { // expected-error {{cannot create a tuple with a duplicate element label}} + return (a, b) +} + +let _ = (bar: 0, bar: "") // expected-error {{cannot create a tuple with a duplicate element label}} + +let zeroTuple = (0,0) + +if case (foo: let x, foo: let y) = zeroTuple { print(x+y) } // expected-error {{cannot create a tuple with a duplicate element label}} +// expected-warning@-1 {{'if' condition is always true}} + +enum BishBash { case bar(foo: Int, foo: String) } +let enumLabelDup: BishBash = .bar(foo: 0, foo: "") // expected-error {{cannot create a tuple with a duplicate element label}} + +func dupLabelClosure(_ fn: () -> Void) {} +dupLabelClosure { print((bar: "", bar: 5).bar) } // expected-error {{cannot create a tuple with a duplicate element label}} + +struct DupLabelSubscript { + subscript(foo x: Int, foo y: Int) -> Int { + return 0 + } +} + +let dupLabelSubscriptStruct = DupLabelSubscript() +let _ = dupLabelSubscriptStruct[foo: 5, foo: 5] // ok + +// SR-12869 + +var dict: [String: (Int, Int)] = [:] +let bignum: Int64 = 1337 +dict["test"] = (bignum, 1) // expected-error {{cannot assign value of type '(Int64, Int)' to subscript of type '(Int, Int)'}} + +var tuple: (Int, Int) +tuple = (bignum, 1) // expected-error {{cannot assign value of type '(Int64, Int)' to type '(Int, Int)'}} + +var optionalTuple: (Int, Int)? +var optionalTuple2: (Int64, Int)? = (bignum, 1) +var optionalTuple3: (UInt64, Int)? = (bignum, 1) // expected-error {{cannot convert value of type '(Int64, Int)' to specified type '(UInt64, Int)?'}} + +optionalTuple = (bignum, 1) // expected-error {{cannot assign value of type '(Int64, Int)' to type '(Int, Int)'}} +// Optional to Optional +optionalTuple = optionalTuple2 // expected-error {{cannot assign value of type '(Int64, Int)?' to type '(Int, Int)?'}} diff --git a/test/Parse/matching_patterns.swift b/test/Parse/matching_patterns.swift index 1d32472a264bc..abaf38e7aa06d 100644 --- a/test/Parse/matching_patterns.swift +++ b/test/Parse/matching_patterns.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -swift-version 4 -I %S/Inputs -enable-source-import +// RUN: %target-typecheck-verify-swift -swift-version 4 -I %S/Inputs -enable-source-import -disable-parser-lookup import imported_enums @@ -47,7 +47,7 @@ case 1 + (_): // expected-error{{'_' can only appear in a pattern or on the left } switch (x,x) { -case (var a, var a): // expected-error {{definition conflicts with previous value}} expected-note {{previous definition of 'a' is here}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} +case (var a, var a): // expected-error {{invalid redeclaration of 'a'}} expected-note {{'a' previously declared here}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} fallthrough case _: // expected-warning {{case is already handled by previous patterns; consider removing it}} () diff --git a/test/Parse/matching_patterns_parser_lookup.swift b/test/Parse/matching_patterns_parser_lookup.swift new file mode 100644 index 0000000000000..172689808f50f --- /dev/null +++ b/test/Parse/matching_patterns_parser_lookup.swift @@ -0,0 +1,332 @@ +// RUN: %target-typecheck-verify-swift -swift-version 4 -I %S/Inputs -enable-source-import -enable-parser-lookup + +import imported_enums + +// TODO: Implement tuple equality in the library. +// BLOCKED: +func ~= (x: (Int,Int,Int), y: (Int,Int,Int)) -> Bool { + return true +} + +var x:Int + +func square(_ x: Int) -> Int { return x*x } + +struct A { + struct C { } +} + +switch x { +// Expressions as patterns. +case 0: + () +case 1 + 2: + () +case square(9): + () + +// 'var' and 'let' patterns. +case var a: + a = 1 +case let a: + a = 1 // expected-error {{cannot assign}} +case var var a: // expected-error {{'var' cannot appear nested inside another 'var' or 'let' pattern}} + a += 1 +case var let a: // expected-error {{'let' cannot appear nested inside another 'var' or 'let' pattern}} + print(a, terminator: "") +case var (var b): // expected-error {{'var' cannot appear nested inside another 'var'}} + b += 1 + +// 'Any' pattern. +case _: + () + +// patterns are resolved in expression-only positions are errors. +case 1 + (_): // expected-error{{'_' can only appear in a pattern or on the left side of an assignment}} + () +} + +switch (x,x) { +case (var a, var a): // expected-error {{definition conflicts with previous value}} expected-note {{previous definition of 'a' is here}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} + fallthrough +case _: // expected-warning {{case is already handled by previous patterns; consider removing it}} + () +} + +var e : Any = 0 + +switch e { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +// 'is' pattern. +case is Int, + is A, + is A.C, + is (Int, Int), + is (a: Int, b: Int): + () +} + +// Enum patterns. +enum Foo { case A, B, C } + +func == (_: Voluntary, _: Voluntary) -> Bool { return true } + +enum Voluntary : Equatable { + case Naught + case Mere(T) + case Twain(T, T) + + + func enumMethod(_ other: Voluntary, foo: Foo) { + switch self { + case other: + () + + case .Naught, + .Naught(), // expected-error {{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{17-19=}} + .Naught(_), // expected-error{{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{17-20=}} + .Naught(_, _): // expected-error{{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{17-23=}} + () + + case .Mere, + .Mere(), // expected-error{{tuple pattern cannot match values of the non-tuple type 'T'}} + .Mere(_), + .Mere(_, _): // expected-error{{tuple pattern cannot match values of the non-tuple type 'T'}} + () + + case .Twain(), // expected-error{{tuple pattern has the wrong length for tuple type '(T, T)'}} + .Twain(_), // expected-warning {{enum case 'Twain' has 2 associated values; matching them as a tuple is deprecated}} + // expected-note@-25 {{'Twain' declared here}} + .Twain(_, _), + .Twain(_, _, _): // expected-error{{tuple pattern has the wrong length for tuple type '(T, T)'}} + () + } + + switch foo { + case .Naught: // expected-error{{type 'Foo' has no member 'Naught'}} + () + case .A, .B, .C: + () + } + } +} + +var n : Voluntary = .Naught +if case let .Naught(value) = n {} // expected-error{{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{20-27=}} +if case let .Naught(value1, value2, value3) = n {} // expected-error{{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{20-44=}} + + + +switch n { +case Foo.A: // expected-error{{enum case 'A' is not a member of type 'Voluntary'}} + () +case Voluntary.Naught, + Voluntary.Naught(), // expected-error {{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{27-29=}} + Voluntary.Naught(_, _), // expected-error{{pattern with associated values does not match enum case 'Naught'}} + // expected-note@-1 {{remove associated values to make the pattern match}} {{27-33=}} + Voluntary.Naught, + .Naught: + () +case Voluntary.Mere, + Voluntary.Mere(_), + Voluntary.Mere(_, _), // expected-error{{tuple pattern cannot match values of the non-tuple type 'Int'}} + Voluntary.Mere, + Voluntary.Mere(_), + .Mere, + .Mere(_): + () +case .Twain, + .Twain(_), // expected-warning {{enum case 'Twain' has 2 associated values; matching them as a tuple is deprecated}} + // expected-note@-69 {{'Twain' declared here}} + .Twain(_, _), + .Twain(_, _, _): // expected-error{{tuple pattern has the wrong length for tuple type '(Int, Int)'}} + () +} + +var notAnEnum = 0 + +switch notAnEnum { +case .Foo: // expected-error{{type 'Int' has no member 'Foo'}} + () +} + +struct ContainsEnum { + enum Possible { + case Naught + case Mere(T) + case Twain(T, T) + } + + func member(_ n: Possible) { + switch n { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.Mere(_)'}} + // expected-note@-2 {{missing case: '.Twain(_, _)'}} + case ContainsEnum.Possible.Naught, + ContainsEnum.Possible.Naught, // expected-warning {{case is already handled by previous patterns; consider removing it}} + Possible.Naught, // expected-warning {{case is already handled by previous patterns; consider removing it}} + Possible.Naught, // expected-warning {{case is already handled by previous patterns; consider removing it}} + .Naught: // expected-warning {{case is already handled by previous patterns; consider removing it}} + () + } + } +} + +func nonmemberAccessesMemberType(_ n: ContainsEnum.Possible) { + switch n { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.Mere(_)'}} + // expected-note@-2 {{missing case: '.Twain(_, _)'}} + case ContainsEnum.Possible.Naught, + .Naught: // expected-warning {{case is already handled by previous patterns; consider removing it}} + () + } +} + +var m : ImportedEnum = .Simple + +switch m { +case imported_enums.ImportedEnum.Simple, + ImportedEnum.Simple, // expected-warning {{case is already handled by previous patterns; consider removing it}} + .Simple: // expected-warning {{case is already handled by previous patterns; consider removing it}} + () +case imported_enums.ImportedEnum.Compound, + imported_enums.ImportedEnum.Compound(_), // expected-warning {{case is already handled by previous patterns; consider removing it}} + ImportedEnum.Compound, // expected-warning {{case is already handled by previous patterns; consider removing it}} + ImportedEnum.Compound(_), // expected-warning {{case is already handled by previous patterns; consider removing it}} + .Compound, // expected-warning {{case is already handled by previous patterns; consider removing it}} + .Compound(_): // expected-warning {{case is already handled by previous patterns; consider removing it}} + () +} + +// Check that single-element tuple payloads work sensibly in patterns. + +enum LabeledScalarPayload { + case Payload(name: Int) +} + +var lsp: LabeledScalarPayload = .Payload(name: 0) +func acceptInt(_: Int) {} +func acceptString(_: String) {} + +switch lsp { +case .Payload(0): + () +case .Payload(name: 0): + () +case let .Payload(x): + acceptInt(x) + acceptString("\(x)") +case let .Payload(name: x): // expected-warning {{case is already handled by previous patterns; consider removing it}} + acceptInt(x) + acceptString("\(x)") +case let .Payload((name: x)): // expected-warning {{case is already handled by previous patterns; consider removing it}} + acceptInt(x) + acceptString("\(x)") +case .Payload(let (name: x)): // expected-warning {{case is already handled by previous patterns; consider removing it}} + acceptInt(x) + acceptString("\(x)") +case .Payload(let (name: x)): // expected-warning {{case is already handled by previous patterns; consider removing it}} + acceptInt(x) + acceptString("\(x)") +case .Payload(let x): // expected-warning {{case is already handled by previous patterns; consider removing it}} + acceptInt(x) + acceptString("\(x)") +case .Payload((let x)): // expected-warning {{case is already handled by previous patterns; consider removing it}} + acceptInt(x) + acceptString("\(x)") +} + +// Property patterns. + +struct S { + static var stat: Int = 0 + var x, y : Int + var comp : Int { + return x + y + } + + func nonProperty() {} +} + + + + + +// Tuple patterns. + +var t = (1, 2, 3) + +prefix operator +++ +infix operator +++ +prefix func +++(x: (Int,Int,Int)) -> (Int,Int,Int) { return x } +func +++(x: (Int,Int,Int), y: (Int,Int,Int)) -> (Int,Int,Int) { + return (x.0+y.0, x.1+y.1, x.2+y.2) +} + +switch t { +case (_, var a, 3): + a += 1 +case var (_, b, 3): + b += 1 +case var (_, var c, 3): // expected-error{{'var' cannot appear nested inside another 'var'}} + c += 1 +case (1, 2, 3): + () + +// patterns in expression-only positions are errors. +case +++(_, var d, 3): +// expected-error@-1{{'_' can only appear in a pattern or on the left side of an assignment}} + () +case (_, var e, 3) +++ (1, 2, 3): +// expected-error@-1{{'_' can only appear in a pattern or on the left side of an assignment}} + () +case (let (_, _, _)) + 1: +// expected-error@-1 {{'_' can only appear in a pattern or on the left side of an assignment}} + () +} + +// FIXME: We don't currently allow subpatterns for "isa" patterns that +// require interesting conditional downcasts. +class Base { } +class Derived : Base { } + + +switch [Derived(), Derived(), Base()] { +case let ds as [Derived]: // expected-error{{collection downcast in cast pattern is not implemented; use an explicit downcast to '[Derived]' instead}} + () +case is [Derived]: // expected-error{{collection downcast in cast pattern is not implemented; use an explicit downcast to '[Derived]' instead}} + () + +default: + () +} + + +// Optional patterns. +let op1 : Int? +let op2 : Int?? + +switch op1 { +case nil: break +case 1?: break +case _?: break +} + +switch op2 { +case nil: break +case _?: break +case (1?)?: break +case (_?)?: break // expected-warning {{case is already handled by previous patterns; consider removing it}} +} + + + +// Bogus diagnostic "refutable pattern match can fail" +let (responseObject: Int?) = op1 +// expected-error @-1 {{expected ',' separator}} {{25-25=,}} +// expected-error @-2 {{expected pattern}} +// expected-error @-3 {{type of expression is ambiguous without more context}} diff --git a/test/Parse/switch.swift b/test/Parse/switch.swift index d44fcacd457cb..7baf7e3ceb554 100644 --- a/test/Parse/switch.swift +++ b/test/Parse/switch.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup // TODO: Implement tuple equality in the library. // BLOCKED: @@ -246,7 +246,7 @@ case (1, _): func patternVarUsedInAnotherPattern(x: Int) { switch x { case let a, // expected-error {{'a' must be bound in every pattern}} - a: + a: // expected-error {{cannot find 'a' in scope}} break } } diff --git a/test/Parse/switch_parser_lookup.swift b/test/Parse/switch_parser_lookup.swift new file mode 100644 index 0000000000000..34a6398d7869b --- /dev/null +++ b/test/Parse/switch_parser_lookup.swift @@ -0,0 +1,647 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +// TODO: Implement tuple equality in the library. +// BLOCKED: +func ~= (x: (Int,Int), y: (Int,Int)) -> Bool { + return true +} + +func parseError1(x: Int) { + switch func {} // expected-error {{expected expression in 'switch' statement}} expected-error {{expected '{' after 'switch' subject expression}} expected-error {{expected identifier in function declaration}} expected-error {{closure expression is unused}} expected-note{{did you mean to use a 'do' statement?}} {{15-15=do }} +} + +func parseError2(x: Int) { + switch x // expected-error {{expected '{' after 'switch' subject expression}} +} + +func parseError3(x: Int) { + switch x { + case // expected-error {{expected pattern}} expected-error {{expected ':' after 'case'}} + } +} + +func parseError4(x: Int) { + switch x { + case var z where // expected-error {{expected expression for 'where' guard of 'case'}} expected-error {{expected ':' after 'case'}} + } +} + +func parseError5(x: Int) { + switch x { + case let z // expected-error {{expected ':' after 'case'}} expected-warning {{immutable value 'z' was never used}} {{8-13=_}} + } +} + +func parseError6(x: Int) { + switch x { + default // expected-error {{expected ':' after 'default'}} + } +} + +var x: Int + +switch x {} // expected-error {{'switch' statement body must have at least one 'case' or 'default' block}} + +switch x { +case 0: + x = 0 +// Multiple patterns per case +case 1, 2, 3: + x = 0 +// 'where' guard +case _ where x % 2 == 0: + x = 1 + x = 2 + x = 3 +case _ where x % 2 == 0, + _ where x % 3 == 0: + x = 1 +case 10, + _ where x % 3 == 0: + x = 1 +case _ where x % 2 == 0, + 20: + x = 1 +case var y where y % 2 == 0: + x = y + 1 +case _ where 0: // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + x = 0 +default: + x = 1 +} + +// Multiple cases per case block +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +case 0: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}} +case 1: + x = 0 +} + +switch x { +case 0: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}} +default: + x = 0 +} + +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +case 0: + x = 0 +case 1: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}} +} + +switch x { +case 0: + x = 0 +default: // expected-error {{'default' label in a 'switch' should have at least one executable statement}} {{9-9= break}} +} + +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +case 0: + ; // expected-error {{';' statements are not allowed}} {{3-5=}} +case 1: + x = 0 +} + + + +switch x { + x = 1 // expected-error{{all statements inside a switch must be covered by a 'case' or 'default'}} +default: + x = 0 +case 0: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + x = 0 +case 1: + x = 0 +} + +switch x { +default: + x = 0 +default: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + x = 0 +} + +switch x { // expected-error{{'switch' statement body must have at least one 'case' or 'default' block}} + x = 1 // expected-error{{all statements inside a switch must be covered by a 'case' or 'default'}} +} + +switch x { // expected-error{{'switch' statement body must have at least one 'case' or 'default' block}} + x = 1 // expected-error{{all statements inside a switch must be covered by a 'case' or 'default'}} + x = 2 +} + +switch x { +default: // expected-error{{'default' label in a 'switch' should have at least one executable statement}} {{9-9= break}} +case 0: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + x = 0 +} + +switch x { +default: // expected-error{{'default' label in a 'switch' should have at least one executable statement}} {{9-9= break}} +default: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + x = 0 +} + +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +default where x == 0: // expected-error{{'default' cannot be used with a 'where' guard expression}} + x = 0 +} + +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +case 0: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}} +} + +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +case 0: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}} +case 1: + x = 0 +} + +switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} +case 0: + x = 0 +case 1: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}} +} + + +case 0: // expected-error{{'case' label can only appear inside a 'switch' statement}} +var y = 0 +default: // expected-error{{'default' label can only appear inside a 'switch' statement}} +var z = 1 + +fallthrough // expected-error{{'fallthrough' is only allowed inside a switch}} + +switch x { +case 0: + fallthrough +case 1: + fallthrough +default: + fallthrough // expected-error{{'fallthrough' without a following 'case' or 'default' block}} +} + +// Fallthrough can transfer control anywhere within a case and can appear +// multiple times in the same case. +switch x { +case 0: + if true { fallthrough } + if false { fallthrough } + x += 1 +default: + x += 1 +} + +// Cases cannot contain 'var' bindings if there are multiple matching patterns +// attached to a block. They may however contain other non-binding patterns. + +var t = (1, 2) + +switch t { +case (var a, 2), (1, _): // expected-error {{'a' must be bound in every pattern}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} + () + +case (_, 2), (var a, _): // expected-error {{'a' must be bound in every pattern}} + () + +case (var a, 2), (1, var b): // expected-error {{'a' must be bound in every pattern}} expected-error {{'b' must be bound in every pattern}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} + () + +case (var a, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{17-17= break}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} +case (1, _): + () + +case (_, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{13-13= break}} +case (1, var a): // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} + () + +case (var a, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{17-17= break}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} +case (1, var b): // expected-warning {{variable 'b' was never used; consider replacing with '_' or removing it}} + () + +case (1, let b): // let bindings expected-warning {{immutable value 'b' was never used; consider replacing with '_' or removing it}} + () + +case (_, 2), (let a, _): // expected-error {{'a' must be bound in every pattern}} expected-warning {{case is already handled by previous patterns; consider removing it}} + () + +// OK +case (_, 2), (1, _): + () + +case (_, var a), (_, var a): // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} + // expected-warning@-1 {{case is already handled by previous patterns; consider removing it}} + // expected-warning@-2 {{case is already handled by previous patterns; consider removing it}} + () + +case (var a, var b), (var b, var a): // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'b' was never used; consider replacing with '_' or removing it}} + // expected-warning@-1 {{case is already handled by previous patterns; consider removing it}} + // expected-warning@-2 {{case is already handled by previous patterns; consider removing it}} + () + +case (_, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{13-13= break}} +case (1, _): + () +} + +func patternVarUsedInAnotherPattern(x: Int) { + switch x { + case let a, // expected-error {{'a' must be bound in every pattern}} + a: + break + } +} + +// Fallthroughs can only transfer control into a case label with bindings if the previous case binds a superset of those vars. +switch t { +case (1, 2): + fallthrough // expected-error {{'fallthrough' from a case which doesn't bind variable 'a'}} expected-error {{'fallthrough' from a case which doesn't bind variable 'b'}} +case (var a, var b): // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}} expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}} + t = (b, a) +} + +switch t { // specifically notice on next line that we shouldn't complain that a is unused - just never mutated +case (var a, let b): // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}} + t = (b, b) + fallthrough // ok - notice that subset of bound variables falling through is fine +case (2, let a): + t = (a, a) +} + +func patternVarDiffType(x: Int, y: Double) { + switch (x, y) { + case (1, let a): // expected-error {{pattern variable bound to type 'Double', fallthrough case bound to type 'Int'}} + fallthrough + case (let a, _): + break + } +} + +func patternVarDiffMutability(x: Int, y: Double) { + switch x { + case let a where a < 5, var a where a > 10: // expected-error {{'var' pattern binding must match previous 'let' pattern binding}}{{27-30=let}} + break + default: + break + } + switch (x, y) { + // Would be nice to have a fixit in the following line if we detect that all bindings in the same pattern have the same problem. + case let (a, b) where a < 5, var (a, b) where a > 10: // expected-error 2{{'var' pattern binding must match previous 'let' pattern binding}}{{none}} + break + case (let a, var b) where a < 5, (let a, let b) where a > 10: // expected-error {{'let' pattern binding must match previous 'var' pattern binding}}{{44-47=var}} + break + case (let a, let b) where a < 5, (var a, let b) where a > 10, (let a, var b) where a == 8: + // expected-error@-1 {{'var' pattern binding must match previous 'let' pattern binding}}{{37-40=let}} + // expected-error@-2 {{'var' pattern binding must match previous 'let' pattern binding}}{{73-76=let}} + break + default: + break + } +} + +func test_label(x : Int) { +Gronk: // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} + switch x { + case 42: return + } +} + +func enumElementSyntaxOnTuple() { + switch (1, 1) { + case .Bar: // expected-error {{value of tuple type '(Int, Int)' has no member 'Bar'}} + break + default: + break + } +} + +// sr-176 +enum Whatever { case Thing } +func f0(values: [Whatever]) { // expected-note {{'values' declared here}} + switch value { // expected-error {{cannot find 'value' in scope; did you mean 'values'?}} + case .Thing: // Ok. Don't emit diagnostics about enum case not found in type <>. + break + } +} + +// sr-720 +enum Whichever { + case Thing + static let title = "title" + static let alias: Whichever = .Thing +} +func f1(x: String, y: Whichever) { + switch x { + case Whichever.title: // Ok. Don't emit diagnostics for static member of enum. + break + case Whichever.buzz: // expected-error {{type 'Whichever' has no member 'buzz'}} + break + case Whichever.alias: // expected-error {{expression pattern of type 'Whichever' cannot match values of type 'String'}} + // expected-note@-1 {{overloads for '~=' exist with these partially matching parameter lists: (Substring, String)}} + break + default: + break + } + switch y { + case Whichever.Thing: // Ok. + break + case Whichever.alias: // Ok. Don't emit diagnostics for static member of enum. + break + case Whichever.title: // expected-error {{expression pattern of type 'String' cannot match values of type 'Whichever'}} + break + } +} + + +switch Whatever.Thing { +case .Thing: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{13-13= break}} +@unknown case _: + x = 0 +} + +switch Whatever.Thing { +case .Thing: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{13-13= break}} +@unknown default: + x = 0 +} + +switch Whatever.Thing { +case .Thing: + x = 0 +@unknown case _: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{17-17= break}} +} + +switch Whatever.Thing { +case .Thing: + x = 0 +@unknown default: // expected-error {{'default' label in a 'switch' should have at least one executable statement}} {{18-18= break}} +} + + +switch Whatever.Thing { +@unknown default: + x = 0 +default: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + x = 0 +case .Thing: + x = 0 +} + +switch Whatever.Thing { +default: + x = 0 +@unknown case _: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} expected-error {{'@unknown' can only be applied to the last case in a switch}} + x = 0 +case .Thing: + x = 0 +} + +switch Whatever.Thing { +default: + x = 0 +@unknown default: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + x = 0 +case .Thing: + x = 0 +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown default where x == 0: // expected-error{{'default' cannot be used with a 'where' guard expression}} + x = 0 +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown case _: + fallthrough // expected-error{{'fallthrough' without a following 'case' or 'default' block}} +} + +switch Whatever.Thing { +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + fallthrough +case .Thing: + break +} + +switch Whatever.Thing { +@unknown default: + fallthrough +case .Thing: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + break +} + +switch Whatever.Thing { +@unknown case _, _: // expected-error {{'@unknown' cannot be applied to multiple patterns}} + break +} + +switch Whatever.Thing { +@unknown case _, _, _: // expected-error {{'@unknown' cannot be applied to multiple patterns}} + break +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown case let value: // expected-error {{'@unknown' is only supported for catch-all cases ("case _")}} + _ = value +} + +switch (Whatever.Thing, Whatever.Thing) { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '(_, _)'}} +@unknown case (_, _): // expected-error {{'@unknown' is only supported for catch-all cases ("case _")}} + break +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown case is Whatever: // expected-error {{'@unknown' is only supported for catch-all cases ("case _")}} + // expected-warning@-1 {{'is' test is always true}} + break +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown case .Thing: // expected-error {{'@unknown' is only supported for catch-all cases ("case _")}} + break +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown case (_): // okay + break +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown case _ where x == 0: // expected-error {{'where' cannot be used with '@unknown'}} + break +} + +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}} +@unknown default where x == 0: // expected-error {{'default' cannot be used with a 'where' guard expression}} + break +} + +switch Whatever.Thing { +case .Thing: + x = 0 +#if true +@unknown case _: + x = 0 +#endif +} + +switch x { +case 0: + break +@garbage case _: // expected-error {{unknown attribute 'garbage'}} + break +} + +switch x { +case 0: + break +@garbage @moreGarbage default: // expected-error {{unknown attribute 'garbage'}} expected-error {{unknown attribute 'moreGarbage'}} + break +} + +@unknown let _ = 1 // expected-error {{unknown attribute 'unknown'}} + +switch x { +case _: + @unknown let _ = 1 // expected-error {{unknown attribute 'unknown'}} +} + +switch Whatever.Thing { +case .Thing: + break +@unknown(garbage) case _: // expected-error {{unexpected '(' in attribute 'unknown'}} + break +} +switch Whatever.Thing { +case .Thing: + break +@unknown // expected-note {{attribute already specified here}} +@unknown // expected-error {{duplicate attribute}} +case _: + break +} +switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note {{add missing case: '.Thing'}} +@unknown @garbage(foobar) // expected-error {{unknown attribute 'garbage'}} +case _: + break +} + +switch x { // expected-error {{switch must be exhaustive}} +case 1: + break +@unknown case _: // expected-note {{remove '@unknown' to handle remaining values}} {{1-10=}} + break +} + +switch x { // expected-error {{switch must be exhaustive}} +@unknown case _: // expected-note {{remove '@unknown' to handle remaining values}} {{1-10=}} + break +} + +switch x { // expected-error {{switch must be exhaustive}} +@unknown default: // expected-note {{remove '@unknown' to handle remaining values}} {{1-10=}} + break +} + +switch Whatever.Thing { +case .Thing: + break +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + break +@unknown case _: + break +} + +switch Whatever.Thing { +case .Thing: + break +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + break +@unknown default: + break +} + +switch Whatever.Thing { +case .Thing: + break +@unknown default: + break +@unknown default: // expected-error {{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + break +} + +switch Whatever.Thing { +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + break +@unknown case _: + break +} + +switch Whatever.Thing { +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + break +@unknown default: + break +} + +switch Whatever.Thing { +@unknown default: + break +@unknown default: // expected-error {{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + break +} + + +switch x { +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + break +@unknown case _: + break +} + +switch x { +@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}} + break +@unknown default: + break +} + +switch x { +@unknown default: + break +@unknown default: // expected-error {{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}} + break +} + +func testReturnBeforeUnknownDefault() { + switch x { // expected-error {{switch must be exhaustive}} + case 1: + return + @unknown default: // expected-note {{remove '@unknown' to handle remaining values}} + break + } +} + +func testReturnBeforeIncompleteUnknownDefault() { + switch x { // expected-error {{switch must be exhaustive}} + case 1: + return + @unknown default // expected-error {{expected ':' after 'default'}} + // expected-note@-1 {{remove '@unknown' to handle remaining values}} + } +} + +func testReturnBeforeIncompleteUnknownDefault2() { + switch x { // expected-error {{switch must be exhaustive}} expected-note {{do you want to add a default clause?}} + case 1: + return + @unknown // expected-error {{unknown attribute 'unknown'}} + } // expected-error {{expected declaration}} +} + +func testIncompleteArrayLiteral() { + switch x { // expected-error {{switch must be exhaustive}} + case 1: + _ = [1 // expected-error {{expected ']' in container literal expression}} expected-note {{to match this opening '['}} + @unknown default: // expected-note {{remove '@unknown' to handle remaining values}} + () + } +} diff --git a/test/Sema/diag_variable_used_in_initial.swift b/test/Sema/diag_variable_used_in_initial.swift index c84cdc9d0cdc6..c60dc5c0dc0fa 100644 --- a/test/Sema/diag_variable_used_in_initial.swift +++ b/test/Sema/diag_variable_used_in_initial.swift @@ -1,45 +1,49 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup class A1 { - func foo1() {} + func foo1() -> Int {} func foo2() { - var foo1 = foo1() // expected-error {{variable used within its own initial value}} + var foo1 = foo1() + // expected-warning@-1 {{initialization of variable 'foo1' was never used; consider replacing with assignment to '_' or removing it}} } } class A2 { var foo1 = 2 func foo2() { - // FIXME: "the var" doesn't sound right. - var foo1 = foo1 // expected-error {{variable used within its own initial value}} + var foo1 = foo1 + // expected-warning@-1 {{initialization of variable 'foo1' was never used; consider replacing with assignment to '_' or removing it}} } } class A3 { func foo2() { - // FIXME: this should also add fixit. - var foo1 = foo1() // expected-error {{variable used within its own initial value}}{{none}} + var foo1 = foo1() + // expected-warning@-1 {{initialization of variable 'foo1' was never used; consider replacing with assignment to '_' or removing it}} } - func foo1() {} + func foo1() -> Int {} } class A4 { func foo2() { - var foo1 = foo1 // expected-error {{variable used within its own initial value}}{{none}} + var foo1 = foo1 // expected-error {{use of local variable 'foo1' before its declaration}} + // expected-note@-1 {{'foo1' declared here}} } } func localContext() { class A5 { - func foo1() {} + func foo1() -> Int {} func foo2() { - var foo1 = foo1() // expected-error {{variable used within its own initial value}} + var foo1 = foo1() + // expected-warning@-1 {{initialization of variable 'foo1' was never used; consider replacing with assignment to '_' or removing it}} } class A6 { - func foo1() {} + func foo1() -> Int {} func foo2() { - var foo1 = foo1() // expected-error {{variable used within its own initial value}} + var foo1 = foo1() + // expected-warning@-1 {{initialization of variable 'foo1' was never used; consider replacing with assignment to '_' or removing it}} } } @@ -48,7 +52,7 @@ func localContext() { class A7 { func foo1() {} func foo2() { - var foo1 = foo1() // expected-error {{variable used within its own initial value}} + var foo1 = foo1() } } } diff --git a/test/Sema/diag_variable_used_in_initial_parser_lookup.swift b/test/Sema/diag_variable_used_in_initial_parser_lookup.swift new file mode 100644 index 0000000000000..6b2d7f900343e --- /dev/null +++ b/test/Sema/diag_variable_used_in_initial_parser_lookup.swift @@ -0,0 +1,56 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +class A1 { + func foo1() {} + func foo2() { + var foo1 = foo1() // expected-error {{variable used within its own initial value}} + } +} + +class A2 { + var foo1 = 2 + func foo2() { + // FIXME: "the var" doesn't sound right. + var foo1 = foo1 // expected-error {{variable used within its own initial value}} + } +} + +class A3 { + func foo2() { + // FIXME: this should also add fixit. + var foo1 = foo1() // expected-error {{variable used within its own initial value}}{{none}} + } + func foo1() {} +} + +class A4 { + func foo2() { + var foo1 = foo1 // expected-error {{variable used within its own initial value}}{{none}} + } +} + +func localContext() { + class A5 { + func foo1() {} + func foo2() { + var foo1 = foo1() // expected-error {{variable used within its own initial value}} + } + + class A6 { + func foo1() {} + func foo2() { + var foo1 = foo1() // expected-error {{variable used within its own initial value}} + } + } + + extension E { // expected-error {{declaration is only valid at file scope}} + // expected-error@-1{{cannot find type 'E' in scope}} + class A7 { + func foo1() {} + func foo2() { + var foo1 = foo1() // expected-error {{variable used within its own initial value}} + } + } + } + } +} diff --git a/test/decl/circularity.swift b/test/decl/circularity.swift index 1f2db505630a4..29af1f663a23c 100644 --- a/test/decl/circularity.swift +++ b/test/decl/circularity.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup // N.B. Validating the pattern binding initializer for `pickMe` used to cause // recursive validation of the VarDecl. Check that we don't regress now that @@ -40,7 +40,8 @@ class Base { class Sub: Base { var foo = { () -> Int in let x = 42 - return foo(1) // expected-error {{variable used within its own initial value}} + // FIXME: Bogus diagnostic + return foo(1) // expected-error {{cannot convert return expression of type '()' to return type 'Int'}} }() } diff --git a/test/decl/circularity_parser_lookup.swift b/test/decl/circularity_parser_lookup.swift new file mode 100644 index 0000000000000..be25472613ee6 --- /dev/null +++ b/test/decl/circularity_parser_lookup.swift @@ -0,0 +1,114 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +// N.B. Validating the pattern binding initializer for `pickMe` used to cause +// recursive validation of the VarDecl. Check that we don't regress now that +// this isn't the case. +public struct Cyclic { + static func pickMe(please: Bool) -> Int { return 42 } + public static let pickMe = Cyclic.pickMe(please: true) +} + +struct Node {} +struct Parameterized { + func please(_ transform: @escaping (_ otherValue: NewValue) -> Value) -> Parameterized { + fatalError() + } +} + +extension Parameterized where Value == [Node], Format == String { + static var pickMe: Parameterized { + fatalError() + } +} + +extension Parameterized where Value == Node, Format == String { + static let pickMe = Parameterized<[Node], String>.pickMe.please { [$0] } +} + +enum Loop: Circle { + struct DeLoop { } +} + +protocol Circle { + typealias DeLoop = Loop.DeLoop +} + +class Base { + static func foo(_ x: Int) {} +} + +class Sub: Base { + var foo = { () -> Int in + let x = 42 + return foo(1) // expected-error {{variable used within its own initial value}} + }() +} + +extension Float { + static let pickMe: Float = 1 +} + +extension SIMD3 { + init(_ scalar: Scalar) { self.init(repeating: scalar) } +} + +extension SIMD3 where SIMD3.Scalar == Float { + static let pickMe = SIMD3(.pickMe) +} + +// Test case with circular overrides +protocol P { + associatedtype A + // expected-note@-1 {{protocol requires nested type 'A'; do you want to add it?}} + // expected-note@-2 {{through reference here}} + func run(a: A) +} + +class C1 { + func run(a: Int) {} +} + +class C2: C1, P { + override func run(a: A) {} + // expected-error@-1 {{circular reference}} + // expected-note@-2 {{while resolving type 'A'}} + // expected-note@-3 2{{through reference here}} +} + +// Another crash to the above +open class G1 { + open func run(a: A) {} +} + +class C3: G1, P { + // expected-error@-1 {{type 'C3' does not conform to protocol 'P'}} + // expected-error@-2 {{cannot find type 'A' in scope}} + override func run(a: A) {} + // expected-error@-1 {{method does not override any method from its superclass}} +} + +// Another case that triggers circular override checking. +protocol P1 { + associatedtype X = Int // expected-note {{through reference here}} + init(x: X) +} + +class C4 { + required init(x: Int) {} +} + +class D4 : C4, P1 { // expected-note 2 {{through reference here}} + required init(x: X) { // expected-error {{circular reference}} + // expected-note@-1 {{while resolving type 'X'}} + // expected-note@-2 2{{through reference here}} + super.init(x: x) + } +} + +// SR-12236 +// N.B. This used to compile in 5.1. +protocol SR12236 { } +class SR12236_A { // expected-note {{through reference here}} + typealias Nest = SR12236 // expected-error {{circular reference}} expected-note {{through reference here}} +} +extension SR12236_A: SR12236_A.Nest { } diff --git a/test/decl/typealias/generic.swift b/test/decl/typealias/generic.swift index faf486048ec3a..732800f558492 100644 --- a/test/decl/typealias/generic.swift +++ b/test/decl/typealias/generic.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup struct MyType { // expected-note {{generic type 'MyType' declared here}} // expected-note @-1 {{arguments to generic parameter 'TyB' ('S' and 'Int') are expected to be equal}} @@ -35,8 +35,8 @@ typealias BadA = MyType // expected-error {{type 'T' constr typealias BadB = MyType // expected-error {{associated types must not have a generic parameter list}} // expected-error@-1 {{same-type requirement makes generic parameter 'T' non-generic}} -typealias BadC = MyType // expected-error {{definition conflicts with previous value}} -// expected-note @-1 {{previous definition of 'T' is here}} +typealias BadC = MyType // expected-error {{invalid redeclaration of 'T'}} +// expected-note @-1 {{'T' previously declared here}} typealias Tuple2 = (T1, T2) diff --git a/test/decl/typealias/generic_parser_lookup.swift b/test/decl/typealias/generic_parser_lookup.swift new file mode 100644 index 0000000000000..63c0cb22af2f0 --- /dev/null +++ b/test/decl/typealias/generic_parser_lookup.swift @@ -0,0 +1,443 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +struct MyType { // expected-note {{generic type 'MyType' declared here}} + // expected-note @-1 {{arguments to generic parameter 'TyB' ('S' and 'Int') are expected to be equal}} + // expected-note @-2 4 {{arguments to generic parameter 'TyA' ('Float' and 'Int') are expected to be equal}} + var a : TyA, b : TyB +} + +// +// Type aliases that reference unbound generic types -- not really generic, +// but they behave as such, in the sense that you can apply generic +// arguments to them. +// + +typealias OurType = MyType + +typealias YourType = Swift.Optional + +struct Container { + typealias YourType = Swift.Optional +} + +let _: OurType +let _: YourType +let _: Container.YourType + +// +// Bona-fide generic type aliases +// + +typealias DS = MyType + +typealias BadA = MyType // expected-error {{type 'T' constrained to non-protocol, non-class type 'Int'}} + +typealias BadB = MyType // expected-error {{associated types must not have a generic parameter list}} +// expected-error@-1 {{same-type requirement makes generic parameter 'T' non-generic}} + +typealias BadC = MyType // expected-error {{definition conflicts with previous value}} +// expected-note @-1 {{previous definition of 'T' is here}} + +typealias Tuple2 = (T1, T2) + +typealias Tuple3 = (T1, T1) where T1 : Hashable + + +let _ : Tuple2 = (1, "foo") +let _ : Tuple2 = (1, "foo") +let _ : Tuple2 = ("bar", // expected-error {{cannot convert value of type '(String, String)' to specified type 'Tuple2' (aka '(Int, String)')}} + "foo") + +func f() { + typealias Tuple2b = (T1, T2) + let _ : Tuple2b = (1, "foo") + +} + + +typealias A = MyType // expected-note {{generic type 'A' declared here}} + +typealias B = MyType + +typealias C = MyType + +// Type aliases with unused generic params. +typealias D = MyType // expected-note 3 {{'T3' declared as parameter to type 'D'}} + +typealias E = Int // expected-note {{generic type 'E' declared here}} +// expected-note@-1 {{'T1' declared as parameter to type 'E'}} +// expected-note@-2 {{'T2' declared as parameter to type 'E'}} + +typealias F = (T1) -> T2 + +// Type alias of type alias. +typealias G = A + +let _ : E = 42 +let _ : E = 42 // expected-error {{generic type 'E' specialized with too few type parameters (got 1, but expected 2)}} +let _ : E = 42 +// expected-error@-1 {{generic parameter 'T1' could not be inferred}} +// expected-error@-2 {{generic parameter 'T2' could not be inferred}} +let _ : D = D(a: 1, b: 2) +// expected-error@-1 {{generic parameter 'T3' could not be inferred}} +// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{14-14=}} + +let _ : D = D(a: 1, b: 2) + +let _ : D = D(a: 1, b: 2) +// expected-error@-1 {{generic parameter 'T3' could not be inferred}} + + +// expected-error @+2 {{generic parameter 'T3' could not be inferred}} +// expected-note @+1 {{explicitly specify the generic arguments to fix this issue}} {{31-31=}} +let _ : D = D(a: 1, b: 2) + +let _ : F = { (a : Int) -> Int in a } // Infer the types of F + +let _ : F = { a in a } // expected-error {{unable to infer type of a closure parameter 'a' in the current context}} + +_ = MyType(a: "foo", b: 42) +_ = A(a: "foo", b: 42) +_ = A(a: "foo", b: 42) +_ = A(a: "foo", // expected-error {{cannot convert value of type 'String' to expected argument type 'Int'}} + b: 42) // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} +_ = B(a: 12, b: 42) +_ = B(a: 12, b: 42 as Float) +_ = B(a: "foo", b: 42) // expected-error {{conflicting arguments to generic parameter 'T1' ('Int' vs. 'String')}} +_ = C(a: "foo", b: 42) +_ = C(a: 42, // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} + b: 42) + +_ = G(a: "foo", b: 42) +_ = G(a: "foo", b: 42) + +// Generic typealias cannot have unbound generic type. +typealias VeryBad1 = MyType // expected-error {{reference to generic type 'MyType' requires arguments in <...>}} +typealias VeryBad2 = Swift.Array // expected-error {{reference to generic type 'Array' requires arguments in <...>}} + +struct MyTypeWithHashable { +} + +typealias MTWHInt = MyTypeWithHashable +typealias MTWHInt2 = MyTypeWithHashable // expected-error {{type 'HT' does not conform to protocol 'Hashable'}} + +func f(a : MyTypeWithHashable) { + f(a: MyTypeWithHashable()) + f(a: MTWHInt()) +} + + +// Unqualified lookup of generic typealiases nested inside generic contexts +class GenericClass { + typealias TA = MyType + typealias TAI = MyType + + func testCapture(s: S, t: T) -> TA { + return TA(a: t, b: s) + } + + func testCaptureUnbound(s: S, t: T) -> TA { + return TA(a: t, b: s) + } + + func testConcrete1(s: Int, t: T) -> TA { + return TA(a: t, b: s) + } + + func testConcreteUnbound1(s: Int, t: T) -> TA { + return TA(a: t, b: s) + } + + func testConcrete2(s: Float, t: Int) -> TAI { + return TAI(a: t, b: s) + } + + func testConcreteUnbound2(s: Float, t: Int) -> TAI { + return TAI(a: t, b: s) + } + + func testCaptureInvalid1(s: S, t: T) -> TA { + return TA(a: t, b: s) // expected-error {{cannot convert return expression of type 'GenericClass.TA' (aka 'MyType') to return type 'GenericClass.TA' (aka 'MyType')}} + } + + func testCaptureInvalid2(s: Int, t: T) -> TA { + return TA(a: t, b: s) // expected-error {{cannot convert value of type 'Int' to expected argument type 'S'}} + } + + struct NestedStruct { + typealias TA = MyType<(T, V), (U, V)> + + func testCapture(x: (T, S), y: (U, S)) -> TA { + return TA(a: x, b: y) + } + } + + // Stupid corner case -- underlying type is not dependent + typealias NotDependent = Int + + func misleadingCode(_: NotDependent) {} +} + +let gc = GenericClass() +let fn: MyType = gc.testCapture(s: 1, t: 1.0) + +func use(_ t: T) {} +use(fn) + +// Make sure we apply base substitutions to the interface type of the typealias +class ConcreteClass : GenericClass { + func testSubstitutedCapture1(s: S, t: String) -> TA { + return TA(a: t, b: s) + } + + func testSubstitutedCapture2(s: S, t: String) -> TA { + return TA(a: t, b: s) + } + + func testSubstitutedCapture3(s: Int, t: String) -> TA { + return TA(a: t, b: s) + } + + func testSubstitutedCapture4(s: Int, t: String) -> TA { + return TA(a: t, b: s) + } + + func testSubstitutedCapture5(s: Float, t: Int) -> TAI { + return TAI(a: t, b: s) + } + + func testSubstitutedCapture6(s: Float, t: Int) -> TAI { + return TAI(a: t, b: s) + } +} + +// Qualified lookup of generic typealiases nested inside concrete contexts +struct ConcreteStruct { + typealias O = Optional +} + +func takesUnsugaredType1(m: MyType) {} +func takesSugaredType1(m: ConcreteClass.TA) { + takesUnsugaredType1(m: m) +} + +let _ = ConcreteStruct.O(123) +let _ = ConcreteStruct.O(123) + +let _: ConcreteStruct.O = ConcreteStruct.O(123) +let _: ConcreteStruct.O = ConcreteStruct.O(123) + +let _: ConcreteStruct.O = ConcreteStruct.O(123) +let _: ConcreteStruct.O = ConcreteStruct.O(123) + +// Qualified lookup of generic typealiases nested inside generic contexts +// +// FIXME marks cases which still don't work correctly, and either produce a +// spurious diagnostic, or are actually invalid and do not diagnose. +// +// This occurs because the constraint solver does the wrong thing with an +// UnresolvedSpecializeExpr applied to a generic typealias. +// +// In the other cases, we manage to fold the UnresolvedSpecializeExpr in the +// precheckExpression() phase, which handles generic typealiases correctly. + +let _ = GenericClass.TA(a: 4.0, b: 1) // FIXME +let _ = GenericClass.TA(a: 1, b: 4.0) + +let _ = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _ = GenericClass.TA(a: 1, b: 4.0) + +let _ = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _ = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // FIXME +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot assign value of type 'MyType' to type 'GenericClass.TA' (aka 'MyType')}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) // expected-error {{cannot assign value of type 'MyType' to type 'GenericClass.TA' (aka 'MyType')}} + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) + +func takesUnsugaredType2(m: MyType) {} +func takesSugaredType2(m: GenericClass.TA) { + takesUnsugaredType2(m: m) +} + + +// +// Error paths +// + +// This works, but in the body of the extension we see the original type +// parameters of A<>'s underlying type MyType<>, rather than the type +// parameters of A<>. +extension A {} + +extension A {} // expected-error {{generic type 'A' specialized with too few type parameters (got 1, but expected 2)}} +extension A {} // expected-error {{constrained extension must be declared on the unspecialized generic type 'MyType' with constraints specified by a 'where' clause}} +extension C {} // expected-error {{cannot find type 'T' in scope}} +extension C {} // expected-error {{constrained extension must be declared on the unspecialized generic type 'MyType' with constraints specified by a 'where' clause}} + + +protocol ErrorQ { + associatedtype Y +} +protocol ErrorP { + associatedtype X: ErrorQ // expected-note {{protocol requires nested type 'X'; do you want to add it?}} +} + +typealias ErrorA = T.X.Y + +struct ErrorB : ErrorP { // expected-error {{type 'ErrorB' does not conform to protocol 'ErrorP'}} + typealias X = ErrorC // expected-note {{possibly intended match 'ErrorB.X' (aka 'ErrorC') does not conform to 'ErrorQ'}} +} + +struct ErrorC { + typealias Y = Int +} + +typealias Y = ErrorA + +typealias Id = T + +extension Id {} // expected-error {{non-nominal type 'Id' cannot be extended}} + +class OuterGeneric { + typealias Alias = AnotherGeneric + // expected-note@-1 {{generic type 'Alias' declared here}} + class InnerNonGeneric : Alias {} + // expected-error@-1 {{reference to generic type 'OuterGeneric.Alias' requires arguments in <...>}} +} + +class AnotherGeneric {} + +// +// Generic typealiases in protocols +// + +protocol P { + associatedtype A + typealias G1 = MyType + typealias G2 = MyType + typealias G3 = () -> () + typealias G4 = (T) -> () + + func firstRequirement(_: G1) + func secondRequirement(_: G2) + func thirdRequirement(_: G3) + func fourthRequirement(_: G4) + + func firstRequirementGeneric(_: G1) + func secondRequirementGeneric(_: G2) + func thirdRequirementGeneric(_: G3, _: T) + func fourthRequirementGeneric(_: G4) +} + +struct S : P { + typealias A = Float + + func shouldFail(fn: (Int) -> ()) { + thirdRequirement(fn) + // expected-error@-1 {{cannot convert value of type '(Int) -> ()' to expected argument type '() -> ()'}} + } + + func firstRequirement(_: G1) {} + func secondRequirement(_: G2) {} + func thirdRequirement(_: G3) {} + func fourthRequirement(_: G4) {} + + func firstRequirementGeneric(_: G1) { + _ = G1.self + } + + func secondRequirementGeneric(_: G2) { + _ = G2.self + } + + func thirdRequirementGeneric(_: G3, _: T) { + _ = G3.self + } + + func fourthRequirementGeneric(_: G4) { + _ = G4.self + } + + func expressionContext() { + let _: G1 = MyType(a: S(), b: 3) + let _: G1 = MyType(a: S(), b: 3) + + let _: S.G1 = MyType(a: S(), b: 3) + let _: S.G1 = MyType(a: S(), b: 3) + + let _: G2 = MyType(a: 3, b: 1.0) + let _: G2 = MyType(a: 3, b: 1.0) + + let _: S.G2 = MyType(a: 3, b: 1.0) + let _: S.G2 = MyType(a: 3, b: 1.0) + } +} + +func takesMyType(x: MyType) {} + +func takesMyType(y: MyType) {} + +func f(x: S.G1, y: S.G2) { + takesMyType(x: x) + takesMyType(y: y) +} + +// +// Generic typealiases with requirements +// + +typealias Element = S.Iterator.Element where S : Sequence + +func takesInt(_: Element<[Int]>) {} + +takesInt(10) + +func failsRequirementCheck(_: Element) {} +// expected-error@-1 {{type 'Int' does not conform to protocol 'Sequence'}} + +// +// Sugar in base types of a typealias. +// +struct X { + typealias GY = [V] +} + +typealias GX = X + +func testSugar(_ gx: GX, _ gy: GX.GY, gz: GX.GY.Element) { + let i: Int = gx // expected-error{{cannot convert value of type 'GX' (aka 'X') to specified type 'Int'}} + let i2: Int = gy // expected-error{{cannot convert value of type 'GX.GY' (aka 'Array') to specified type 'Int'}} + let i3: Int = gz // expected-error{{cannot convert value of type 'GX.GY.Element' (aka 'Double') to specified type 'Int'}} +} diff --git a/test/decl/var/usage.swift b/test/decl/var/usage.swift index 76d145b314e56..9f89092728c4f 100644 --- a/test/decl/var/usage.swift +++ b/test/decl/var/usage.swift @@ -242,6 +242,15 @@ func testBuildConfigs() { #endif } +// same as above, but with a guard statement +func testGuardWithPoundIf(x: Int?) { + guard let x = x else { return } + +#if false + _ = x +#endif +} + // Bogus 'never mutated' warning when protocol variable is mutated only by mutating method protocol Fooable { mutating func mutFoo() diff --git a/test/decl/var/variables.swift b/test/decl/var/variables.swift index f2b5d0190c4b1..b470686ca0819 100644 --- a/test/decl/var/variables.swift +++ b/test/decl/var/variables.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup var t1 : Int var t2 = 10 @@ -14,17 +14,30 @@ var bfx : Int, bfy : Int _ = 10 -var self1 = self1 // expected-error {{variable used within its own initial value}} -var self2 : Int = self2 // expected-error {{variable used within its own initial value}} -var (self3) : Int = self3 // expected-error {{variable used within its own initial value}} -var (self4) : Int = self4 // expected-error {{variable used within its own initial value}} -var self5 = self5 + self5 // expected-error 2 {{variable used within its own initial value}} -var self6 = !self6 // expected-error {{variable used within its own initial value}} -var (self7a, self7b) = (self7b, self7a) // expected-error 2 {{variable used within its own initial value}} +var self1 = self1 +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} + +var self2 : Int = self2 +var (self3) : Int = self3 +var (self4) : Int = self4 + +var self5 = self5 + self5 +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} + +var self6 = !self6 +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} + +var (self7a, self7b) = (self7b, self7a) +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} var self8 = 0 func testShadowing() { - var self8 = self8 // expected-error {{variable used within its own initial value}} + var self8 = self8 + // expected-warning@-1 {{initialization of variable 'self8' was never used; consider replacing with assignment to '_' or removing it}} } var (paren) = 0 diff --git a/test/decl/var/variables_parser_lookup.swift b/test/decl/var/variables_parser_lookup.swift new file mode 100644 index 0000000000000..8b2fa5c2aa080 --- /dev/null +++ b/test/decl/var/variables_parser_lookup.swift @@ -0,0 +1,121 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +var t1 : Int +var t2 = 10 +var t3 = 10, t4 = 20.0 +var (t5, t6) = (10, 20.0) +var t7, t8 : Int +var t9, t10 = 20 // expected-error {{type annotation missing in pattern}} +var t11, t12 : Int = 20 // expected-error {{type annotation missing in pattern}} +var t13 = 2.0, t14 : Int +var (x = 123, // expected-error {{expected ',' separator}} {{7-7=,}} expected-error {{expected pattern}} + y = 456) : (Int,Int) +var bfx : Int, bfy : Int + +_ = 10 + +var self1 = self1 // expected-error {{variable used within its own initial value}} +var self2 : Int = self2 // expected-error {{variable used within its own initial value}} +var (self3) : Int = self3 // expected-error {{variable used within its own initial value}} +var (self4) : Int = self4 // expected-error {{variable used within its own initial value}} +var self5 = self5 + self5 // expected-error 2 {{variable used within its own initial value}} +var self6 = !self6 // expected-error {{variable used within its own initial value}} +var (self7a, self7b) = (self7b, self7a) // expected-error 2 {{variable used within its own initial value}} + +var self8 = 0 +func testShadowing() { + var self8 = self8 // expected-error {{variable used within its own initial value}} +} + +var (paren) = 0 +var paren2: Int = paren + +struct Broken { + var b : Bool = True // expected-error{{cannot find 'True' in scope}} +} + +// rdar://16252090 - Warning when inferring empty tuple type for declarations +var emptyTuple = testShadowing() // expected-warning {{variable 'emptyTuple' inferred to have type '()'}} \ + // expected-note {{add an explicit type annotation to silence this warning}} {{15-15=: ()}} + +// rdar://15263687 - Diagnose variables inferenced to 'AnyObject' +var ao1 : AnyObject +var ao2 = ao1 + +var aot1 : AnyObject.Type +var aot2 = aot1 // expected-warning {{variable 'aot2' inferred to have type 'AnyObject.Type', which may be unexpected}} \ + // expected-note {{add an explicit type annotation to silence this warning}} {{9-9=: AnyObject.Type}} + + +for item in [AnyObject]() { // No warning in for-each loop. + _ = item +} + + +// Type inference of _Nil very coherent but kind of useless +var ptr = nil // expected-error {{'nil' requires a contextual type}} + +func testAnyObjectOptional() -> AnyObject? { + let x = testAnyObjectOptional() + return x +} + +// SR-11511 Warning for inferring an array of empty tuples +var arrayOfEmptyTuples = [""].map { print($0) } // expected-warning {{variable 'arrayOfEmptyTuples' inferred to have type '[()]'}} \ + // expected-note {{add an explicit type annotation to silence this warning}} {{23-23=: [()]}} + +var maybeEmpty = Optional(arrayOfEmptyTuples) // expected-warning {{variable 'maybeEmpty' inferred to have type '[()]?'}} \ + // expected-note {{add an explicit type annotation to silence this warning}} {{15-15=: [()]?}} + +var shouldWarnWithoutSugar = (arrayOfEmptyTuples as Array<()>) // expected-warning {{variable 'shouldWarnWithoutSugar' inferred to have type 'Array<()>'}} \ + // expected-note {{add an explicit type annotation to silence this warning}} {{27-27=: Array<()>}} + +class SomeClass {} + +// weak let's should be rejected +weak let V = SomeClass() // expected-error {{'weak' must be a mutable variable, because it may change at runtime}} + +let a = b ; let b = a +// expected-error@-1 {{circular reference}} +// expected-note@-2 {{through reference here}} +// expected-note@-3 {{through reference here}} +// expected-note@-4 {{through reference here}} +// expected-note@-5 {{through reference here}} +// expected-note@-6 {{through reference here}} + +// Swift should warn about immutable default initialized values +let uselessValue : String? + + +func tuplePatternDestructuring(_ x : Int, y : Int) { + let (b: _, a: h) = (b: x, a: y) + _ = h + + // Destructuring tuple with labels doesn't work + let (i, j) = (b: x, a: y) + _ = i+j + + // QoI: type variable reconstruction failing for tuple types + let (x: g1, a: h1) = (b: x, a: y) // expected-error {{cannot convert value of type '(b: Int, a: Int)' to specified type '(x: Int, a: Int)'}} +} + +// Crash while compiling attached test-app. +func test21057425() -> (Int, Int) { + let x: Int = "not an int!", y = 0 // expected-error{{cannot convert value of type 'String' to specified type 'Int'}} + return (x, y) +} + +// rdar://problem/21081340 +func test21081340() { + func foo() { } + let (x: a, y: b): () = foo() // expected-error{{tuple pattern has the wrong length for tuple type '()'}} +} + +// Swift let late initialization in top level control flow statements +if true { + let s : Int + s = 42 // should be valid. + _ = s +} + + diff --git a/test/diagnostics/Localization/en_localization.swift b/test/diagnostics/Localization/en_localization.swift index 6c9842f1d1df9..605c00dcaccf1 100644 --- a/test/diagnostics/Localization/en_localization.swift +++ b/test/diagnostics/Localization/en_localization.swift @@ -1,8 +1,11 @@ -// RUN: %target-typecheck-verify-swift -localization-path %S/Inputs -locale en +// RUN: %target-typecheck-verify-swift -localization-path %S/Inputs -locale en -disable-parser-lookup _ = "HI! // expected-error@-1{{unterminated string literal}} -var self1 = self1 // expected-error {{variable used within its own initial value}} +var self1 = self1 +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} + struct Broken { var b : Bool = True // expected-error{{cannot find 'True' in scope}} } diff --git a/test/diagnostics/Localization/en_localization_parser_lookup.swift b/test/diagnostics/Localization/en_localization_parser_lookup.swift new file mode 100644 index 0000000000000..dd5ed8f861127 --- /dev/null +++ b/test/diagnostics/Localization/en_localization_parser_lookup.swift @@ -0,0 +1,9 @@ +// RUN: %target-typecheck-verify-swift -localization-path %S/Inputs -locale en -enable-parser-lookup + +_ = "HI! +// expected-error@-1{{unterminated string literal}} +var self1 = self1 // expected-error {{variable used within its own initial value}} +struct Broken { + var b : Bool = True // expected-error{{cannot find 'True' in scope}} +} +var v1 : Int[1 // expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} diff --git a/test/diagnostics/Localization/fr_localization.swift b/test/diagnostics/Localization/fr_localization.swift index 9caf88a529e37..c2acde077a92a 100644 --- a/test/diagnostics/Localization/fr_localization.swift +++ b/test/diagnostics/Localization/fr_localization.swift @@ -1,12 +1,17 @@ // RUN: %empty-directory(%t) // RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/fr.yaml --output-directory=%t/ // RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/en.yaml --output-directory=%t/ 2>&1 | %FileCheck %s -// RUN: %target-typecheck-verify-swift -localization-path %t -locale fr +// RUN: %target-typecheck-verify-swift -localization-path %t -locale fr -disable-parser-lookup // CHECK: These diagnostic IDs are no longer availiable: 'not_available_in_def, not_available_in_def_2, not_available_in_def_3, not_available_in_def_4, not_available_in_def_5' _ = "HI! // expected-error@-1{{chaĂ®ne non terminĂ©e littĂ©rale}} -var self1 = self1 // expected-error {{variable utilisĂ©e dans sa propre valeur initiale}} + +// FIXME: This used to produce a localized diagnostic. + +var self1 = self1 // expected-note 2{{through reference here}} +// expected-error@-1 {{circular reference}} + struct Broken { var b : Bool = True // expected-error{{impossible de trouver 'True' portĂ©e}} } diff --git a/test/diagnostics/Localization/fr_localization_parser_lookup.swift b/test/diagnostics/Localization/fr_localization_parser_lookup.swift new file mode 100644 index 0000000000000..b46efe97f06c2 --- /dev/null +++ b/test/diagnostics/Localization/fr_localization_parser_lookup.swift @@ -0,0 +1,13 @@ +// RUN: %empty-directory(%t) +// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/fr.yaml --output-directory=%t/ +// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/en.yaml --output-directory=%t/ 2>&1 | %FileCheck %s +// RUN: %target-typecheck-verify-swift -localization-path %t -locale fr -enable-parser-lookup + +// CHECK: These diagnostic IDs are no longer availiable: 'not_available_in_def, not_available_in_def_2, not_available_in_def_3, not_available_in_def_4, not_available_in_def_5' +_ = "HI! +// expected-error@-1{{chaĂ®ne non terminĂ©e littĂ©rale}} +var self1 = self1 // expected-error {{variable utilisĂ©e dans sa propre valeur initiale}} +struct Broken { + var b : Bool = True // expected-error{{impossible de trouver 'True' portĂ©e}} +} +var v1 : Int[1 // expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} diff --git a/test/diagnostics/Localization/no_localization_files_and_wrong_path.swift b/test/diagnostics/Localization/no_localization_files_and_wrong_path.swift index f2a27dcf7b3f5..2184a5d762fc5 100644 --- a/test/diagnostics/Localization/no_localization_files_and_wrong_path.swift +++ b/test/diagnostics/Localization/no_localization_files_and_wrong_path.swift @@ -1,11 +1,14 @@ -// RUN: %target-typecheck-verify-swift -localization-path /Not_exsisting_path -locale en +// RUN: %target-typecheck-verify-swift -localization-path /Not_exsisting_path -locale en -disable-parser-lookup // :0: warning: cannot find translations for 'en' at '/Not_exsisting_path/en.yaml': no such file // :0: warning: specified localization directory '/Not_exsisting_path' does not exist, translation is disabled _ = "HI! // expected-error@-1{{unterminated string literal}} -var self1 = self1 // expected-error {{variable used within its own initial value}} +var self1 = self1 +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} + struct Broken { var b : Bool = True // expected-error{{cannot find 'True' in scope}} } diff --git a/test/diagnostics/Localization/no_localization_files_and_wrong_path_parser_lookup.swift b/test/diagnostics/Localization/no_localization_files_and_wrong_path_parser_lookup.swift new file mode 100644 index 0000000000000..88633ab4f03b3 --- /dev/null +++ b/test/diagnostics/Localization/no_localization_files_and_wrong_path_parser_lookup.swift @@ -0,0 +1,11 @@ +// RUN: %target-typecheck-verify-swift -localization-path /Not_exsisting_path -locale en -enable-parser-lookup + +// :0: warning: cannot find translations for 'en' at '/Not_exsisting_path/en.yaml': no such file +// :0: warning: specified localization directory '/Not_exsisting_path' does not exist, translation is disabled + +_ = "HI! +// expected-error@-1{{unterminated string literal}} +var self1 = self1 // expected-error {{variable used within its own initial value}} +struct Broken { + var b : Bool = True // expected-error{{cannot find 'True' in scope}} +} diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift index 90514b405d185..ad884058d150f 100644 --- a/test/expr/closure/closures.swift +++ b/test/expr/closure/closures.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup var func6 : (_ fn : (Int,Int) -> Int) -> () var func6a : ((Int, Int) -> Int) -> () @@ -116,9 +116,14 @@ func f0(_ a: Any) -> Int { return 1 } assert(f0(1) == 1) -var selfRef = { selfRef() } // expected-error {{variable used within its own initial value}} +var selfRef = { selfRef() } +// expected-note@-1 2{{through reference here}} +// expected-error@-2 {{circular reference}} +// expected-error@-3 {{unable to infer closure type in the current context}} + var nestedSelfRef = { - var recursive = { nestedSelfRef() } // expected-error {{variable used within its own initial value}} + var recursive = { nestedSelfRef() } + // expected-warning@-1 {{variable 'recursive' was never mutated; consider changing to 'let' constant}} recursive() } @@ -319,7 +324,7 @@ func testCaptureBehavior(_ ptr : SomeClass) { doStuff { [weak v1] in v1!.foo() } // expected-warning @+2 {{variable 'v1' was written to, but never read}} doStuff { [weak v1, // expected-note {{previous}} - weak v1] in v1!.foo() } // expected-error {{definition conflicts with previous value}} + weak v1] in v1!.foo() } // expected-error {{invalid redeclaration of 'v1'}} doStuff { [unowned v2] in v2.foo() } doStuff { [unowned(unsafe) v2] in v2.foo() } doStuff { [unowned(safe) v2] in v2.foo() } diff --git a/test/expr/closure/closures_parser_lookup.swift b/test/expr/closure/closures_parser_lookup.swift new file mode 100644 index 0000000000000..1ec9182c62d59 --- /dev/null +++ b/test/expr/closure/closures_parser_lookup.swift @@ -0,0 +1,526 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +var func6 : (_ fn : (Int,Int) -> Int) -> () +var func6a : ((Int, Int) -> Int) -> () +var func6b : (Int, (Int, Int) -> Int) -> () +func func6c(_ f: (Int, Int) -> Int, _ n: Int = 0) {} + + +// Expressions can be auto-closurified, so that they can be evaluated separately +// from their definition. +var closure1 : () -> Int = {4} // Function producing 4 whenever it is called. +var closure2 : (Int,Int) -> Int = { 4 } // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{36-36= _,_ in}} +var closure3a : () -> () -> (Int,Int) = {{ (4, 2) }} // multi-level closing. +var closure3b : (Int,Int) -> (Int) -> (Int,Int) = {{ (4, 2) }} // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{52-52=_,_ in }} +// expected-error@-1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{53-53= _ in}} +var closure4 : (Int,Int) -> Int = { $0 + $1 } +var closure5 : (Double) -> Int = { + $0 + 1.0 + // expected-error@-1 {{cannot convert value of type 'Double' to closure result type 'Int'}} +} + +var closure6 = $0 // expected-error {{anonymous closure argument not contained in a closure}} + +var closure7 : Int = { 4 } // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{27-27=()}} // expected-note {{Remove '=' to make 'closure7' a computed property}}{{20-22=}} + +var capturedVariable = 1 +var closure8 = { [capturedVariable] in + capturedVariable += 1 // expected-error {{left side of mutating operator isn't mutable: 'capturedVariable' is an immutable capture}} +} + +func funcdecl1(_ a: Int, _ y: Int) {} +func funcdecl3() -> Int {} +func funcdecl4(_ a: ((Int) -> Int), _ b: Int) {} + +func funcdecl5(_ a: Int, _ y: Int) { + // Pass in a closure containing the call to funcdecl3. + funcdecl4({ funcdecl3() }, 12) // expected-error {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{14-14= _ in}} + + + func6({$0 + $1}) // Closure with two named anonymous arguments + func6({($0) + $1}) // Closure with sequence expr inferred type + func6({($0) + $0}) // // expected-error {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 1 was used in closure body}} + + + var testfunc : ((), Int) -> Int // expected-note {{'testfunc' declared here}} + testfunc({$0+1}) // expected-error {{missing argument for parameter #2 in call}} + // expected-error@-1 {{cannot convert value of type '(Int) -> Int' to expected argument type '()'}} + + funcdecl5(1, 2) // recursion. + + // Element access from a tuple. + var a : (Int, f : Int, Int) + var b = a.1+a.f + + // Tuple expressions with named elements. + var i : (y : Int, x : Int) = (x : 42, y : 11) // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}} + funcdecl1(123, 444) + + // Calls. + 4() // expected-error {{cannot call value of non-function type 'Int'}}{{4-6=}} + + + // rdar://12017658 - Infer some argument types from func6. + func6({ a, b -> Int in a+b}) + // Return type inference. + func6({ a,b in a+b }) + + // Infer incompatible type. + func6({a,b -> Float in 4.0 }) // expected-error {{declared closure result 'Float' is incompatible with contextual type 'Int'}} {{17-22=Int}} // Pattern doesn't need to name arguments. + func6({ _,_ in 4 }) + + func6({a,b in 4.0 }) // expected-error {{cannot convert value of type 'Double' to closure result type 'Int'}} + + // TODO: This diagnostic can be improved: rdar://22128205 + func6({(a : Float, b) in 4 }) // expected-error {{cannot convert value of type '(Float, Int) -> Int' to expected argument type '(Int, Int) -> Int'}} + + + + var fn = {} + var fn2 = { 4 } + + + var c : Int = { a,b -> Int in a+b} // expected-error{{cannot convert value of type '(Int, Int) -> Int' to specified type 'Int'}} + + +} + +func unlabeledClosureArgument() { + + func add(_ x: Int, y: Int) -> Int { return x + y } + func6a({$0 + $1}) // single closure argument + func6a(add) + func6b(1, {$0 + $1}) // second arg is closure + func6b(1, add) + func6c({$0 + $1}) // second arg is default int + func6c(add) +} + +// rdar://11935352 - closure with no body. +func closure_no_body(_ p: () -> ()) { + return closure_no_body({}) +} + + +// rdar://12019415 +func t() { + let u8 : UInt8 = 1 + let x : Bool = true + + if 0xA0..<0xBF ~= Int(u8) && x { + } +} + +// +func f0(_ a: Any) -> Int { return 1 } +assert(f0(1) == 1) + + +var selfRef = { selfRef() } // expected-error {{variable used within its own initial value}} +var nestedSelfRef = { + var recursive = { nestedSelfRef() } // expected-error {{variable used within its own initial value}} + recursive() +} + +var shadowed = { (shadowed: Int) -> Int in + let x = shadowed + return x +} // no-warning +var shadowedShort = { (shadowedShort: Int) -> Int in shadowedShort+1 } // no-warning + + +func anonymousClosureArgsInClosureWithArgs() { + func f(_: String) {} + var a1 = { () in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} + var a2 = { () -> Int in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} + var a3 = { (z: Int) in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'z'?}} {{26-28=z}} + var a4 = { (z: [Int], w: [Int]) in + f($0.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'z'?}} {{7-9=z}} expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} + f($1.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'w'?}} {{7-9=w}} expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} + } + var a5 = { (_: [Int], w: [Int]) in + f($0.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} + f($1.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'w'?}} {{7-9=w}} + // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'String'}} + } +} + +func doStuff(_ fn : @escaping () -> Int) {} +func doVoidStuff(_ fn : @escaping () -> ()) {} + +// Require specifying self for locations in code where strong reference cycles are likely +class ExplicitSelfRequiredTest { + var x = 42 + func method() -> Int { + // explicit closure requires an explicit "self." base or an explicit capture. + doVoidStuff({ self.x += 1 }) + doVoidStuff({ [self] in x += 1 }) + doVoidStuff({ [self = self] in x += 1 }) + doVoidStuff({ [unowned self] in x += 1 }) + doVoidStuff({ [unowned(unsafe) self] in x += 1 }) + doVoidStuff({ [unowned self = self] in x += 1 }) + + doStuff({ [self] in x+1 }) + doStuff({ [self = self] in x+1 }) + doStuff({ self.x+1 }) + doStuff({ [unowned self] in x+1 }) + doStuff({ [unowned(unsafe) self] in x+1 }) + doStuff({ [unowned self = self] in x+1 }) + doStuff({ x+1 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} expected-note{{reference 'self.' explicitly}} {{15-15=self.}} + doVoidStuff({ doStuff({ x+1 })}) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{28-28= [self] in}} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} + doVoidStuff({ x += 1 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{19-19=self.}} + doVoidStuff({ _ = "\(x)"}) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} + doVoidStuff({ [y = self] in x += 1 }) // expected-warning {{capture 'y' was never used}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{20-20=self, }} expected-note{{reference 'self.' explicitly}} {{33-33=self.}} + doStuff({ [y = self] in x+1 }) // expected-warning {{capture 'y' was never used}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} + doVoidStuff({ [weak self] in x += 1 }) // expected-note {{weak capture of 'self' here does not enable implicit 'self'}} expected-warning {{variable 'self' was written to, but never read}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} + doStuff({ [weak self] in x+1 }) // expected-note {{weak capture of 'self' here does not enable implicit 'self'}} expected-warning {{variable 'self' was written to, but never read}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} + doVoidStuff({ [self = self.x] in x += 1 }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} + doStuff({ [self = self.x] in x+1 }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} + + // Methods follow the same rules as properties, uses of 'self' without capturing must be marked with "self." + doStuff { method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} expected-note{{reference 'self.' explicitly}} {{15-15=self.}} + doVoidStuff { _ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{23-23=self.}} + doVoidStuff { _ = "\(method())" } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} + doVoidStuff { () -> () in _ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self]}} expected-note{{reference 'self.' explicitly}} {{35-35=self.}} + doVoidStuff { [y = self] in _ = method() } // expected-warning {{capture 'y' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{20-20=self, }} expected-note{{reference 'self.' explicitly}} {{37-37=self.}} + doStuff({ [y = self] in method() }) // expected-warning {{capture 'y' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} + doVoidStuff({ [weak self] in _ = method() }) // expected-note {{weak capture of 'self' here does not enable implicit 'self'}} expected-warning {{variable 'self' was written to, but never read}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} + doStuff({ [weak self] in method() }) // expected-note {{weak capture of 'self' here does not enable implicit 'self'}} expected-warning {{variable 'self' was written to, but never read}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} + doVoidStuff({ [self = self.x] in _ = method() }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} + doStuff({ [self = self.x] in method() }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} + doVoidStuff { _ = self.method() } + doVoidStuff { [self] in _ = method() } + doVoidStuff { [self = self] in _ = method() } + doVoidStuff({ [unowned self] in _ = method() }) + doVoidStuff({ [unowned(unsafe) self] in _ = method() }) + doVoidStuff({ [unowned self = self] in _ = method() }) + + doStuff { self.method() } + doStuff { [self] in method() } + doStuff({ [self = self] in method() }) + doStuff({ [unowned self] in method() }) + doStuff({ [unowned(unsafe) self] in method() }) + doStuff({ [unowned self = self] in method() }) + + // When there's no space between the opening brace and the first expression, insert it + doStuff {method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in }} expected-note{{reference 'self.' explicitly}} {{14-14=self.}} + doVoidStuff {_ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in }} expected-note{{reference 'self.' explicitly}} {{22-22=self.}} + doVoidStuff {() -> () in _ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self]}} expected-note{{reference 'self.' explicitly}} {{34-34=self.}} + // With an empty capture list, insertion should should be suggested without a comma + doStuff { [] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} expected-note{{reference 'self.' explicitly}} {{21-21=self.}} + doStuff { [ ] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} expected-note{{reference 'self.' explicitly}} {{23-23=self.}} + doStuff { [ /* This space intentionally left blank. */ ] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} expected-note{{reference 'self.' explicitly}} {{65-65=self.}} + // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} + doStuff { [ // Nothing in this capture list! + ] + in + method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{9-9=self.}} + } + // An inserted capture list should be on the same line as the opening brace, immediately following it. + // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} + doStuff { + method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} + } + // expected-note@+2 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} + // Note: Trailing whitespace on the following line is intentional and should not be removed! + doStuff { + method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} + } + // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} + doStuff { // We have stuff to do. + method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} + } + // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} + doStuff {// We have stuff to do. + method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} + } + + // String interpolation should offer the diagnosis and fix-its at the expected locations + doVoidStuff { _ = "\(method())" } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} + doVoidStuff { _ = "\(x+1)" } // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} + + // If we already have a capture list, self should be added to the list + let y = 1 + doStuff { [y] in method() } // expected-warning {{capture 'y' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} expected-note{{reference 'self.' explicitly}} {{22-22=self.}} + doStuff { [ // expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} + y // expected-warning {{capture 'y' was never used}} + ] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{14-14=self.}} + + // "self." shouldn't be required in the initializer expression in a capture list + // This should not produce an error, "x" isn't being captured by the closure. + doStuff({ [myX = x] in myX }) + + // This should produce an error, since x is used within the inner closure. + doStuff({ [myX = {x}] in 4 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{23-23= [self] in }} expected-note{{reference 'self.' explicitly}} {{23-23=self.}} + // expected-warning @-1 {{capture 'myX' was never used}} + + return 42 + } +} + +// If the implicit self is of value type, no diagnostic should be produced. +struct ImplicitSelfAllowedInStruct { + var x = 42 + mutating func method() -> Int { + doStuff({ x+1 }) + doVoidStuff({ x += 1 }) + doStuff({ method() }) + doVoidStuff({ _ = method() }) + } + + func method2() -> Int { + doStuff({ x+1 }) + doVoidStuff({ _ = x+1 }) + doStuff({ method2() }) + doVoidStuff({ _ = method2() }) + } +} + +enum ImplicitSelfAllowedInEnum { + case foo + var x: Int { 42 } + mutating func method() -> Int { + doStuff({ x+1 }) + doVoidStuff({ _ = x+1 }) + doStuff({ method() }) + doVoidStuff({ _ = method() }) + } + + func method2() -> Int { + doStuff({ x+1 }) + doVoidStuff({ _ = x+1 }) + doStuff({ method2() }) + doVoidStuff({ _ = method2() }) + } +} + + +class SomeClass { + var field : SomeClass? + func foo() -> Int {} +} + +func testCaptureBehavior(_ ptr : SomeClass) { + // Test normal captures. + weak var wv : SomeClass? = ptr + unowned let uv : SomeClass = ptr + unowned(unsafe) let uv1 : SomeClass = ptr + unowned(safe) let uv2 : SomeClass = ptr + doStuff { wv!.foo() } + doStuff { uv.foo() } + doStuff { uv1.foo() } + doStuff { uv2.foo() } + + + // Capture list tests + let v1 : SomeClass? = ptr + let v2 : SomeClass = ptr + + doStuff { [weak v1] in v1!.foo() } + // expected-warning @+2 {{variable 'v1' was written to, but never read}} + doStuff { [weak v1, // expected-note {{previous}} + weak v1] in v1!.foo() } // expected-error {{definition conflicts with previous value}} + doStuff { [unowned v2] in v2.foo() } + doStuff { [unowned(unsafe) v2] in v2.foo() } + doStuff { [unowned(safe) v2] in v2.foo() } + doStuff { [weak v1, weak v2] in v1!.foo() + v2!.foo() } + + let i = 42 + // expected-warning @+1 {{variable 'i' was never mutated}} + doStuff { [weak i] in i! } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}} +} + +extension SomeClass { + func bar() { + doStuff { [unowned self] in self.foo() } + doStuff { [unowned xyz = self.field!] in xyz.foo() } + doStuff { [weak xyz = self.field] in xyz!.foo() } + + // rdar://16889886 - Assert when trying to weak capture a property of self in a lazy closure + // FIXME: We should probably offer a fix-it to the field capture error and suppress the 'implicit self' error. https://bugs.swift.org/browse/SR-11634 + doStuff { [weak self.field] in field!.foo() } // expected-error {{fields may only be captured by assigning to a specific name}} expected-error {{reference to property 'field' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} {{36-36=self.}} expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} + // expected-warning @+1 {{variable 'self' was written to, but never read}} + doStuff { [weak self&field] in 42 } // expected-error {{expected ']' at end of capture list}} + + } + + func strong_in_capture_list() { + // QOI: "[strong self]" in capture list generates unhelpful error message + _ = {[strong self] () -> () in return } // expected-error {{expected 'weak', 'unowned', or no specifier in capture list}} + } +} + + +// Observed variable in a closure triggers an assertion +var closureWithObservedProperty: () -> () = { + var a: Int = 42 { // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} + willSet { + _ = "Will set a to \(newValue)" + } + didSet { + _ = "Did set a with old value of \(oldValue)" + } + } +} + +; + +{}() // expected-error{{top-level statement cannot begin with a closure expression}} + + + +// rdar://19179412 - Crash on valid code. +func rdar19179412() -> (Int) -> Int { + return { x in + class A { + let d : Int = 0 + } + return 0 + } +} + +// Test coercion of single-expression closure return types to void. +func takesVoidFunc(_ f: () -> ()) {} +var i: Int = 1 + +// expected-warning @+1 {{expression of type 'Int' is unused}} +takesVoidFunc({i}) +// expected-warning @+1 {{expression of type 'Int' is unused}} +var f1: () -> () = {i} +var x = {return $0}(1) + +func returnsInt() -> Int { return 0 } +takesVoidFunc(returnsInt) // expected-error {{cannot convert value of type '() -> Int' to expected argument type '() -> ()'}} +takesVoidFunc({() -> Int in 0}) // expected-error {{declared closure result 'Int' is incompatible with contextual type '()'}} {{22-25=()}} + +// These used to crash the compiler, but were fixed to support the implementation of rdar://problem/17228969 +Void(0) // expected-error{{argument passed to call that takes no arguments}} +_ = {0} + +// "multi-statement closures require an explicit return type" should be an error not a note +let samples = { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{16-16= () -> <#Result#> in }} + if (i > 10) { return true } + else { return false } + }() + +// Swift error: cannot capture '$0' before it is declared +func f(_ fp : (Bool, Bool) -> Bool) {} +f { $0 && !$1 } + + +// unexpected error on self. capture inside class method +func TakesIntReturnsVoid(_ fp : ((Int) -> ())) {} + +struct TestStructWithStaticMethod { + static func myClassMethod(_ count: Int) { + // Shouldn't require "self." + TakesIntReturnsVoid { _ in myClassMethod(0) } + } +} + +class TestClassWithStaticMethod { + class func myClassMethod(_ count: Int) { + // Shouldn't require "self." + TakesIntReturnsVoid { _ in myClassMethod(0) } + } +} + +// Test that we can infer () as the result type of these closures. +func genericOne(_ a: () -> T) {} +func genericTwo(_ a: () -> T, _ b: () -> T) {} +genericOne {} +genericTwo({}, {}) + + +// QoI: Warning for unused capture list variable should be customized +class r22344208 { + func f() { + let q = 42 + let _: () -> Int = { + [unowned self, // expected-warning {{capture 'self' was never used}} + q] in // expected-warning {{capture 'q' was never used}} + 1 } + } +} + +var f = { (s: Undeclared) -> Int in 0 } // expected-error {{cannot find type 'Undeclared' in scope}} + +// Swift compiler crashes when using closure, declared to return illegal type. +func r21375863() { + var width = 0 // expected-warning {{variable 'width' was never mutated}} + var height = 0 // expected-warning {{variable 'height' was never mutated}} + var bufs: [[UInt8]] = (0..<4).map { _ -> [asdf] in // expected-error {{cannot find type 'asdf' in scope}} expected-warning {{variable 'bufs' was never used}} + [UInt8](repeating: 0, count: width*height) + } +} + +// +// Don't crash if we infer a closure argument to have a tuple type containing inouts. +func r25993258_helper(_ fn: (inout Int, Int) -> ()) {} +func r25993258a() { + r25993258_helper { x in () } // expected-error {{contextual closure type '(inout Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} +} +func r25993258b() { + r25993258_helper { _ in () } // expected-error {{contextual closure type '(inout Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} +} + +// We have to map the captured var type into the right generic environment. +class GenericClass {} + +func lvalueCapture(c: GenericClass) { + var cc = c + weak var wc = c + + func innerGeneric(_: U) { + _ = cc + _ = wc + + cc = wc! + } +} + +// Don't expose @lvalue-ness in diagnostics. +let closure = { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{16-16= () -> <#Result#> in }} + var helper = true + return helper +} + +// SR-9839 +func SR9839(_ x: @escaping @convention(block) () -> Void) {} + +func id(_ x: T) -> T { + return x +} + +var qux: () -> Void = {} + +SR9839(qux) +SR9839(id(qux)) // expected-error {{conflicting arguments to generic parameter 'T' ('() -> Void' vs. '@convention(block) () -> Void')}} + +func forceUnwrap(_ x: T?) -> T { + return x! +} + +var qux1: (() -> Void)? = {} + +SR9839(qux1!) +SR9839(forceUnwrap(qux1)) + +// rdar://problem/65155671 - crash referencing parameter of outer closure +func rdar65155671(x: Int) { + { a in + _ = { [a] in a } + }(x) +} + +func sr3186(_ f: (@escaping (@escaping (T) -> U) -> ((T) -> U))) -> ((T) -> U) { + return { x in return f(sr3186(f))(x) } +} + +class SR3186 { + init() { + // expected-warning@+1{{capture 'self' was never used}} + let v = sr3186 { f in { [unowned self, f] x in x != 1000 ? f(x + 1) : "success" } }(0) + print("\(v)") + } +} diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift index 4479f9a74fc15..d4dcbe24a27d1 100644 --- a/test/expr/expressions.swift +++ b/test/expr/expressions.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup //===----------------------------------------------------------------------===// // Tests and samples. @@ -246,15 +246,16 @@ func test_as_2() { func test_lambda() { // A simple closure. var a = { (value: Int) -> () in markUsed(value+1) } + // expected-warning@-1 {{initialization of variable 'a' was never used; consider replacing with assignment to '_' or removing it}} // A recursive lambda. - // FIXME: This should definitely be accepted. var fib = { (n: Int) -> Int in + // expected-warning@-1 {{variable 'fib' was never mutated; consider changing to 'let' constant}} if (n < 2) { return n } - return fib(n-1)+fib(n-2) // expected-error 2 {{variable used within its own initial value}} + return fib(n-1)+fib(n-2) } } diff --git a/test/expr/expressions_parser_lookup.swift b/test/expr/expressions_parser_lookup.swift new file mode 100644 index 0000000000000..582d59d7d5d12 --- /dev/null +++ b/test/expr/expressions_parser_lookup.swift @@ -0,0 +1,947 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +//===----------------------------------------------------------------------===// +// Tests and samples. +//===----------------------------------------------------------------------===// + +// Comment. With unicode characters: Â¡Ă§Â®Ă¥zÂ¥! + +func markUsed(_: T) {} + +// Various function types. +var func1 : () -> () // No input, no output. +var func2 : (Int) -> Int +var func3 : () -> () -> () // Takes nothing, returns a fn. +var func3a : () -> (() -> ()) // same as func3 +var func6 : (_ fn : (Int,Int) -> Int) -> () // Takes a fn, returns nothing. +var func7 : () -> (Int,Int,Int) // Takes nothing, returns tuple. + +// Top-Level expressions. These are 'main' content. +func1() +_ = 4+7 + +var bind_test1 : () -> () = func1 +var bind_test2 : Int = 4; func1 // expected-error {{expression resolves to an unused variable}} + +(func1, func2) // expected-error {{expression resolves to an unused variable}} + +func basictest() { + // Simple integer variables. + var x : Int + var x2 = 4 // Simple Type inference. + var x3 = 4+x*(4+x2)/97 // Basic Expressions. + + // Declaring a variable Void, aka (), is fine too. + var v : Void + + var x4 : Bool = true + var x5 : Bool = + 4 // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + + //var x6 : Float = 4+5 + + var x7 = 4; 5 // expected-warning {{integer literal is unused}} + + // Test implicit conversion of integer literal to non-Int64 type. + var x8 : Int8 = 4 + x8 = x8 + 1 + _ = x8 + 1 + _ = 0 + x8 + 1.0 + x8 // expected-error{{binary operator '+' cannot be applied to operands of type 'Double' and 'Int8'}} + // expected-note @-1 {{overloads for '+' exist with these partially matching parameter lists:}} + + + var x9 : Int16 = x8 + 1 // expected-error {{cannot convert value of type 'Int8' to specified type 'Int16'}} + + // Various tuple types. + var tuple1 : () + var tuple2 : (Int) + var tuple3 : (Int, Int, ()) + var tuple2a : (a : Int) // expected-error{{cannot create a single-element tuple with an element label}}{{18-22=}} + var tuple3a : (a : Int, b : Int, c : ()) + + var tuple4 = (1, 2) // Tuple literal. + var tuple5 = (1, 2, 3, 4) // Tuple literal. + var tuple6 = (1 2) // expected-error {{expected ',' separator}} {{18-18=,}} + + // Brace expressions. + var brace3 = { + var brace2 = 42 // variable shadowing. + _ = brace2+7 + } + + // Function calls. + var call1 : () = func1() + var call2 = func2(1) + var call3 : () = func3()() + + // Cannot call an integer. + bind_test2() // expected-error {{cannot call value of non-function type 'Int'}}{{13-15=}} +} + +// +func testUnusedLiterals_SR3522() { + 42 // expected-warning {{integer literal is unused}} + 2.71828 // expected-warning {{floating-point literal is unused}} + true // expected-warning {{boolean literal is unused}} + false // expected-warning {{boolean literal is unused}} + "Hello" // expected-warning {{string literal is unused}} + "Hello \(42)" // expected-warning {{string literal is unused}} + #file // expected-warning {{#file literal is unused}} + (#line) // expected-warning {{#line literal is unused}} + #column // expected-warning {{#column literal is unused}} + #function // expected-warning {{#function literal is unused}} + #dsohandle // expected-warning {{#dsohandle literal is unused}} + __FILE__ // expected-error {{__FILE__ has been replaced with #file in Swift 3}} expected-warning {{#file literal is unused}} + __LINE__ // expected-error {{__LINE__ has been replaced with #line in Swift 3}} expected-warning {{#line literal is unused}} + __COLUMN__ // expected-error {{__COLUMN__ has been replaced with #column in Swift 3}} expected-warning {{#column literal is unused}} + __FUNCTION__ // expected-error {{__FUNCTION__ has been replaced with #function in Swift 3}} expected-warning {{#function literal is unused}} + __DSO_HANDLE__ // expected-error {{__DSO_HANDLE__ has been replaced with #dsohandle in Swift 3}} expected-warning {{#dsohandle literal is unused}} + + nil // expected-error {{'nil' requires a contextual type}} + #fileLiteral(resourceName: "what.txt") // expected-error {{could not infer type of file reference literal}} expected-note * {{}} + #imageLiteral(resourceName: "hello.png") // expected-error {{could not infer type of image literal}} expected-note * {{}} + #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) // expected-error {{could not infer type of color literal}} expected-note * {{}} +} + +// Infix operators and attribute lists. +infix operator %% : MinPrecedence +precedencegroup MinPrecedence { + associativity: left + lowerThan: AssignmentPrecedence +} + +func %%(a: Int, b: Int) -> () {} +var infixtest : () = 4 % 2 + 27 %% 123 + + + +// The 'func' keyword gives a nice simplification for function definitions. +func funcdecl1(_ a: Int, _ y: Int) {} +func funcdecl2() { + return funcdecl1(4, 2) +} +func funcdecl3() -> Int { + return 12 +} +func funcdecl4(_ a: ((Int) -> Int), b: Int) {} +func signal(_ sig: Int, f: (Int) -> Void) -> (Int) -> Void {} + +// Doing fun things with named arguments. Basic stuff first. +func funcdecl6(_ a: Int, b: Int) -> Int { return a+b } + +// Can dive into tuples, 'b' is a reference to a whole tuple, c and d are +// fields in one. Cannot dive into functions or through aliases. +func funcdecl7(_ a: Int, b: (c: Int, d: Int), third: (c: Int, d: Int)) -> Int { + _ = a + b.0 + b.c + third.0 + third.1 + b.foo // expected-error {{value of tuple type '(c: Int, d: Int)' has no member 'foo'}} +} + +// Error recovery. +func testfunc2 (_: ((), Int) -> Int) -> Int {} +func makeTuple() -> (String, Int) { return ("foo", 42) } +func errorRecovery() { + testfunc2({ $0 + 1 }) // expected-error {{contextual closure type '((), Int) -> Int' expects 2 arguments, but 1 was used in closure body}} + // expected-error@-1 {{cannot convert value of type '()' to expected argument type 'Int'}} + + enum union1 { + case bar + case baz + } + var a: Int = .hello // expected-error {{type 'Int' has no member 'hello'}} + var b: union1 = .bar // ok + var c: union1 = .xyz // expected-error {{type 'union1' has no member 'xyz'}} + var d: (Int,Int,Int) = (1,2) // expected-error {{'(Int, Int)' is not convertible to '(Int, Int, Int)', tuples have a different number of elements}} + var e: (Int,Int) = (1, 2, 3) // expected-error {{'(Int, Int, Int)' is not convertible to '(Int, Int)', tuples have a different number of elements}} + var f: (Int,Int) = (1, 2, f : 3) // expected-error {{'(Int, Int, f: Int)' is not convertible to '(Int, Int)', tuples have a different number of elements}} + + // CrashTracer: [USER] swift at …mous_namespace::ConstraintGenerator::getTypeForPattern + 698 + var (g1, g2, g3) = (1, 2) // expected-error {{'(Int, Int)' is not convertible to '(Int, Int, _)', tuples have a different number of elements}} + var (h1, h2) = (1, 2, 3) // expected-error {{'(Int, Int, Int)' is not convertible to '(Int, Int)', tuples have a different number of elements}} + var i: (Bool, Bool) = makeTuple() // expected-error {{cannot convert value of type '(String, Int)' to specified type '(Bool, Bool)'}} +} + +func acceptsInt(_ x: Int) {} +acceptsInt(unknown_var) // expected-error {{cannot find 'unknown_var' in scope}} + + + +var test1a: (Int) -> (Int) -> Int = { { $0 } } // expected-error{{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{38-38= _ in}} +var test1b = { 42 } +var test1c = { { 42 } } +var test1d = { { { 42 } } } + +func test2(_ a: Int, b: Int) -> (c: Int) { // expected-error{{cannot create a single-element tuple with an element label}} {{34-37=}} expected-note {{did you mean 'a'?}} expected-note {{did you mean 'b'?}} + _ = a+b + a+b+c // expected-error{{cannot find 'c' in scope}} + return a+b +} + + +func test3(_ arg1: Int, arg2: Int) -> Int { + return 4 +} + +func test4() -> ((_ arg1: Int, _ arg2: Int) -> Int) { + return test3 +} + +func test5() { + let a: (Int, Int) = (1,2) + var + _: ((Int) -> Int, Int) = a // expected-error {{cannot convert value of type '(Int, Int)' to specified type '((Int) -> Int, Int)'}} + + + let c: (a: Int, b: Int) = (1,2) + let _: (b: Int, a: Int) = c // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}} +} + + +// Functions can obviously take and return values. +func w3(_ a: Int) -> Int { return a } +func w4(_: Int) -> Int { return 4 } + + + +func b1() {} + +func foo1(_ a: Int, b: Int) -> Int {} +func foo2(_ a: Int) -> (_ b: Int) -> Int {} +func foo3(_ a: Int = 2, b: Int = 3) {} + +prefix operator ^^ + +prefix func ^^(a: Int) -> Int { + return a + 1 +} + +func test_unary1() { + var x: Int + + x = ^^(^^x) + x = *x // expected-error {{'*' is not a prefix unary operator}} + x = x* // expected-error {{'*' is not a postfix unary operator}} + x = +(-x) + x = + -x // expected-error {{unary operator cannot be separated from its operand}} {{8-9=}} +} +func test_unary2() { + var x: Int + // FIXME: second diagnostic is redundant. + x = &; // expected-error {{expected expression after unary operator}} expected-error {{expected expression in assignment}} +} +func test_unary3() { + var x: Int + // FIXME: second diagnostic is redundant. + x = &, // expected-error {{expected expression after unary operator}} expected-error {{expected expression in assignment}} +} + +func test_as_1() { + var _: Int +} +func test_as_2() { + let x: Int = 1 + x as [] // expected-error {{expected element type}} {{9-9= <#type#>}} +} + +func test_lambda() { + // A simple closure. + var a = { (value: Int) -> () in markUsed(value+1) } + + // A recursive lambda. + // FIXME: This should definitely be accepted. + var fib = { (n: Int) -> Int in + if (n < 2) { + return n + } + + return fib(n-1)+fib(n-2) // expected-error 2 {{variable used within its own initial value}} + } +} + +func test_lambda2() { + { () -> protocol in + // expected-error @-1 {{'protocol<...>' composition syntax has been removed and is not needed here}} {{11-24=Int}} + // expected-error @-2 {{non-protocol, non-class type 'Int' cannot be used within a protocol-constrained type}} + // expected-warning @-3 {{result of call to closure returning 'Any' is unused}} + return 1 + }() +} + +func test_floating_point() { + _ = 0.0 + _ = 100.1 + var _: Float = 0.0 + var _: Double = 0.0 +} + +func test_nonassoc(_ x: Int, y: Int) -> Bool { + // FIXME: the second error and note here should arguably disappear + return x == y == x // expected-error {{adjacent operators are in non-associative precedence group 'ComparisonPrecedence'}} expected-error {{binary operator '==' cannot be applied to operands of type 'Bool' and 'Int'}} + // expected-note@-1 {{overloads for '==' exist with these partially matching parameter lists: (Bool, Bool), (Int, Int)}} +} + +// More realistic examples. + +func fib(_ n: Int) -> Int { + if (n < 2) { + return n + } + + return fib(n-2) + fib(n-1) +} + +//===----------------------------------------------------------------------===// +// Integer Literals +//===----------------------------------------------------------------------===// + +// FIXME: Should warn about integer constants being too large +var + il_a: Bool = 4 // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} +var il_b: Int8 + = 123123 +var il_c: Int8 = 4 // ok + +struct int_test4 : ExpressibleByIntegerLiteral { + typealias IntegerLiteralType = Int + init(integerLiteral value: Int) {} // user type. +} + +var il_g: int_test4 = 4 + + + +// This just barely fits in Int64. +var il_i: Int64 = 18446744073709551615 + +// This constant is too large to fit in an Int64, but it is fine for Int128. +// FIXME: Should warn about the first. +var il_j: Int64 = 18446744073709551616 +// var il_k: Int128 = 18446744073709551616 + +var bin_literal: Int64 = 0b100101 +var hex_literal: Int64 = 0x100101 +var oct_literal: Int64 = 0o100101 + +// verify that we're not using C rules +var oct_literal_test: Int64 = 0123 +assert(oct_literal_test == 123) + +// ensure that we swallow random invalid chars after the first invalid char +var invalid_num_literal: Int64 = 0QWERTY // expected-error{{'Q' is not a valid digit in integer literal}} +var invalid_bin_literal: Int64 = 0bQWERTY // expected-error{{'Q' is not a valid binary digit (0 or 1) in integer literal}} +var invalid_hex_literal: Int64 = 0xQWERTY // expected-error{{'Q' is not a valid hexadecimal digit (0-9, A-F) in integer literal}} +var invalid_oct_literal: Int64 = 0oQWERTY // expected-error{{'Q' is not a valid octal digit (0-7) in integer literal}} +var invalid_exp_literal: Double = 1.0e+QWERTY // expected-error{{'Q' is not a valid digit in floating point exponent}} +var invalid_fp_exp_literal: Double = 0x1p+QWERTY // expected-error{{'Q' is not a valid digit in floating point exponent}} + +// don't emit a partial integer literal if the invalid char is valid for identifiers. +var invalid_num_literal_prefix: Int64 = 0a1234567 // expected-error{{'a' is not a valid digit in integer literal}} +var invalid_num_literal_middle: Int64 = 0123A5678 // expected-error{{'A' is not a valid digit in integer literal}} +var invalid_bin_literal_middle: Int64 = 0b1020101 // expected-error{{'2' is not a valid binary digit (0 or 1) in integer literal}} +var invalid_oct_literal_middle: Int64 = 0o1357864 // expected-error{{'8' is not a valid octal digit (0-7) in integer literal}} +var invalid_hex_literal_middle: Int64 = 0x147ADG0 // expected-error{{'G' is not a valid hexadecimal digit (0-9, A-F) in integer literal}} + +var invalid_hex_literal_exponent_ = 0xffp+12abc // expected-error{{'a' is not a valid digit in floating point exponent}} +var invalid_float_literal_exponent = 12e1abc // expected-error{{'a' is not a valid digit in floating point exponent}} + +// rdar://11088443 +var negative_int32: Int32 = -1 + +// +var tupleelemvar = 1 +markUsed((tupleelemvar, tupleelemvar).1) + +func int_literals() { + // Fits exactly in 64-bits - rdar://11297273 + _ = 1239123123123123 + // Overly large integer. + // FIXME: Should warn about it. + _ = 123912312312312312312 + +} + +// +func tuple_of_rvalues(_ a:Int, b:Int) -> Int { + return (a, b).1 +} + +extension Int { + func testLexingMethodAfterIntLiteral() {} + func _0() {} + // Hex letters + func ffa() {} + // Hex letters + non hex. + func describe() {} + // Hex letters + 'p'. + func eap() {} + // Hex letters + 'p' + non hex. + func fpValue() {} +} + +123.testLexingMethodAfterIntLiteral() +0b101.testLexingMethodAfterIntLiteral() +0o123.testLexingMethodAfterIntLiteral() +0x1FFF.testLexingMethodAfterIntLiteral() + +123._0() +0b101._0() +0o123._0() +0x1FFF._0() + +0x1fff.ffa() +0x1FFF.describe() +0x1FFF.eap() +0x1FFF.fpValue() + +var separator1: Int = 1_ +var separator2: Int = 1_000 +var separator4: Int = 0b1111_0000_ +var separator5: Int = 0b1111_0000 +var separator6: Int = 0o127_777_ +var separator7: Int = 0o127_777 +var separator8: Int = 0x12FF_FFFF +var separator9: Int = 0x12FF_FFFF_ + +//===----------------------------------------------------------------------===// +// Float Literals +//===----------------------------------------------------------------------===// + +var fl_a = 0.0 +var fl_b: Double = 1.0 +var fl_c: Float = 2.0 +// FIXME: crummy diagnostic +var fl_d: Float = 2.0.0 // expected-error {{expected named member of numeric literal}} +var fl_e: Float = 1.0e42 +var fl_f: Float = 1.0e+ // expected-error {{expected a digit in floating point exponent}} +var fl_g: Float = 1.0E+42 +var fl_h: Float = 2e-42 +var vl_i: Float = -.45 // expected-error {{'.45' is not a valid floating point literal; it must be written '0.45'}} {{20-20=0}} +var fl_j: Float = 0x1p0 +var fl_k: Float = 0x1.0p0 +var fl_l: Float = 0x1.0 // expected-error {{hexadecimal floating point literal must end with an exponent}} +var fl_m: Float = 0x1.FFFFFEP-2 +var fl_n: Float = 0x1.fffffep+2 +var fl_o: Float = 0x1.fffffep+ // expected-error {{expected a digit in floating point exponent}} +var fl_p: Float = 0x1p // expected-error {{expected a digit in floating point exponent}} +var fl_q: Float = 0x1p+ // expected-error {{expected a digit in floating point exponent}} +var fl_r: Float = 0x1.0fp // expected-error {{expected a digit in floating point exponent}} +var fl_s: Float = 0x1.0fp+ // expected-error {{expected a digit in floating point exponent}} +var fl_t: Float = 0x1.p // expected-error {{value of type 'Int' has no member 'p'}} +var fl_u: Float = 0x1.p2 // expected-error {{value of type 'Int' has no member 'p2'}} +var fl_v: Float = 0x1.p+ // expected-error {{'+' is not a postfix unary operator}} +var fl_w: Float = 0x1.p+2 // expected-error {{value of type 'Int' has no member 'p'}} + +var if1: Double = 1.0 + 4 // integer literal ok as double. +var if2: Float = 1.0 + 4 // integer literal ok as float. + +var fl_separator1: Double = 1_.2_ +var fl_separator2: Double = 1_000.2_ +var fl_separator3: Double = 1_000.200_001 +var fl_separator4: Double = 1_000.200_001e1_ +var fl_separator5: Double = 1_000.200_001e1_000 +var fl_separator6: Double = 1_000.200_001e1_000 +var fl_separator7: Double = 0x1_.0FFF_p1_ +var fl_separator8: Double = 0x1_0000.0FFF_ABCDp10_001 + +var fl_bad_separator1: Double = 1e_ // expected-error {{'_' is not a valid first character in floating point exponent}} +var fl_bad_separator2: Double = 0x1p_ // expected-error {{'_' is not a valid first character in floating point exponent}} + +//===----------------------------------------------------------------------===// +// String Literals +//===----------------------------------------------------------------------===// + +var st_a = "" +var st_b: String = "" +var st_c = "asdfasd // expected-error {{unterminated string literal}} + +var st_d = " \t\n\r\"\'\\ " // Valid simple escapes +var st_e = " \u{12}\u{0012}\u{00000078} " // Valid unicode escapes +var st_u1 = " \u{1} " +var st_u2 = " \u{123} " +var st_u3 = " \u{1234567} " // expected-error {{invalid unicode scalar}} +var st_u4 = " \q " // expected-error {{invalid escape sequence in literal}} + +var st_u5 = " \u{FFFFFFFF} " // expected-error {{invalid unicode scalar}} +var st_u6 = " \u{D7FF} \u{E000} " // Fencepost UTF-16 surrogate pairs. +var st_u7 = " \u{D800} " // expected-error {{invalid unicode scalar}} +var st_u8 = " \u{DFFF} " // expected-error {{invalid unicode scalar}} +var st_u10 = " \u{0010FFFD} " // Last valid codepoint, 0xFFFE and 0xFFFF are reserved in each plane +var st_u11 = " \u{00110000} " // expected-error {{invalid unicode scalar}} + +func stringliterals(_ d: [String: Int]) { + + // rdar://11385385 + let x = 4 + "Hello \(x+1) world" // expected-warning {{string literal is unused}} + + "Error: \(x+1"; // expected-error {{unterminated string literal}} + + "Error: \(x+1 // expected-error {{unterminated string literal}} + ; // expected-error {{';' statements are not allowed}} + + // rdar://14050788 [DF] String Interpolations can't contain quotes + "test \("nested")" + "test \("\("doubly nested")")" + "test \(d["hi"])" + "test \("quoted-paren )")" + "test \("quoted-paren (")" + "test \("\\")" + "test \("\n")" + "test \("\")" // expected-error {{unterminated string literal}} + + "test \ + // expected-error @-1 {{unterminated string literal}} expected-error @-1 {{invalid escape sequence in literal}} + "test \("\ + // expected-error @-1 {{unterminated string literal}} + "test newline \("something" + + "something else")" + // expected-error @-2 {{unterminated string literal}} expected-error @-1 {{unterminated string literal}} + + // expected-warning @+2 {{variable 'x2' was never used; consider replacing with '_' or removing it}} + // expected-error @+1 {{unterminated string literal}} + var x2 : () = ("hello" + " + ; +} + +func testSingleQuoteStringLiterals() { + _ = 'abc' // expected-error{{single-quoted string literal found, use '"'}}{{7-12="abc"}} + _ = 'abc' + "def" // expected-error{{single-quoted string literal found, use '"'}}{{7-12="abc"}} + + _ = 'ab\nc' // expected-error{{single-quoted string literal found, use '"'}}{{7-14="ab\\nc"}} + + _ = "abc\('def')" // expected-error{{single-quoted string literal found, use '"'}}{{13-18="def"}} + _ = 'ab\("c")' // expected-error{{single-quoted string literal found, use '"'}}{{7-17="ab\\("c")"}} + _ = 'a\('b')c' // expected-error{{single-quoted string literal found, use '"'}}{{7-17="a\\('b')c"}} + // expected-error@-1{{single-quoted string literal found, use '"'}}{{11-14="b"}} + + _ = "abc' // expected-error{{unterminated string literal}} + _ = 'abc" // expected-error{{unterminated string literal}} + _ = "a'c" + + _ = 'ab\'c' // expected-error{{single-quoted string literal found, use '"'}}{{7-14="ab'c"}} + + _ = 'ab"c' // expected-error{{single-quoted string literal found, use '"'}}{{7-13="ab\\"c"}} + _ = 'ab\"c' // expected-error{{single-quoted string literal found, use '"'}}{{7-14="ab\\"c"}} + _ = 'ab\\"c' // expected-error{{single-quoted string literal found, use '"'}}{{7-15="ab\\\\\\"c"}} +} + +// +var s = "" // expected-note {{did you mean 's'?}} +s.append(contentsOf: ["x"]) + +//===----------------------------------------------------------------------===// +// InOut arguments +//===----------------------------------------------------------------------===// + +func takesInt(_ x: Int) {} +func takesExplicitInt(_ x: inout Int) { } + +func testInOut(_ arg: inout Int) { + var x: Int + takesExplicitInt(x) // expected-error{{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{20-20=&}} + takesExplicitInt(&x) + takesInt(&x) // expected-error{{'&' used with non-inout argument of type 'Int'}} + var y = &x //expected-error {{use of extraneous '&'}} + var z = &arg //expected-error {{use of extraneous '&'}} + + takesExplicitInt(5) // expected-error {{cannot pass immutable value as inout argument: literals are not mutable}} +} + +//===----------------------------------------------------------------------===// +// Conversions +//===----------------------------------------------------------------------===// + +var pi_f: Float +var pi_d: Double + +struct SpecialPi {} // Type with no implicit construction. + +var pi_s: SpecialPi + +func getPi() -> Float {} +func getPi() -> Double {} +func getPi() -> SpecialPi {} + +enum Empty { } + +extension Empty { + init(_ f: Float) { } +} + +func conversionTest(_ a: inout Double, b: inout Int) { + var f: Float + var d: Double + a = Double(b) + a = Double(f) + a = Double(d) // no-warning + b = Int(a) + f = Float(b) + + var pi_f1 = Float(pi_f) + var pi_d1 = Double(pi_d) + var pi_s1 = SpecialPi(pi_s) // expected-error {{argument passed to call that takes no arguments}} + + var pi_f2 = Float(getPi()) // expected-error {{ambiguous use of 'init(_:)'}} + var pi_d2 = Double(getPi()) // expected-error {{ambiguous use of 'init(_:)'}} + var pi_s2: SpecialPi = getPi() // no-warning + + var float = Float.self + var pi_f3 = float.init(getPi()) // expected-error {{ambiguous use of 'init(_:)'}} + var pi_f4 = float.init(pi_f) + + var e = Empty(f) // expected-warning {{variable 'e' inferred to have type 'Empty', which is an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}} {{8-8=: Empty}} + var e2 = Empty(d) // expected-error{{cannot convert value of type 'Double' to expected argument type 'Float'}} + var e3 = Empty(Float(d)) // expected-warning {{variable 'e3' inferred to have type 'Empty', which is an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}} {{9-9=: Empty}} +} + +// FIXME(diagnostics): This note is pointing to a synthesized init +struct Rule { // expected-note {{'init(target:dependencies:)' declared here}} + var target: String + var dependencies: String +} + +var ruleVar: Rule +// FIXME(diagnostics): To be able to suggest different candidates here we need to teach the solver how to figure out to which parameter +// does argument belong to in this case. If the `target` was of a different type, we currently suggest to add an argument for `dependencies:` +// which is incorrect. +ruleVar = Rule("a") // expected-error {{missing argument label 'target:' in call}} +// expected-error@-1 {{missing argument for parameter 'dependencies' in call}} + +class C { // expected-note {{did you mean 'C'?}} + var x: C? + init(other: C?) { x = other } + + func method() {} +} + +_ = C(3) // expected-error {{missing argument label 'other:' in call}} +// expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'C?'}} +_ = C(other: 3) // expected-error {{cannot convert value of type 'Int' to expected argument type 'C?'}} + +//===----------------------------------------------------------------------===// +// Unary Operators +//===----------------------------------------------------------------------===// + +func unaryOps(_ i8: inout Int8, i64: inout Int64) { + i8 = ~i8 + i64 += 1 + i8 -= 1 + + Int64(5) += 1 // expected-error{{left side of mutating operator has immutable type 'Int64'}} + + // attempt to modify a 'let' variable with ++ results in typecheck error not being able to apply ++ to Float + let a = i8 // expected-note {{change 'let' to 'var' to make it mutable}} {{3-6=var}} + a += 1 // expected-error {{left side of mutating operator isn't mutable: 'a' is a 'let' constant}} + + var b : Int { get { }} + b += 1 // expected-error {{left side of mutating operator isn't mutable: 'b' is a get-only property}} +} + +//===----------------------------------------------------------------------===// +// Iteration +//===----------------------------------------------------------------------===// + +func..<(x: Double, y: Double) -> Double { + return x + y +} + +func iterators() { + _ = 0..<42 + _ = 0.0..<42.0 +} + +//===----------------------------------------------------------------------===// +// Magic literal expressions +//===----------------------------------------------------------------------===// + +func magic_literals() { + _ = __FILE__ // expected-error {{__FILE__ has been replaced with #file in Swift 3}} + _ = __LINE__ // expected-error {{__LINE__ has been replaced with #line in Swift 3}} + _ = __COLUMN__ // expected-error {{__COLUMN__ has been replaced with #column in Swift 3}} + _ = __DSO_HANDLE__ // expected-error {{__DSO_HANDLE__ has been replaced with #dsohandle in Swift 3}} + + _ = #file + _ = #line + #column + var _: UInt8 = #line + #column +} + +//===----------------------------------------------------------------------===// +// lvalue processing +//===----------------------------------------------------------------------===// + + +infix operator +-+= +@discardableResult +func +-+= (x: inout Int, y: Int) -> Int { return 0} + +func lvalue_processing() { + var i = 0 + i += 1 // obviously ok + + var fn = (+-+=) + + var n = 42 + fn(n, 12) // expected-error {{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{6-6=&}} + fn(&n, 12) // expected-warning {{result of call to function returning 'Int' is unused}} + + n +-+= 12 + + (+-+=)(&n, 12) // ok. + (+-+=)(n, 12) // expected-error {{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{10-10=&}} +} + +struct Foo { + func method() {} + mutating func mutatingMethod() {} +} + +func test() { + var x = Foo() + let y = Foo() + + // rdar://15708430 + (&x).method() // expected-error {{use of extraneous '&'}} + (&x).mutatingMethod() // expected-error {{use of extraneous '&'}} +} + + +// Unused results. +func unusedExpressionResults() { + // Unused l-value + _ // expected-error{{'_' can only appear in a pattern or on the left side of an assignment}} + + // Conditional Optional binding hides compiler error + let optionalc:C? = nil + optionalc?.method() // ok + optionalc?.method // expected-error {{expression resolves to an unused function}} +} + + + + +//===----------------------------------------------------------------------===// +// Collection Literals +//===----------------------------------------------------------------------===// + +func arrayLiterals() { + let _ = [1,2,3] + let _ : [Int] = [] + let _ = [] // expected-error {{empty collection literal requires an explicit type}} +} + +func dictionaryLiterals() { + let _ = [1 : "foo",2 : "bar",3 : "baz"] + let _: Dictionary = [:] + let _ = [:] // expected-error {{empty collection literal requires an explicit type}} +} + +func invalidDictionaryLiteral() { + // FIXME: lots of unnecessary diagnostics. + + var a = [1: ; // expected-error {{expected value in dictionary literal}} + var b = [1: ;] // expected-error {{expected value in dictionary literal}} + var c = [1: "one" ;] // expected-error {{expected key expression in dictionary literal}} expected-error {{expected ',' separator}} {{20-20=,}} + var d = [1: "one", ;] // expected-error {{expected key expression in dictionary literal}} + var e = [1: "one", 2] // expected-error {{expected ':' in dictionary literal}} + var f = [1: "one", 2 ;] // expected-error {{expected ':' in dictionary literal}} + var g = [1: "one", 2: ;] // expected-error {{expected value in dictionary literal}} +} + + +[4].joined(separator: [1]) +// expected-error@-1 {{cannot convert value of type 'Int' to expected element type 'String'}} +// expected-error@-2 {{cannot convert value of type '[Int]' to expected argument type 'String'}} + +[4].joined(separator: [[[1]]]) +// expected-error@-1 {{cannot convert value of type 'Int' to expected element type 'String'}} +// expected-error@-2 {{cannot convert value of type '[[[Int]]]' to expected argument type 'String'}} + +//===----------------------------------------------------------------------===// +// nil/metatype comparisons +//===----------------------------------------------------------------------===// +_ = Int.self == nil // expected-warning {{comparing non-optional value of type 'Any.Type' to 'nil' always returns false}} +_ = nil == Int.self // expected-warning {{comparing non-optional value of type 'Any.Type' to 'nil' always returns false}} +_ = Int.self != nil // expected-warning {{comparing non-optional value of type 'Any.Type' to 'nil' always returns true}} +_ = nil != Int.self // expected-warning {{comparing non-optional value of type 'Any.Type' to 'nil' always returns true}} + +// Disallow postfix ? when not chaining +func testOptionalChaining(_ a : Int?, b : Int!, c : Int??) { + _ = a? // expected-error {{optional chain has no effect, expression already produces 'Int?'}} {{8-9=}} + _ = a?.customMirror + + _ = b? // expected-error {{optional chain has no effect, expression already produces 'Int?'}} + _ = b?.customMirror + + var _: Int? = c? // expected-error {{'?' must be followed by a call, member lookup, or subscript}} +} + + +// Nil Coalescing operator (??) should have a higher precedence +func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange?) { + // ?? should have higher precedence than logical operators like || and comparisons. + if cond || (a ?? 42 > 0) {} // Ok. + if (cond || a) ?? 42 > 0 {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}} + // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + // expected-error@-2 {{cannot convert value of type 'Bool' to expected argument type 'Int'}} + if (cond || a) ?? (42 > 0) {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}} + + if cond || a ?? 42 > 0 {} // Parses as the first one, not the others. + + + // ?? should have lower precedence than range and arithmetic operators. + let r1 = r ?? (0...42) // ok + let r2 = (r ?? 0)...42 // not ok: expected-error {{binary operator '??' cannot be applied to operands of type 'ClosedRange?' and 'Int'}} + let r3 = r ?? 0...42 // parses as the first one, not the second. + + + // [Type checker] Diagnose unsavory optional injections + // Accidental optional injection for ??. + let i = 42 + _ = i ?? 17 // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'Int', so the right side is never used}} {{9-15=}} +} + +// Parsing of as and ?? regressed +func testOptionalTypeParsing(_ a : AnyObject) -> String { + return a as? String ?? "default name string here" +} + +func testParenExprInTheWay() { + let x = 42 + + if x & 4.0 {} // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} + // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + if (x & 4.0) {} // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} + // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + if !(x & 4.0) {} // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} + // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + + if x & x {} // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} +} + +// Mixed method/property overload groups can cause a crash during constraint optimization +public struct TestPropMethodOverloadGroup { + public typealias Hello = String + public let apply:(Hello) -> Int + public func apply(_ input:Hello) -> Int { + return apply(input) + } +} + + +// Passing ternary operator expression as inout crashes Swift compiler +func inoutTests(_ arr: inout Int) { + var x = 1, y = 2 + (true ? &x : &y) // expected-error {{use of extraneous '&'}} + let a = (true ? &x : &y) // expected-error {{use of extraneous '&'}} + + inoutTests(true ? &x : &y) // expected-error {{use of extraneous '&'}} + + &_ // expected-error {{use of extraneous '&'}} + + inoutTests((&x, 24).0) // expected-error {{use of extraneous '&'}} + + inoutTests((&x)) // expected-error {{use of extraneous '&'}} + inoutTests(&x) + + // inout not rejected as operand to assignment operator + &x += y // expected-error {{use of extraneous '&'}} + + // + func takeAny(_ x: Any) {} + takeAny(&x) // expected-error{{'&' used with non-inout argument of type 'Any'}} + func takeManyAny(_ x: Any...) {} + takeManyAny(&x) // expected-error{{'&' used with non-inout argument of type 'Any'}} + takeManyAny(1, &x) // expected-error{{'&' used with non-inout argument of type 'Any'}} + func takeIntAndAny(_ x: Int, _ y: Any) {} + takeIntAndAny(1, &x) // expected-error{{'&' used with non-inout argument of type 'Any'}} +} + + +// Compiler crash in default argument & inout expr +var g20802757 = 2 +func r20802757(_ z: inout Int = &g20802757) { // expected-error {{cannot provide default value to inout parameter 'z'}} + // expected-error@-1 {{use of extraneous '&'}} + print(z) +} + +_ = _.foo // expected-error {{'_' can only appear in a pattern or on the left side of an assignment}} + +// wrong arg list crashing sourcekit +func r22211854() { + func f(_ x: Bool, _ y: Int, _ z: String = "") {} // expected-note 2 {{'f' declared here}} + func g(_ x: T, _ y: T, _ z: String = "") {} // expected-note 2 {{'g' declared here}} + + f(false) // expected-error{{missing argument for parameter #2 in call}} + g(1) // expected-error{{missing argument for parameter #2 in call}} + func h() -> Int { return 1 } + f(h() == 1) // expected-error{{missing argument for parameter #2 in call}} + g(h() == 1) // expected-error{{missing argument for parameter #2 in call}} +} + +// Compiler crash on invoking function with labeled defaulted param with non-labeled argument +func r22348394() { + func f(x: Int = 0) { } + f(Int(3)) // expected-error{{missing argument label 'x:' in call}} +} + +// Compiler crashes in Assertion failed: ((AllowOverwrite || !E->hasLValueAccessKind()) && "l-value access kind has already been set"), function visit +protocol Proto { var y: String? { get } } +func r23185177(_ x: Proto?) -> [String] { + return x?.y // expected-error{{cannot convert return expression of type 'String?' to return type '[String]'}} +} + +// Miscompile: wrong argument parsing when calling a function in swift2.0 +func r22913570() { + func f(_ from: Int = 0, to: Int) {} // expected-note {{'f(_:to:)' declared here}} + f(1 + 1) // expected-error{{missing argument for parameter 'to' in call}} +} + +// SR-628 mixing lvalues and rvalues in tuple expression +do { + var x = 0 + var y = 1 + let _ = (x, x + 1).0 + let _ = (x, 3).1 + (x,y) = (2,3) + (x,4) = (1,2) // expected-error {{cannot assign to value: literals are not mutable}} + (x,y).1 = 7 // expected-error {{cannot assign to immutable expression of type 'Int'}} + x = (x,(3,y)).1.1 +} + +// SR-3439 subscript with pound exprssions. +Sr3439: do { + class B { + init() {} + subscript(x: Int) -> Int { return x } + subscript(x: String) -> String { return x } + + func foo() { + _ = self[#line] // Ok. + } + } + class C : B { + func bar() { + _ = super[#file] // Ok. + } + } + + let obj = C(); + _ = obj[#column] // Ok. +} + +// rdar://problem/23672697 - No way to express literal integers larger than Int without using type ascription +let _: Int64 = 0xFFF_FFFF_FFFF_FFFF +let _: Int64 = Int64(0xFFF_FFFF_FFFF_FFFF) +let _: Int64 = 0xFFF_FFFF_FFFF_FFFF as Int64 +let _ = Int64(0xFFF_FFFF_FFFF_FFFF) +let _ = 0xFFF_FFFF_FFFF_FFFF as Int64 + +// rdar://problem/20289969 - string interpolation with comment containing ')' or '"' +let _ = "foo \(42 /* ) " ) */)" +let _ = "foo \(foo // ) " // expected-error {{unterminated string literal}} +let _ = "foo \(42 /* + * multiline comment + */)end" +// expected-error @-3 {{unterminated string literal}} +// expected-error @-2 {{expected expression}} +// expected-error @-3 {{unterminated string literal}} diff --git a/test/stmt/statements.swift b/test/stmt/statements.swift index 93de7f6efabc8..2c1e4e5085bdd 100644 --- a/test/stmt/statements.swift +++ b/test/stmt/statements.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -disable-parser-lookup /* block comments */ /* /* nested too */ */ @@ -501,8 +501,9 @@ func test_guard(_ x : Int, y : Int??, cond : Bool) { guard let e, cond else {} // expected-error {{variable binding in a condition requires an initializer}} guard case let f? : Int?, cond else {} // expected-error {{variable binding in a condition requires an initializer}} + // FIXME: Bring back the tailored diagnostic guard let g = y else { - markUsed(g) // expected-error {{variable declared in 'guard' condition is not usable in its body}} + markUsed(g) // expected-error {{cannot find 'g' in scope}} } guard let h = y, cond {} // expected-error {{expected 'else' after 'guard' condition}} {{25-25=else }} @@ -512,8 +513,9 @@ func test_guard(_ x : Int, y : Int??, cond : Bool) { // SR-7567 guard let outer = y else { + // FIXME: Bring back the tailored diagnostic guard true else { - print(outer) // expected-error {{variable declared in 'guard' condition is not usable in its body}} + print(outer) // expected-error {{cannot find 'outer' in scope}} } } } diff --git a/test/stmt/statements_parser_lookup.swift b/test/stmt/statements_parser_lookup.swift new file mode 100644 index 0000000000000..caeb47ef5097a --- /dev/null +++ b/test/stmt/statements_parser_lookup.swift @@ -0,0 +1,723 @@ +// RUN: %target-typecheck-verify-swift -enable-parser-lookup + +/* block comments */ +/* /* nested too */ */ + +func markUsed(_ t: T) {} + +func f1(_ a: Int, _ y: Int) {} +func f2() {} +func f3() -> Int {} + +func invalid_semi() { + ; // expected-error {{';' statements are not allowed}} {{3-5=}} +} + +func nested1(_ x: Int) { + var y : Int + // expected-warning@-1 {{variable 'y' was never mutated; consider changing to 'let' constant}} + + func nested2(_ z: Int) -> Int { + return x+y+z + } + + _ = nested2(1) +} + +func funcdecl5(_ a: Int, y: Int) { + var x : Int + + // a few statements + if (x != 0) { + if (x != 0 || f3() != 0) { + // while with and without a space after it. + while(true) { 4; 2; 1 } // expected-warning 3 {{integer literal is unused}} + while (true) { 4; 2; 1 } // expected-warning 3 {{integer literal is unused}} + } + } + + // Assignment statement. + x = y + (x) = y + + 1 = x // expected-error {{cannot assign to value: literals are not mutable}} + (1) = x // expected-error {{cannot assign to value: literals are not mutable}} + "string" = "other" // expected-error {{cannot assign to value: literals are not mutable}} + [1, 1, 1, 1] = [1, 1] // expected-error {{cannot assign to immutable expression of type '[Int]}} + 1.0 = x // expected-error {{cannot assign to value: literals are not mutable}} + nil = 1 // expected-error {{cannot assign to value: literals are not mutable}} + + (x:1).x = 1 // expected-error {{cannot assign to immutable expression of type 'Int'}} + var tup : (x:Int, y:Int) + tup.x = 1 + _ = tup + + let B : Bool + + // if/then/else. + if (B) { + } else if (y == 2) { + } + + // This diagnostic is terrible - rdar://12939553 + if x {} // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + + if true { + if (B) { + } else { + } + } + + if (B) { + f1(1,2) + } else { + f2() + } + + if (B) { + if (B) { + f1(1,2) + } else { + f2() + } + } else { + f2() + } + + // while statement. + while (B) { + } + + // It's okay to leave out the spaces in these. + while(B) {} + if(B) {} +} + +struct infloopbool { + var boolValue: infloopbool { + return self + } +} + +func infloopbooltest() { + if (infloopbool()) {} // expected-error {{cannot convert value of type 'infloopbool' to expected condition type 'Bool'}} +} + +// test "builder" API style +extension Int { + static func builder() -> Int { } + var builderProp: Int { return 0 } + func builder2() {} +} +Int + .builder() + .builderProp + .builder2() + +struct SomeGeneric { + static func builder() -> SomeGeneric { } + var builderProp: SomeGeneric { return .builder() } + func builder2() {} +} +SomeGeneric + .builder() + .builderProp + .builder2() + + +break // expected-error {{'break' is only allowed inside a loop, if, do, or switch}} +continue // expected-error {{'continue' is only allowed inside a loop}} +while true { + func f() { + break // expected-error {{'break' is only allowed inside a loop}} + continue // expected-error {{'continue' is only allowed inside a loop}} + } + + // Labeled if + MyIf: if 1 != 2 { + break MyIf + continue MyIf // expected-error {{'continue' cannot be used with if statements}} + break // break the while + continue // continue the while. + } +} + +// Labeled if +MyOtherIf: if 1 != 2 { + break MyOtherIf + continue MyOtherIf // expected-error {{'continue' cannot be used with if statements}} + break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if}} + continue // expected-error {{'continue' is only allowed inside a loop}} +} + +do { + break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do}} +} + +func tuple_assign() { + var a,b,c,d : Int + (a,b) = (1,2) + func f() -> (Int,Int) { return (1,2) } + ((a,b), (c,d)) = (f(), f()) + _ = (a,b,c,d) +} + +func missing_semicolons() { + var w = 321 + func g() {} + g() w += 1 // expected-error{{consecutive statements}} {{6-6=;}} + var z = w"hello" // expected-error{{consecutive statements}} {{12-12=;}} expected-warning {{string literal is unused}} + // expected-warning@-1 {{initialization of variable 'z' was never used; consider replacing with assignment to '_' or removing it}} + class C {}class C2 {} // expected-error{{consecutive statements}} {{14-14=;}} + struct S {}struct S2 {} // expected-error{{consecutive statements}} {{14-14=;}} + func j() {}func k() {} // expected-error{{consecutive statements}} {{14-14=;}} +} + +//===--- Return statement. + +return 42 // expected-error {{return invalid outside of a func}} + +return // expected-error {{return invalid outside of a func}} + +func NonVoidReturn1() -> Int { + _ = 0 + return // expected-error {{non-void function should return a value}} +} + +func NonVoidReturn2() -> Int { + return + // expected-error {{unary operator cannot be separated from its operand}} {{11-1=}} expected-error {{expected expression in 'return' statement}} +} + +func VoidReturn1() { + if true { return } + // Semicolon should be accepted -- rdar://11344875 + return; // no-error +} + +func VoidReturn2() { + return () // no-error +} + +func VoidReturn3() { + return VoidReturn2() // no-error +} + +//===--- If statement. + +func IfStmt1() { + if 1 > 0 // expected-error {{expected '{' after 'if' condition}} + _ = 42 +} + +func IfStmt2() { + if 1 > 0 { + } else // expected-error {{expected '{' or 'if' after 'else'}} + _ = 42 +} +func IfStmt3() { + if 1 > 0 { + } else 1 < 0 { // expected-error {{expected '{' or 'if' after 'else'; did you mean to write 'if'?}} {{9-9= if}} + _ = 42 + } else { + } +} + +//===--- While statement. + +func WhileStmt1() { + while 1 > 0 // expected-error {{expected '{' after 'while' condition}} + _ = 42 +} + +//===-- Do statement. +func DoStmt() { + // This is just a 'do' statement now. + do { + } +} + + +func DoWhileStmt1() { + do { // expected-error {{'do-while' statement is not allowed}} + // expected-note@-1 {{did you mean 'repeat-while' statement?}} {{3-5=repeat}} + // expected-note@-2 {{did you mean separate 'do' and 'while' statements?}} {{5-5=\n}} + } while true +} + +func DoWhileStmt2() { + do { + + } + while true { + + } +} + +func LabeledDoStmt() { + LABEL: { // expected-error {{labeled block needs 'do'}} {{10-10=do }} + } +} + +//===--- Repeat-while statement. + +func RepeatWhileStmt1() { + repeat {} while true + + repeat {} while false + + repeat { break } while true + repeat { continue } while true +} + +func RepeatWhileStmt2() { + repeat // expected-error {{expected '{' after 'repeat'}} expected-error {{expected 'while' after body of 'repeat' statement}} +} + +func RepeatWhileStmt4() { + repeat { + } while + // expected-error {{unary operator cannot be separated from its operand}} {{12-1=}} expected-error {{expected expression in 'repeat-while' condition}} +} + +func brokenSwitch(_ x: Int) -> Int { + switch x { + case .Blah(var rep): // expected-error{{type 'Int' has no member 'Blah'}} + return rep + } +} + +func switchWithVarsNotMatchingTypes(_ x: Int, y: Int, z: String) -> Int { + switch (x,y,z) { + case (let a, 0, _), (0, let a, _): // OK + return a + case (let a, _, _), (_, _, let a): // expected-error {{pattern variable bound to type 'String', expected type 'Int'}} + // expected-warning@-1 {{case is already handled by previous patterns; consider removing it}} + return a + } +} + +func breakContinue(_ x : Int) -> Int { + +Outer: + for _ in 0...1000 { + + Switch: // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}} + switch x { + case 42: break Outer + case 97: continue Outer + case 102: break Switch + case 13: continue + case 139: break // 'break' should be able to break out of switch statements + } + } + + // shadowing loop labels should be an error +Loop: // expected-note {{previously declared here}} + for _ in 0...2 { + Loop: // expected-error {{label 'Loop' cannot be reused on an inner statement}} + for _ in 0...2 { + } + } + + + // Following a 'break' statement by another statement on a new line result in an error/fit-it + switch 5 { + case 5: + markUsed("before the break") + break + markUsed("after the break") // 'markUsed' is not a label for the break. + default: + markUsed("") + } + + let x : Int? = 42 + + // Should be able to pattern match 'nil' against optionals + switch x { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.some(_)'}} + case .some(42): break + case nil: break + + } + +} + + +enum MyEnumWithCaseLabels { + case Case(one: String, two: Int) +} + +func testMyEnumWithCaseLabels(_ a : MyEnumWithCaseLabels) { + // Enum case labels are ignored in "case let" statements + switch a { + case let .Case(one: _, two: x): break // ok + case let .Case(xxx: _, two: x): break // expected-error {{tuple pattern element label 'xxx' must be 'one'}} + // TODO: In principle, reordering like this could be supported. + case let .Case(two: _, one: x): break // expected-error {{tuple pattern element label}} + } +} + + + +// "defer" + +func test_defer(_ a : Int) { + + defer { VoidReturn1() } + defer { breakContinue(1)+42 } // expected-warning {{result of operator '+' is unused}} + + // Ok: + defer { while false { break } } + + // Not ok. + while false { defer { break } } // expected-error {{'break' cannot transfer control out of a defer statement}} + // expected-warning@-1 {{'defer' statement at end of scope always executes immediately}}{{17-22=do}} + defer { return } // expected-error {{'return' cannot transfer control out of a defer statement}} + // expected-warning@-1 {{'defer' statement at end of scope always executes immediately}}{{3-8=do}} +} + +class SomeTestClass { + var x = 42 + + func method() { + defer { x = 97 } // self. not required here! + // expected-warning@-1 {{'defer' statement at end of scope always executes immediately}}{{5-10=do}} + } +} + +enum DeferThrowError: Error { + case someError +} + +func throwInDefer() { + defer { throw DeferThrowError.someError } // expected-error {{errors cannot be thrown out of a defer body}} + print("Foo") +} + +func throwInDeferOK1() { + defer { + do { + throw DeferThrowError.someError + } catch {} + } + print("Bar") +} + +func throwInDeferOK2() throws { + defer { + do { + throw DeferThrowError.someError + } catch {} + } + print("Bar") +} + +func throwingFuncInDefer1() throws { + defer { try throwingFunctionCalledInDefer() } // expected-error {{errors cannot be thrown out of a defer body}} + print("Bar") +} + +func throwingFuncInDefer1a() throws { + defer { + do { + try throwingFunctionCalledInDefer() + } catch {} + } + print("Bar") +} + +func throwingFuncInDefer2() throws { + defer { throwingFunctionCalledInDefer() } // expected-error {{errors cannot be thrown out of a defer body}} + print("Bar") +} + +func throwingFuncInDefer2a() throws { + defer { + do { + throwingFunctionCalledInDefer() + // expected-error@-1 {{call can throw but is not marked with 'try'}} + // expected-note@-2 {{did you mean to use 'try'?}} + // expected-note@-3 {{did you mean to handle error as optional value?}} + // expected-note@-4 {{did you mean to disable error propagation?}} + } catch {} + } + print("Bar") +} + +func throwingFuncInDefer3() { + defer { try throwingFunctionCalledInDefer() } // expected-error {{errors cannot be thrown out of a defer body}} + print("Bar") +} + +func throwingFuncInDefer3a() { + defer { + do { + try throwingFunctionCalledInDefer() + } catch {} + } + print("Bar") +} + +func throwingFuncInDefer4() { + defer { throwingFunctionCalledInDefer() } // expected-error {{errors cannot be thrown out of a defer body}} + print("Bar") +} + +func throwingFuncInDefer4a() { + defer { + do { + throwingFunctionCalledInDefer() + // expected-error@-1 {{call can throw but is not marked with 'try'}} + // expected-note@-2 {{did you mean to use 'try'?}} + // expected-note@-3 {{did you mean to handle error as optional value?}} + // expected-note@-4 {{did you mean to disable error propagation?}} + } catch {} + } + print("Bar") +} + +func throwingFunctionCalledInDefer() throws { + throw DeferThrowError.someError +} + +class SomeDerivedClass: SomeTestClass { + override init() { + defer { + super.init() // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}} + } + } +} + +func test_guard(_ x : Int, y : Int??, cond : Bool) { + + // These are all ok. + guard let a = y else {} + markUsed(a) + guard let b = y, cond else {} + guard case let c = x, cond else {} + guard case let Optional.some(d) = y else {} + guard x != 4, case _ = x else { } + + + guard let e, cond else {} // expected-error {{variable binding in a condition requires an initializer}} + guard case let f? : Int?, cond else {} // expected-error {{variable binding in a condition requires an initializer}} + + guard let g = y else { + markUsed(g) // expected-error {{variable declared in 'guard' condition is not usable in its body}} + } + + guard let h = y, cond {} // expected-error {{expected 'else' after 'guard' condition}} {{25-25=else }} + + + guard case _ = x else {} // expected-warning {{'guard' condition is always true, body is unreachable}} + + // SR-7567 + guard let outer = y else { + guard true else { + print(outer) // expected-error {{variable declared in 'guard' condition is not usable in its body}} + } + } +} + +func test_is_as_patterns() { + switch 4 { + case is Int: break // expected-warning {{'is' test is always true}} + case _ as Int: break // expected-warning {{'as' test is always true}} + // expected-warning@-1 {{case is already handled by previous patterns; consider removing it}} + case _: break // expected-warning {{case is already handled by previous patterns; consider removing it}} + } +} + +// Fuzzing SourceKit: crash in Parser::parseStmtForEach(...) +func matching_pattern_recursion() { + switch 42 { + case { // expected-error {{expression pattern of type '() -> ()' cannot match values of type 'Int'}} + for i in zs { + } + }: break + } +} + +// Swift's break operator in switch should be indicated in errors +func r18776073(_ a : Int?) { + switch a { + case nil: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{14-14= break}} + case _?: break + } +} + +// unhelpful error message from "throw nil" +func testThrowNil() throws { + throw nil // expected-error {{cannot infer concrete Error for thrown 'nil' value}} +} + + +// rdar://problem/23684220 +// Even if the condition fails to typecheck, save it in the AST anyway; the old +// condition may have contained a SequenceExpr. +func r23684220(_ b: Any) { + if let _ = b ?? b {} // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'Any', so the right side is never used}} + // expected-error@-1 {{initializer for conditional binding must have Optional type, not 'Any'}} +} + + +// QoI: try/catch (instead of do/catch) creates silly diagnostics +func f21080671() { + try { // expected-error {{the 'do' keyword is used to specify a 'catch' region}} {{3-6=do}} + } catch { } + + + try { // expected-error {{the 'do' keyword is used to specify a 'catch' region}} {{3-6=do}} + f21080671() + } catch let x as Int { + } catch { + } +} + +// QoI: Using "&& #available" should fixit to comma +// https://twitter.com/radexp/status/694561060230184960 +func f(_ x : Int, y : Int) { + if x == y && #available(iOS 52, *) {} // expected-error {{expected ',' joining parts of a multi-clause condition}} {{12-15=,}} + if #available(iOS 52, *) && x == y {} // expected-error {{expected ',' joining parts of a multi-clause condition}} {{27-30=,}} + + // https://twitter.com/radexp/status/694790631881883648 + if x == y && let _ = Optional(y) {} // expected-error {{expected ',' joining parts of a multi-clause condition}} {{12-15=,}} + if x == y&&let _ = Optional(y) {} // expected-error {{expected ',' joining parts of a multi-clause condition}} {{12-14=,}} +} + + + +// QoI: Warn about cases where switch statement "ignores" where clause +enum Type { + case Foo + case Bar +} +func r25178926(_ a : Type) { + switch a { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.Bar'}} + case .Foo, .Bar where 1 != 100: + // expected-warning @-1 {{'where' only applies to the second pattern match in this case}} + // expected-note @-2 {{disambiguate by adding a line break between them if this is desired}} {{14-14=\n }} + // expected-note @-3 {{duplicate the 'where' on both patterns to check both patterns}} {{12-12= where 1 != 100}} + break + } + + switch a { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.Bar'}} + case .Foo: break + case .Bar where 1 != 100: break + } + + switch a { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.Bar'}} + case .Foo, // no warn + .Bar where 1 != 100: + break + } + + switch a { // expected-error {{switch must be exhaustive}} + // expected-note@-1 {{missing case: '.Foo'}} + // expected-note@-2 {{missing case: '.Bar'}} + case .Foo where 1 != 100, .Bar where 1 != 100: + break + } +} + +do { + guard 1 == 2 else { + break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do}} + } +} + +func fn(a: Int) { + guard a < 1 else { + break // expected-error {{'break' is only allowed inside a loop, if, do, or switch}} + } +} + +func fn(x: Int) { + if x >= 0 { + guard x < 1 else { + guard x < 2 else { + break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do}} + } + return + } + } +} + +func bad_if() { + if 1 {} // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + if (x: false) {} // expected-error {{cannot convert value of type '(x: Bool)' to expected condition type 'Bool'}} + if (x: 1) {} // expected-error {{cannot convert value of type '(x: Int)' to expected condition type 'Bool'}} + if nil {} // expected-error {{'nil' is not compatible with expected condition type 'Bool'}} +} + +// Typo correction for loop labels +for _ in [1] { + break outerloop // expected-error {{cannot find label 'outerloop' in scope}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope}} +} +while true { + break outerloop // expected-error {{cannot find label 'outerloop' in scope}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope}} +} +repeat { + break outerloop // expected-error {{cannot find label 'outerloop' in scope}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope}} +} while true + +outerLoop: for _ in [1] { // expected-note {{'outerLoop' declared here}} + break outerloop // expected-error {{cannot find label 'outerloop' in scope; did you mean 'outerLoop'?}} {{9-18=outerLoop}} +} +outerLoop: for _ in [1] { // expected-note {{'outerLoop' declared here}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope; did you mean 'outerLoop'?}} {{12-21=outerLoop}} +} +outerLoop: while true { // expected-note {{'outerLoop' declared here}} + break outerloop // expected-error {{cannot find label 'outerloop' in scope; did you mean 'outerLoop'?}} {{9-18=outerLoop}} +} +outerLoop: while true { // expected-note {{'outerLoop' declared here}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope; did you mean 'outerLoop'?}} {{12-21=outerLoop}} +} +outerLoop: repeat { // expected-note {{'outerLoop' declared here}} + break outerloop // expected-error {{cannot find label 'outerloop' in scope; did you mean 'outerLoop'?}} {{9-18=outerLoop}} +} while true +outerLoop: repeat { // expected-note {{'outerLoop' declared here}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope; did you mean 'outerLoop'?}} {{12-21=outerLoop}} +} while true + +outerLoop1: for _ in [1] { // expected-note {{did you mean 'outerLoop1'?}} {{11-20=outerLoop1}} + outerLoop2: for _ in [1] { // expected-note {{did you mean 'outerLoop2'?}} {{11-20=outerLoop2}} + break outerloop // expected-error {{cannot find label 'outerloop' in scope}} + } +} +outerLoop1: for _ in [1] { // expected-note {{did you mean 'outerLoop1'?}} {{14-23=outerLoop1}} + outerLoop2: for _ in [1] { // expected-note {{did you mean 'outerLoop2'?}} {{14-23=outerLoop2}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope}} + } +} +outerLoop1: while true { // expected-note {{did you mean 'outerLoop1'?}} {{11-20=outerLoop1}} + outerLoop2: while true { // expected-note {{did you mean 'outerLoop2'?}} {{11-20=outerLoop2}} + break outerloop // expected-error {{cannot find label 'outerloop' in scope}} + } +} +outerLoop1: while true { // expected-note {{did you mean 'outerLoop1'?}} {{14-23=outerLoop1}} + outerLoop2: while true { // expected-note {{did you mean 'outerLoop2'?}} {{14-23=outerLoop2}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope}} + } +} +outerLoop1: repeat { // expected-note {{did you mean 'outerLoop1'?}} {{11-20=outerLoop1}} + outerLoop2: repeat { // expected-note {{did you mean 'outerLoop2'?}} {{11-20=outerLoop2}} + break outerloop // expected-error {{cannot find label 'outerloop' in scope}} + } while true +} while true +outerLoop1: repeat { // expected-note {{did you mean 'outerLoop1'?}} {{14-23=outerLoop1}} + outerLoop2: repeat { // expected-note {{did you mean 'outerLoop2'?}} {{14-23=outerLoop2}} + continue outerloop // expected-error {{cannot find label 'outerloop' in scope}} + } while true +} while true + +// Errors in case syntax +class +case, // expected-error {{expected identifier in enum 'case' declaration}} expected-error {{expected identifier after comma in enum 'case' declaration}} expected-error {{enum 'case' is not allowed outside of an enum}} +case // expected-error {{expected identifier in enum 'case' declaration}} expected-error {{enum 'case' is not allowed outside of an enum}} +// NOTE: EOF is important here to properly test a code path that used to crash the parser diff --git a/utils/build-script-impl b/utils/build-script-impl index 2bb99c886a669..49e339d9715b6 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -2012,7 +2012,7 @@ for host in "${ALL_HOSTS[@]}"; do fi # Construct dotest arguments. We use semicolons so CMake interprets this as a list. - DOTEST_ARGS="--build-dir;${lldb_build_dir}/lldb-test-build.noindex;${LLDB_TEST_CATEGORIES};-t" + DOTEST_ARGS="--build-dir;${lldb_build_dir}/lldb-test-build.noindex;${LLDB_TEST_CATEGORIES}" # Only set the extra arguments if they're not empty. if [[ -n "${DOTEST_EXTRA}" ]]; then diff --git a/utils/build-windows.bat b/utils/build-windows.bat index 90462413e1ad1..39360fbc09a2f 100644 --- a/utils/build-windows.bat +++ b/utils/build-windows.bat @@ -201,6 +201,7 @@ cmake^ -DCMAKE_CXX_FLAGS:STRING="/GS- /Oy"^ -DCMAKE_EXE_LINKER_FLAGS:STRING=/INCREMENTAL:NO^ -DCMAKE_SHARED_LINKER_FLAGS:STRING=/INCREMENTAL:NO^ + -DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=YES^ -S "%source_root%\llvm-project\llvm" %exitOnError% cmake --build "%build_root%\llvm" %exitOnError% diff --git a/validation-test/compiler_crashers_2_fixed/0180-rdar45557325-parser-lookup.swift b/validation-test/compiler_crashers_2_fixed/0180-rdar45557325-parser-lookup.swift new file mode 100644 index 0000000000000..93e2285cf083c --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/0180-rdar45557325-parser-lookup.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -verify -enable-parser-lookup + +// REQUIRES: objc_interop + +import Foundation + +class MyClass: NSObject { + func f() { + let url = URL(url) // expected-error{{variable used within its own initial value}} + } +} diff --git a/validation-test/compiler_crashers_2_fixed/0180-rdar45557325.swift b/validation-test/compiler_crashers_2_fixed/0180-rdar45557325.swift index 0276ac8627fb5..af0f3b45e45d2 100644 --- a/validation-test/compiler_crashers_2_fixed/0180-rdar45557325.swift +++ b/validation-test/compiler_crashers_2_fixed/0180-rdar45557325.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -verify +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -verify -disable-parser-lookup // REQUIRES: objc_interop @@ -6,6 +6,7 @@ import Foundation class MyClass: NSObject { func f() { - let url = URL(url) // expected-error{{variable used within its own initial value}} + let url = URL(url) // expected-error{{use of local variable 'url' before its declaration}} + // expected-note@-1 {{'url' declared here}} } }