diff --git a/docs/SIL.rst b/docs/SIL.rst index f114cb48047bd..e9ce6ea2b5ab8 100644 --- a/docs/SIL.rst +++ b/docs/SIL.rst @@ -5894,6 +5894,25 @@ This instruction is assumed to forward a fixed ownership (set upon its construction) and lowers to 'unchecked_bitwise_cast' in non-ossa code. This causes the cast to lose its guarantee of layout-compatibility. +unchecked_ownership_conversion +`````````````````````````````` +:: + + sil-instruction ::= 'unchecked_ownership_conversion' sil-operand ',' sil-value-ownership-kind 'to' sil-value-ownership-kind + + %1 = unchecked_ownership_conversion %0 : $A, @guaranteed to @owned + +Converts its operand to an identical value of the same type but with +different ownership without performing any semantic operations +normally required by for ownership conversion. + +This is used in Objective-C compatible destructors to convert a +guaranteed parameter to an owned parameter without performing a +semantic copy. + +The resulting value must meet the usual ownership requirements; for +example, a trivial type must have '.none' ownership. + ref_to_raw_pointer `````````````````` :: diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def index 3317ce298b3e9..457b4c1792eed 100644 --- a/include/swift/AST/Builtins.def +++ b/include/swift/AST/Builtins.def @@ -736,6 +736,15 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(CancelAsyncTask, "cancelAsyncTask", "", Speci /// a function to execute. BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask, "createAsyncTask", "", Special) +/// createAsyncTaskFuture(): ( +/// Int, Builtin.NativeObject?, @escaping () async throws -> T +/// ) -> Builtin.NativeObject +/// +/// Create a new asynchronous task future, given flags, an (optional) parent +/// task and a function to execute. +BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTaskFuture, + "createAsyncTaskFuture", "", Special) + /// globalStringTablePointer has type String -> Builtin.RawPointer. /// It returns an immortal, global string table pointer for strings constructed /// from string literals. We consider it effects as readnone meaning that it diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index ca4b7d6b88202..de6eb6f2c38ac 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -128,7 +128,8 @@ ERROR(error_mode_cannot_emit_interface,none, ERROR(error_mode_cannot_emit_module_summary,none, "this mode does not support emitting module summary files", ()) ERROR(cannot_emit_ir_skipping_function_bodies,none, - "-experimental-skip-*-function-bodies do not support emitting IR", ()) + "the -experimental-skip-*-function-bodies* flags do not support " + "emitting IR", ()) WARNING(emit_reference_dependencies_without_primary_file,none, "ignoring -emit-reference-dependencies (requires -primary-file)", ()) @@ -415,9 +416,9 @@ ERROR(expectation_missing_opening_braces,none, ERROR(expectation_missing_closing_braces,none, "didn't find '}}' to match '{{' in expectation", ()) -WARNING(module_incompatible_with_skip_non_inlinable_function_bodies,none, - "module '%0' cannot be built with " - "-experimental-skip-non-inlinable-function-bodies; this option has " +WARNING(module_incompatible_with_skip_function_bodies,none, + "module '%0' cannot be built with any of the " + "-experimental-skip-*-function-bodies* flags; they have " "been automatically disabled", (StringRef)) #define UNDEFINE_DIAGNOSTIC_MACROS diff --git a/include/swift/AST/GenericParamList.h b/include/swift/AST/GenericParamList.h index 2d3b8c34475c3..38b3b1344db4d 100644 --- a/include/swift/AST/GenericParamList.h +++ b/include/swift/AST/GenericParamList.h @@ -324,6 +324,9 @@ class GenericParamList final : if (WhereLoc.isInvalid()) return SourceRange(); + if (Requirements.empty()) + return WhereLoc; + auto endLoc = Requirements.back().getSourceRange().End; return SourceRange(WhereLoc, endLoc); } @@ -352,16 +355,18 @@ class alignas(RequirementRepr) TrailingWhereClause final : friend TrailingObjects; SourceLoc WhereLoc; + SourceLoc EndLoc; /// The number of requirements. The actual requirements are tail-allocated. unsigned NumRequirements; - TrailingWhereClause(SourceLoc whereLoc, + TrailingWhereClause(SourceLoc whereLoc, SourceLoc endLoc, ArrayRef requirements); public: /// Create a new trailing where clause with the given set of requirements. - static TrailingWhereClause *create(ASTContext &ctx, SourceLoc whereLoc, + static TrailingWhereClause *create(ASTContext &ctx, + SourceLoc whereLoc, SourceLoc endLoc, ArrayRef requirements); /// Retrieve the location of the 'where' keyword. @@ -379,8 +384,7 @@ class alignas(RequirementRepr) TrailingWhereClause final : /// Compute the source range containing this trailing where clause. SourceRange getSourceRange() const { - return SourceRange(WhereLoc, - getRequirements().back().getSourceRange().End); + return SourceRange(WhereLoc, EndLoc); } void print(llvm::raw_ostream &OS, bool printWhereKeyword) const; diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index bd32b8f067d41..b79cbf8c1be35 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -258,9 +258,6 @@ namespace swift { /// This is a staging flag; eventually it will be removed. bool EnableDeserializationRecovery = true; - /// Someday, ASTScopeLookup will supplant lookup in the parser - bool DisableParserLookup = false; - /// Whether to enable the new operator decl and precedencegroup lookup /// behavior. This is a staging flag, and will be removed in the future. bool EnableNewOperatorLookup = false; diff --git a/include/swift/Basic/TreeScopedHashTable.h b/include/swift/Basic/TreeScopedHashTable.h deleted file mode 100644 index 9867fe0246ca5..0000000000000 --- a/include/swift/Basic/TreeScopedHashTable.h +++ /dev/null @@ -1,431 +0,0 @@ -//===--- TreeScopedHashTable.h - Hash table with multiple active scopes ---===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// Note: This file intentionally uses C++03 so that it can be eventually moved -// into LLVM ADT library. - -#ifndef SWIFT_BASIC_TREESCOPEDHASHTABLE_H -#define SWIFT_BASIC_TREESCOPEDHASHTABLE_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/Allocator.h" -#include "swift/Basic/Debug.h" -#include "swift/Basic/Malloc.h" -#include - -namespace swift { - -template -class TreeScopedHashTable; - -template -class TreeScopedHashTableScope; - -template class TreeScopedHashTableVal { - TreeScopedHashTableVal *NextInScope; - TreeScopedHashTableVal *NextForKey; - K Key; - V Val; - TreeScopedHashTableVal(const K &Key, const V &Val) : Key(Key), Val(Val) {} - -public: - ~TreeScopedHashTableVal() = default; - TreeScopedHashTableVal(const TreeScopedHashTableVal &) = delete; - TreeScopedHashTableVal(TreeScopedHashTableVal &&) = delete; - TreeScopedHashTableVal &operator=(const TreeScopedHashTableVal &) = delete; - TreeScopedHashTableVal &operator=(TreeScopedHashTableVal &&) = delete; - - const K &getKey() const { return Key; } - const V &getValue() const { return Val; } - V &getValue() { return Val; } - - TreeScopedHashTableVal *getNextForKey() { return NextForKey; } - const TreeScopedHashTableVal *getNextForKey() const { return NextForKey; } - TreeScopedHashTableVal *getNextInScope() { return NextInScope; } - - template - static TreeScopedHashTableVal *Create(TreeScopedHashTableVal *NextInScope, - TreeScopedHashTableVal *NextForKey, - const K &key, const V &val, - AllocatorTy &Allocator) { - TreeScopedHashTableVal *New = - Allocator.template Allocate(); - // Set up the value. - new (New) TreeScopedHashTableVal(key, val); - New->NextInScope = NextInScope; - New->NextForKey = NextForKey; - return New; - } - - template void Destroy(AllocatorTy &Allocator) { - // Free memory referenced by the item. - this->~TreeScopedHashTableVal(); - Allocator.Deallocate(this); - } -}; - -/// A reference-counted scope that actually owns the data in the -/// hashtable. -template -class TreeScopedHashTableScopeImpl { -public: - typedef TreeScopedHashTable HTTy; - - /// The hashtable that we are active for. - HTTy *HT; - - const typename HTTy::ScopeIDTy ID; - - /// This is the scope that we are shadowing in HT. - TreeScopedHashTableScopeImpl *ParentScope; - - /// This is the last value that was inserted for this scope or null if none - /// have been inserted yet. - TreeScopedHashTableVal *LastValInScope; - - bool MovedFrom; - bool OwnsParentScope; - - unsigned RefCount; - - TreeScopedHashTableScopeImpl(TreeScopedHashTableScopeImpl &) = delete; - void operator=(TreeScopedHashTableScopeImpl &) = delete; - - TreeScopedHashTableScopeImpl() - : HT(0), ID(0), ParentScope(0), MovedFrom(true), RefCount(0) {} - - TreeScopedHashTableScopeImpl(TreeScopedHashTable *HT, - TreeScopedHashTableScopeImpl *ParentScope) - : HT(HT), ID(HT->getNextScopeID()), ParentScope(ParentScope), - LastValInScope(0), MovedFrom(false), OwnsParentScope(false), - RefCount(0) {} - - TreeScopedHashTableScopeImpl(TreeScopedHashTableScopeImpl &&Other) - : HT(Other.HT), ID(Other.ID), ParentScope(Other.ParentScope), - LastValInScope(Other.LastValInScope), MovedFrom(false), - OwnsParentScope(Other.OwnsParentScope), RefCount(Other.RefCount) { - assert(!Other.MovedFrom && "moving from a moved-from scope"); - Other.MovedFrom = true; - // *Don't* set Other.ID to a trap value so that the old scope object can - // be still used for lookup. - } - - void retain() { - RefCount++; - } - void release() { - RefCount--; - if (RefCount == 0) - delete this; - } - - ~TreeScopedHashTableScopeImpl(); -}; - -/// A scope that was detached from the stack to heap. -template -class TreeScopedHashTableDetachedScope { - friend class TreeScopedHashTableScope; - - typedef TreeScopedHashTableScopeImpl ImplTy; - - ImplTy *DetachedImpl; - - TreeScopedHashTableDetachedScope(TreeScopedHashTableDetachedScope &) = delete; - void operator=(TreeScopedHashTableDetachedScope &) = delete; - - TreeScopedHashTableDetachedScope(ImplTy *DetachedImpl) - : DetachedImpl(DetachedImpl) { - DetachedImpl->retain(); - } - - const ImplTy *getImpl() { return DetachedImpl; } - -public: - TreeScopedHashTableDetachedScope & - operator=(TreeScopedHashTableDetachedScope &&) = default; - - TreeScopedHashTableDetachedScope() : DetachedImpl(0) {} - - TreeScopedHashTableDetachedScope(TreeScopedHashTableDetachedScope &&Other) - : DetachedImpl(Other.DetachedImpl) { - Other.DetachedImpl = 0; - } - - ~TreeScopedHashTableDetachedScope() { - if (DetachedImpl) - DetachedImpl->release(); - } -}; - -/// A normal hashtable scope. Objects of this class should be created only -/// on stack. A normal scope is faster to create than a detached scope because -/// it does not do heap allocation for the reference counted -/// \c TreeScopedHashTableScopeImpl. -template -class TreeScopedHashTableScope { - friend class TreeScopedHashTable; - - typedef TreeScopedHashTableScopeImpl ImplTy; - - /// Inline storage for a reference-counted scope. - ImplTy InlineImpl; - - /// Pointer to the reference-counted scope that was detached to the heap. - ImplTy *DetachedImpl; - TreeScopedHashTableScope *const ParentScope; - - ImplTy *getImpl() { - assert(static_cast(DetachedImpl) == InlineImpl.MovedFrom); - return InlineImpl.MovedFrom ? DetachedImpl : &InlineImpl; - } - - const ImplTy *getImpl() const { - assert(static_cast(DetachedImpl) == InlineImpl.MovedFrom); - return InlineImpl.MovedFrom ? DetachedImpl : &InlineImpl; - } - - TreeScopedHashTableScope(TreeScopedHashTableScope &) = delete; - void operator=(TreeScopedHashTableScope &) = delete; - -public: - /// Install this as the current scope for the hash table. - TreeScopedHashTableScope(TreeScopedHashTable &HT, - TreeScopedHashTableScope *ParentScope) - : InlineImpl(&HT, ParentScope ? ParentScope->getImpl() : 0), - DetachedImpl(0), ParentScope(ParentScope) {} - - TreeScopedHashTableScope(TreeScopedHashTableDetachedScope &&DS) - : DetachedImpl(DS.DetachedImpl), ParentScope(0) { - DS.DetachedImpl = 0; - } - - ~TreeScopedHashTableScope() { - if (DetachedImpl) - DetachedImpl->release(); - } - - /// Detach this scope to the heap. - TreeScopedHashTableDetachedScope detach() { - if (DetachedImpl) - return TreeScopedHashTableDetachedScope(DetachedImpl); - - // Detach all parent scopes recursively. - if (ParentScope && !ParentScope->DetachedImpl) { - ParentScope->detach(); - InlineImpl.ParentScope = ParentScope->getImpl(); - } - - DetachedImpl = new ImplTy(std::move(InlineImpl)); - DetachedImpl->retain(); - if (DetachedImpl->ParentScope) { - DetachedImpl->ParentScope->retain(); - DetachedImpl->OwnsParentScope = true; - } - return TreeScopedHashTableDetachedScope(DetachedImpl); - } -}; - -template class TreeScopedHashTableIterator { - TreeScopedHashTableVal *Node; - -public: - TreeScopedHashTableIterator(TreeScopedHashTableVal *Node) - : Node(Node) {} - - V &operator*() const { - assert(Node && "Dereference end()"); - return Node->getValue(); - } - V *operator->() const { return &Node->getValue(); } - - bool operator==(const TreeScopedHashTableIterator &RHS) const { - return Node == RHS.Node; - } - bool operator!=(const TreeScopedHashTableIterator &RHS) const { - return Node != RHS.Node; - } - - inline TreeScopedHashTableIterator &operator++() { // Preincrement - assert(Node && "incrementing past end()"); - Node = Node->getNextForKey(); - return *this; - } - TreeScopedHashTableIterator operator++(int) { // Postincrement - TreeScopedHashTableIterator tmp = *this; - ++*this; - return tmp; - } -}; - -/// A scoped hashtable that can have multiple active scopes. -/// -/// There are two kinds of scopes: -/// -/// \li TreeScopedHashTableScope -- normal scopes, which should be created on -/// stack. Obviously, only one such scope can be active at a time. As soon as -/// the scope object is destroyed, corresponding data from the hashtable is -/// deleted. -/// -/// \li TreeScopedHashTableDetachedScope -- detached scopes, can be stored on -/// heap. These can be created from normal scopes by calling \c detach(). -/// Detaching a scope transparently detaches all its parent scopes. -/// A detached scope takes ownership of the corresponding data in the -/// hashtable. -/// -/// All scopes should be destroyed before hashtable is destroyed. -template -class TreeScopedHashTable { -public: - /// This is a helpful typedef that allows clients to get easy access - /// to the name of the scope for this hash table. - typedef TreeScopedHashTableScope ScopeTy; - typedef TreeScopedHashTableDetachedScope DetachedScopeTy; - -private: - typedef unsigned ScopeIDTy; - typedef std::pair KeyTy; - typedef TreeScopedHashTableVal ValTy; - llvm::DenseMap TopLevelMap; - - AllocatorTy Allocator; - - ScopeIDTy NextScopeID; - - ScopeIDTy getNextScopeID() { - return NextScopeID++; - } - - TreeScopedHashTable(const TreeScopedHashTable &) = delete; - void operator=(const TreeScopedHashTable &) = delete; - friend class TreeScopedHashTableScopeImpl; - -public: - TreeScopedHashTable() : NextScopeID(0) {} - TreeScopedHashTable(AllocatorTy A) : Allocator(A), NextScopeID(0) {} - ~TreeScopedHashTable() { - assert(TopLevelMap.empty() && "Scope imbalance!"); - } - - /// Access to the allocator. - typedef AllocatorTy &AllocatorRefTy; - typedef const AllocatorTy &AllocatorCRefTy; - AllocatorRefTy getAllocator() { return Allocator; } - AllocatorCRefTy getAllocator() const { return Allocator; } - - bool count(const ScopeTy &S, const K &Key) const { - const typename ScopeTy::ImplTy *CurrScope = S.getImpl(); - while (CurrScope) { - if (TopLevelMap.count(std::make_pair(Key, CurrScope->ID))) { - return true; - } - CurrScope = CurrScope->ParentScope; - } - return false; - } - - V lookup(const ScopeTy &S, const K &Key) { - const typename ScopeTy::ImplTy *CurrScope = S.getImpl(); - while (CurrScope) { - typename llvm::DenseMap::iterator I = - TopLevelMap.find(std::make_pair(Key, CurrScope->ID)); - if (I != TopLevelMap.end()) - return I->second->getValue(); - CurrScope = CurrScope->ParentScope; - } - return V(); - } - - typedef TreeScopedHashTableIterator iterator; - - iterator end() { return iterator(0); } - - iterator begin(ScopeTy &S, const K &Key) { - typename llvm::DenseMap::iterator I = - TopLevelMap.find(std::make_pair(Key, S.getImpl()->ID)); - if (I == TopLevelMap.end()) - return end(); - return iterator(I->second); - } - - using DebugVisitValueTy = TreeScopedHashTableVal *; - - /// Visit each entry in the map without regard to order. Meant to be used with - /// in the debugger in coordination with other dumpers that can dump whatever - /// is stored in the map. No-op when asserts are disabled. - SWIFT_DEBUG_HELPER( - void debugVisit(std::function &&func) const - ); - - /// This inserts the specified key/value at the specified - /// (possibly not the current) scope. While it is ok to insert into a scope - /// that isn't the current one, it isn't ok to insert *underneath* an existing - /// value of the specified key. - void insertIntoScope(ScopeTy &S, const K &Key, const V &Val) { - TreeScopedHashTableVal *PrevEntry = 0; - const typename ScopeTy::ImplTy *CurrScope = S.getImpl(); - while (CurrScope) { - typename llvm::DenseMap::iterator I = - TopLevelMap.find(std::make_pair(Key, CurrScope->ID)); - if (I != TopLevelMap.end()) { - PrevEntry = I->second; - break; - } - CurrScope = CurrScope->ParentScope; - } - assert(TopLevelMap.find(std::make_pair(Key, S.getImpl()->ID)) == TopLevelMap.end()); - - TreeScopedHashTableVal *&KeyEntry = - TopLevelMap[std::make_pair(Key, S.getImpl()->ID)]; - KeyEntry = - ValTy::Create(S.getImpl()->LastValInScope, PrevEntry, Key, Val, Allocator); - S.getImpl()->LastValInScope = KeyEntry; - } -}; - -template -void TreeScopedHashTable::debugVisit( - std::function &&func) const { -#ifndef NDEBUG - for (auto entry : TopLevelMap) { - func(entry.second); - } -#endif -} - -template -TreeScopedHashTableScopeImpl::~TreeScopedHashTableScopeImpl() { - if (MovedFrom) - return; - - // Pop and delete all values corresponding to this scope. - while (TreeScopedHashTableVal *ThisEntry = LastValInScope) { - // Pop this value out of the TopLevelMap. - assert(HT->TopLevelMap[std::make_pair(ThisEntry->getKey(), this->ID)] == - ThisEntry && - "Scope imbalance!"); - HT->TopLevelMap.erase(std::make_pair(ThisEntry->getKey(), this->ID)); - - // Pop this value out of the scope. - LastValInScope = ThisEntry->getNextInScope(); - - // Delete this entry. - ThisEntry->Destroy(HT->getAllocator()); - } - - if (OwnsParentScope) - ParentScope->release(); -} - -} // end namespace swift - -#endif // SWIFT_BASIC_TREESCOPEDHASHTABLE_H diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index a79a7879a407d..eb5cf3a7bec02 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1118,14 +1118,6 @@ def emit_supported_features : Flag<["-"], "emit-supported-features">, HelpText<"Emit a JSON file including all supported compiler features">, ModeOpt, Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>; -def disable_parser_lookup : Flag<["-"], "disable-parser-lookup">, - Flags<[FrontendOption]>, - 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">, Flags<[FrontendOption]>, diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index a3ca904ad12f0..36bbd85a0b24e 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -136,13 +136,6 @@ class Parser { void recordTokenHash(StringRef token); - /// DisabledVars is a list of variables for whom local name lookup is - /// disabled. This is used when parsing a PatternBindingDecl to reject self - /// uses and to disable uses of the bound variables in a let/else block. The - /// diagnostic to emit is stored in DisabledVarReason. - ArrayRef DisabledVars; - Diag<> DisabledVarReason; - enum { /// InVarOrLetPattern has this value when not parsing a pattern. IVOLP_NotInVarOrLet, @@ -790,23 +783,6 @@ class Parser { consumeStartingCharacterOfCurrentToken(tok Kind = tok::oper_binary_unspaced, size_t Len = 1); - swift::ScopeInfo &getScopeInfo() { return State->getScopeInfo(); } - - /// Add the given Decl to the current scope. - void addToScope(ValueDecl *D, bool diagnoseRedefinitions = true) { - if (Context.LangOpts.DisableParserLookup) - return; - - getScopeInfo().addToScope(D, *this, diagnoseRedefinitions); - } - - ValueDecl *lookupInScope(DeclNameRef Name) { - if (Context.LangOpts.DisableParserLookup) - return nullptr; - - return getScopeInfo().lookupValueName(Name); - } - //===--------------------------------------------------------------------===// // Primitive Parsing @@ -1171,9 +1147,6 @@ class Parser { ParserResult parseDeclDeinit(ParseDeclOptions Flags, DeclAttributes &Attributes); - void addPatternVariablesToScope(ArrayRef Patterns); - void addParametersToScope(ParameterList *PL); - ParserResult parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes); ParserResult parseDeclOperatorImpl(SourceLoc OperatorLoc, @@ -1224,8 +1197,7 @@ class Parser { ParserResult parseOldStyleProtocolComposition(); ParserResult parseAnyType(); ParserResult parseSILBoxType(GenericParamList *generics, - const TypeAttributes &attrs, - Optional &GenericsScope); + const TypeAttributes &attrs); ParserResult parseTypeTupleBody(); ParserResult parseTypeArray(TypeRepr *Base); @@ -1689,8 +1661,9 @@ class Parser { parseFreestandingGenericWhereClause(GenericContext *genCtx); ParserStatus parseGenericWhereClause( - SourceLoc &WhereLoc, SmallVectorImpl &Requirements, - bool &FirstTypeInComplete, bool AllowLayoutConstraints = false); + SourceLoc &WhereLoc, SourceLoc &EndLoc, + SmallVectorImpl &Requirements, + bool AllowLayoutConstraints = false); ParserStatus parseProtocolOrAssociatedTypeWhereClause(TrailingWhereClause *&trailingWhere, diff --git a/include/swift/Parse/PersistentParserState.h b/include/swift/Parse/PersistentParserState.h index 0879674a33492..852bca9afbeeb 100644 --- a/include/swift/Parse/PersistentParserState.h +++ b/include/swift/Parse/PersistentParserState.h @@ -19,7 +19,6 @@ #include "swift/Basic/SourceLoc.h" #include "swift/Parse/LocalContext.h" -#include "swift/Parse/Scope.h" namespace swift { @@ -38,33 +37,27 @@ class CodeCompletionDelayedDeclState { CodeCompletionDelayedDeclKind Kind; unsigned Flags; DeclContext *ParentContext; - SavedScope Scope; unsigned StartOffset; unsigned EndOffset; unsigned PrevOffset; - SavedScope takeScope() { return std::move(Scope); } - CodeCompletionDelayedDeclState(CodeCompletionDelayedDeclKind Kind, unsigned Flags, DeclContext *ParentContext, - SavedScope &&Scope, unsigned StartOffset, - unsigned EndOffset, unsigned PrevOffset) + unsigned StartOffset, unsigned EndOffset, + unsigned PrevOffset) : Kind(Kind), Flags(Flags), ParentContext(ParentContext), - Scope(std::move(Scope)), StartOffset(StartOffset), EndOffset(EndOffset), + StartOffset(StartOffset), EndOffset(EndOffset), PrevOffset(PrevOffset) {} }; /// Parser state persistent across multiple parses. class PersistentParserState { - swift::ScopeInfo ScopeInfo; - std::unique_ptr CodeCompletionDelayedDeclStat; /// The local context for all top-level code. TopLevelContext TopLevelCode; public: - swift::ScopeInfo &getScopeInfo() { return ScopeInfo; } PersistentParserState(); PersistentParserState(ASTContext &ctx) : PersistentParserState() { } ~PersistentParserState(); diff --git a/include/swift/Parse/Scope.h b/include/swift/Parse/Scope.h deleted file mode 100644 index c58443d335384..0000000000000 --- a/include/swift/Parse/Scope.h +++ /dev/null @@ -1,192 +0,0 @@ -//===--- Scope.h - Scope Abstraction ----------------------------*- 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 file defines the Sema interface which implement hooks invoked by the -// parser to build the AST. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SEMA_SCOPE_H -#define SWIFT_SEMA_SCOPE_H - -#include "swift/AST/Identifier.h" -#include "swift/Basic/Debug.h" -#include "swift/Basic/TreeScopedHashTable.h" - -namespace swift { - class ValueDecl; - class Parser; - class Scope; - class SavedScope; - -/// ScopeInfo - A single instance of this class is maintained by the Parser to -/// track the current scope. -class ScopeInfo { - friend class Scope; -public: - using ValueScopeEntry = std::pair; - - using ScopedHTTy = TreeScopedHashTable; - using ScopedHTScopeTy = ScopedHTTy::ScopeTy; - using ScopedHTDetachedScopeTy = ScopedHTTy::DetachedScopeTy; - -private: - ScopedHTTy HT; - - Scope *CurScope = nullptr; - unsigned ResolvableDepth = 0; - -public: - ValueDecl *lookupValueName(DeclNameRef Name); - - Scope *getCurrentScope() const { return CurScope; } - - /// addToScope - Register the specified decl as being in the current lexical - /// scope. - void addToScope(ValueDecl *D, Parser &TheParser, - bool diagnoseRedefinitions = true); - - bool isInactiveConfigBlock() const; - - SavedScope saveCurrentScope(); - - SWIFT_DEBUG_DUMP; -}; - -enum class ScopeKind { - Extension, - FunctionBody, - Generics, - EnumBody, - StructBody, - ClassBody, - ProtocolBody, - InheritanceClause, - - Brace, - TopLevel, - ForeachVars, - CaseVars, - CatchVars, - WhileVars, - IfVars, - - ClosureParams, -}; - -/// An opaque object that owns the scope frame. The scope frame can be -/// re-entered later. -class SavedScope { - friend class Scope; - - ScopeInfo::ScopedHTDetachedScopeTy HTDetachedScope; - unsigned Depth; - ScopeKind Kind; - bool IsInactiveConfigBlock; - - SavedScope() = delete; - SavedScope(const SavedScope &) = delete; - void operator=(const SavedScope &) = delete; - -public: - SavedScope(SavedScope &&Other) = default; - SavedScope &operator=(SavedScope &&) = default; - ~SavedScope() = default; - - SavedScope(ScopeInfo::ScopedHTDetachedScopeTy &&HTDetachedScope, - unsigned Depth, ScopeKind Kind, bool isInactiveConfigBlock) - : HTDetachedScope(std::move(HTDetachedScope)), Depth(Depth), Kind(Kind), - IsInactiveConfigBlock(isInactiveConfigBlock) {} -}; - -/// Scope - This class represents lexical scopes. These objects are created -/// and destroyed as the parser is running, and name lookup happens relative -/// to them. -/// -class Scope { - friend class ScopeInfo; - - Scope(const Scope&) = delete; - void operator=(const Scope&) = delete; - - ScopeInfo &SI; - ScopeInfo::ScopedHTScopeTy HTScope; - - Scope *PrevScope; - unsigned PrevResolvableDepth; - unsigned Depth; - ScopeKind Kind; - bool IsInactiveConfigBlock; - - /// Save this scope so that it can be re-entered later. Transfers the - /// ownership of the scope frame to returned object. - SavedScope saveScope() { - return SavedScope(HTScope.detach(), Depth, Kind, IsInactiveConfigBlock); - } - - unsigned getDepth() const { - return Depth; - } - - bool isResolvable() const; - -public: - Scope(ScopeInfo &SI, ScopeKind SC, bool isInactiveConfigBlock = false); - - /// Create a lexical scope of the specified kind. - Scope(Parser *P, ScopeKind SC, bool isInactiveConfigBlock = false); - - /// Re-enter the specified scope, transferring the ownership of the - /// scope frame to the new object. - Scope(Parser *P, SavedScope &&SS); - - ScopeKind getKind() const { return Kind; } - - ~Scope() { - // Active config blocks delegate to the enclosing scope, so there's nothing - // to pop off. - assert(SI.CurScope == this && "Scope mismatch"); - SI.CurScope = PrevScope; - SI.ResolvableDepth = PrevResolvableDepth; - } -}; - -inline ValueDecl *ScopeInfo::lookupValueName(DeclNameRef Name) { - // FIXME: this check can go away when SIL parser parses everything in - // a toplevel scope. - if (!CurScope) - return nullptr; - - assert(CurScope && "no scope"); - // If we found nothing, or we found a decl at the top-level, return nothing. - // We ignore results at the top-level because we may have overloading that - // will be resolved properly by name lookup. - std::pair Res = HT.lookup(CurScope->HTScope, - Name.getFullName()); - if (Res.first < ResolvableDepth) - return 0; - return Res.second; -} - -inline bool ScopeInfo::isInactiveConfigBlock() const { - if (!CurScope) - return false; - return CurScope->IsInactiveConfigBlock; -} - -inline SavedScope ScopeInfo::saveCurrentScope() { - return CurScope->saveScope(); -} - -} // end namespace swift - -#endif diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def index 80f2364a826af..bc9278e9bab72 100644 --- a/include/swift/Runtime/RuntimeFunctions.def +++ b/include/swift/Runtime/RuntimeFunctions.def @@ -1498,12 +1498,24 @@ FUNCTION(TaskCancel, ATTRS(NoUnwind, ArgMemOnly)) // AsyncTaskAndContext swift_task_create( -// size_t flags, AsyncTask *task, AsyncFunctionPointer *function); +// size_t flags, AsyncTask *task, TaskContinuationFunction* function, +// size_t contextSize); FUNCTION(TaskCreateFunc, - swift_task_create, SwiftCC, + swift_task_create_f, SwiftCC, ConcurrencyAvailability, RETURNS(AsyncTaskAndContextTy), - ARGS(SizeTy, SwiftTaskPtrTy, AsyncFunctionPointerPtrTy), + ARGS(SizeTy, SwiftTaskPtrTy, TaskContinuationFunctionPtrTy, SizeTy), + ATTRS(NoUnwind, ArgMemOnly)) + +// AsyncTaskAndContext swift_task_create_future_f( +// size_t flags, AsyncTask *task, const Metadata *futureResultType, +// TaskContinuationFunction *function, size_t contextSize); +FUNCTION(TaskCreateFutureFunc, + swift_task_create_future_f, SwiftCC, + ConcurrencyAvailability, + RETURNS(AsyncTaskAndContextTy), + ARGS(SizeTy, SwiftTaskPtrTy, TypeMetadataPtrTy, + TaskContinuationFunctionPtrTy, SizeTy), ATTRS(NoUnwind, ArgMemOnly)) #undef RETURNS diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def index 7148a46b82f9d..b88fbc85890b5 100644 --- a/include/swift/SIL/SILNodes.def +++ b/include/swift/SIL/SILNodes.def @@ -575,7 +575,7 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction) SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) #include "swift/AST/ReferenceStorage.def" SINGLE_VALUE_INST(UncheckedOwnershipConversionInst, unchecked_ownership_conversion, - SingleValueInstruction, MayHaveSideEffects, MayRelease) + SingleValueInstruction, None, MayRelease) // IsUnique does not actually write to memory but should be modeled // as such. Its operand is a pointer to an object reference. The diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index 40d7dc6ffc94f..ec02718e74eca 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -4736,26 +4736,11 @@ class ConstraintSystem { /// Whether the bindings of this type involve other type variables. bool InvolvesTypeVariables = false; - /// Whether this type variable is considered a hole in the constraint system. - bool IsHole = false; - - /// Whether the bindings represent (potentially) incomplete set, - /// there is no way to say with absolute certainty if that's the - /// case, but that could happen when certain constraints like - /// `bind param` are present in the system. - bool PotentiallyIncomplete = false; - ASTNode AssociatedCodeCompletionToken = ASTNode(); /// Whether this type variable has literal bindings. LiteralBindingKind LiteralBinding = LiteralBindingKind::None; - /// Whether this type variable is only bound above by existential types. - bool SubtypeOfExistentialType = false; - - /// The number of defaultable bindings. - unsigned NumDefaultableBindings = 0; - /// Tracks the position of the last known supertype in the group. Optional lastSupertypeIndex; @@ -4767,41 +4752,80 @@ class ConstraintSystem { llvm::SmallMapVector SupertypeOf; llvm::SmallMapVector EquivalentTo; - PotentialBindings(TypeVariableType *typeVar) - : TypeVar(typeVar), PotentiallyIncomplete(isGenericParameter()) {} + PotentialBindings(TypeVariableType *typeVar) : TypeVar(typeVar) {} /// Determine whether the set of bindings is non-empty. explicit operator bool() const { return !Bindings.empty(); } - /// Whether there are any non-defaultable bindings. - bool hasNonDefaultableBindings() const { - return Bindings.size() > NumDefaultableBindings; + /// Whether the bindings represent (potentially) incomplete set, + /// there is no way to say with absolute certainty if that's the + /// case, but that could happen when certain constraints like + /// `bind param` are present in the system. + bool isPotentiallyIncomplete() const; + + /// If there is only one binding and it's to a hole type, consider + /// this type variable to be a hole in a constraint system regardless + /// of where hole type originated. + bool isHole() const { + if (Bindings.size() != 1) + return false; + + auto &binding = Bindings.front(); + return binding.BindingType->is(); + } + + /// Determine if the bindings only constrain the type variable from above + /// with an existential type; such a binding is not very helpful because + /// it's impossible to enumerate the existential type's subtypes. + bool isSubtypeOfExistentialType() const { + if (Bindings.empty()) + return false; + + return llvm::all_of(Bindings, [](const PotentialBinding &binding) { + return binding.BindingType->isExistentialType() && + binding.Kind == AllowedBindingKind::Subtypes; + }); + } + + unsigned getNumDefaultableBindings() const { + return llvm::count_if(Bindings, [](const PotentialBinding &binding) { + return binding.isDefaultableBinding(); + }); } static BindingScore formBindingScore(const PotentialBindings &b) { - return std::make_tuple(b.IsHole, - !b.hasNonDefaultableBindings(), + auto numDefaults = b.getNumDefaultableBindings(); + auto hasNoDefaultableBindings = b.Bindings.size() > numDefaults; + + return std::make_tuple(b.isHole(), + !hasNoDefaultableBindings, b.FullyBound, - b.SubtypeOfExistentialType, + b.isSubtypeOfExistentialType(), b.InvolvesTypeVariables, static_cast(b.LiteralBinding), - -(b.Bindings.size() - b.NumDefaultableBindings)); + -(b.Bindings.size() - numDefaults)); } /// Compare two sets of bindings, where \c x < y indicates that /// \c x is a better set of bindings that \c y. friend bool operator<(const PotentialBindings &x, const PotentialBindings &y) { - if (formBindingScore(x) < formBindingScore(y)) + auto xScore = formBindingScore(x); + auto yScore = formBindingScore(y); + + if (xScore < yScore) return true; - if (formBindingScore(y) < formBindingScore(x)) + if (yScore < xScore) return false; + auto xDefaults = x.Bindings.size() + std::get<6>(xScore); + auto yDefaults = y.Bindings.size() + std::get<6>(yScore); + // If there is a difference in number of default types, // prioritize bindings with fewer of them. - if (x.NumDefaultableBindings != y.NumDefaultableBindings) - return x.NumDefaultableBindings < y.NumDefaultableBindings; + if (xDefaults != yDefaults) + return xDefaults < yDefaults; // If neither type variable is a "hole" let's check whether // there is a subtype relationship between them and prefer @@ -4809,7 +4833,7 @@ class ConstraintSystem { // for "subtype" type variable to attempt more bindings later. // This is required because algorithm can't currently infer // bindings for subtype transitively through superclass ones. - if (!(x.IsHole && y.IsHole)) { + if (!(std::get<0>(xScore) && std::get<0>(yScore))) { if (x.isSubtypeOf(y.TypeVar)) return false; @@ -4819,7 +4843,7 @@ class ConstraintSystem { // As a last resort, let's check if the bindings are // potentially incomplete, and if so, let's de-prioritize them. - return x.PotentiallyIncomplete < y.PotentiallyIncomplete; + return x.isPotentiallyIncomplete() < y.isPotentiallyIncomplete(); } void foundLiteralBinding(ProtocolDecl *proto) { @@ -4920,18 +4944,20 @@ class ConstraintSystem { void dump(llvm::raw_ostream &out, unsigned indent = 0) const LLVM_ATTRIBUTE_USED { out.indent(indent); - if (PotentiallyIncomplete) + if (isPotentiallyIncomplete()) out << "potentially_incomplete "; if (FullyBound) out << "fully_bound "; - if (SubtypeOfExistentialType) + if (isSubtypeOfExistentialType()) out << "subtype_of_existential "; if (LiteralBinding != LiteralBindingKind::None) out << "literal=" << static_cast(LiteralBinding) << " "; if (InvolvesTypeVariables) out << "involves_type_vars "; - if (NumDefaultableBindings > 0) - out << "#defaultable_bindings=" << NumDefaultableBindings << " "; + + auto numDefaultable = getNumDefaultableBindings(); + if (numDefaultable > 0) + out << "#defaultable_bindings=" << numDefaultable << " "; PrintOptions PO; PO.PrintTypesForDebugging = true; diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index 03992fc22274d..6125b87112d9e 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -1369,6 +1369,20 @@ static ValueDecl *getCreateAsyncTask(ASTContext &ctx, Identifier id) { getAsyncTaskAndContextType(ctx)); } +static ValueDecl *getCreateAsyncTaskFuture(ASTContext &ctx, Identifier id) { + BuiltinFunctionBuilder builder(ctx); + auto genericParam = makeGenericParam().build(builder); + builder.addParameter( + makeConcrete(ctx.getIntDecl()->getDeclaredInterfaceType())); + builder.addParameter( + makeConcrete(OptionalType::get(ctx.TheNativeObjectType))); + auto extInfo = ASTExtInfoBuilder().withAsync().withThrows().build(); + builder.addParameter( + makeConcrete(FunctionType::get({ }, genericParam, extInfo))); + builder.setResult(makeConcrete(getAsyncTaskAndContextType(ctx))); + return builder.build(id); +} + static ValueDecl *getPoundAssert(ASTContext &Context, Identifier Id) { auto int1Type = BuiltinIntegerType::get(1, Context); auto optionalRawPointerType = BoundGenericEnumType::get( @@ -2504,6 +2518,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { case BuiltinValueKind::CreateAsyncTask: return getCreateAsyncTask(Context, Id); + case BuiltinValueKind::CreateAsyncTaskFuture: + return getCreateAsyncTaskFuture(Context, Id); + case BuiltinValueKind::PoundAssert: return getPoundAssert(Context, Id); diff --git a/lib/AST/GenericParamList.cpp b/lib/AST/GenericParamList.cpp index 426833e151997..adb566a045544 100644 --- a/lib/AST/GenericParamList.cpp +++ b/lib/AST/GenericParamList.cpp @@ -110,9 +110,9 @@ GenericTypeParamDecl *GenericParamList::lookUpGenericParam( } TrailingWhereClause::TrailingWhereClause( - SourceLoc whereLoc, + SourceLoc whereLoc, SourceLoc endLoc, ArrayRef requirements) - : WhereLoc(whereLoc), + : WhereLoc(whereLoc), EndLoc(endLoc), NumRequirements(requirements.size()) { std::uninitialized_copy(requirements.begin(), requirements.end(), @@ -122,8 +122,9 @@ TrailingWhereClause::TrailingWhereClause( TrailingWhereClause *TrailingWhereClause::create( ASTContext &ctx, SourceLoc whereLoc, + SourceLoc endLoc, ArrayRef requirements) { unsigned size = totalSizeToAlloc(requirements.size()); void *mem = ctx.Allocate(size, alignof(TrailingWhereClause)); - return new (mem) TrailingWhereClause(whereLoc, requirements); + return new (mem) TrailingWhereClause(whereLoc, endLoc, requirements); } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 928f4a40918d0..376b039e76649 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -268,8 +268,6 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_debug_diagnostic_names); 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/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 7852b9b4613b7..833210cf35c9d 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -434,9 +434,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, = A->getOption().matches(OPT_enable_target_os_checking); } - Opts.DisableParserLookup |= Args.hasFlag(OPT_disable_parser_lookup, - OPT_enable_parser_lookup, - /*default*/ true); Opts.EnableNewOperatorLookup = Args.hasFlag(OPT_enable_new_operator_lookup, OPT_disable_new_operator_lookup, /*default*/ false); @@ -744,15 +741,15 @@ static bool ParseTypeCheckerArgs(TypeCheckerOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_experimental_skip_all_function_bodies)) Opts.SkipFunctionBodies = FunctionBodySkipping::All; - if (Opts.SkipFunctionBodies == FunctionBodySkipping::NonInlinable && + if (Opts.SkipFunctionBodies != FunctionBodySkipping::None && FrontendOpts.ModuleName == SWIFT_ONONE_SUPPORT) { - // Disable this optimization if we're compiling SwiftOnoneSupport, because - // we _definitely_ need to look inside every declaration to figure out - // what gets prespecialized. + // Disable these optimizations if we're compiling SwiftOnoneSupport, + // because we _definitely_ need to look inside every declaration to figure + // out what gets prespecialized. Opts.SkipFunctionBodies = FunctionBodySkipping::None; Diags.diagnose( SourceLoc(), - diag::module_incompatible_with_skip_non_inlinable_function_bodies, + diag::module_incompatible_with_skip_function_bodies, SWIFT_ONONE_SUPPORT); } diff --git a/lib/IDE/CompletionInstance.cpp b/lib/IDE/CompletionInstance.cpp index 355713a970591..597e59957a3c2 100644 --- a/lib/IDE/CompletionInstance.cpp +++ b/lib/IDE/CompletionInstance.cpp @@ -366,7 +366,6 @@ bool CompletionInstance::performCachedOperationIfPossible( tmpSM.setCodeCompletionPoint(tmpBufferID, Offset); LangOptions langOpts = CI.getASTContext().LangOpts; - langOpts.DisableParserLookup = true; TypeCheckerOptions typeckOpts = CI.getASTContext().TypeCheckerOpts; SearchPathOptions searchPathOpts = CI.getASTContext().SearchPathOpts; DiagnosticEngine tmpDiags(tmpSM); @@ -444,17 +443,6 @@ bool CompletionInstance::performCachedOperationIfPossible( 1); SM.setCodeCompletionPoint(newBufferID, newOffset); - // Construct dummy scopes. We don't need to restore the original scope - // because they are probably not 'isResolvable()' anyway. - auto &SI = oldState->getScopeInfo(); - assert(SI.getCurrentScope() == nullptr); - Scope Top(SI, ScopeKind::TopLevel); - Scope Body(SI, ScopeKind::FunctionBody); - - assert(oldInfo.Kind == CodeCompletionDelayedDeclKind::FunctionBody && - "If the interface hash is the same as old one, the previous kind " - "must be FunctionBody too. Otherwise, hashing is too weak"); - oldInfo.Kind = CodeCompletionDelayedDeclKind::FunctionBody; oldInfo.ParentContext = DC; oldInfo.StartOffset = newInfo.StartOffset; oldInfo.EndOffset = newInfo.EndOffset; diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp index 0153cb6858f87..58efe1a268d23 100644 --- a/lib/IRGen/GenBuiltin.cpp +++ b/lib/IRGen/GenBuiltin.cpp @@ -225,9 +225,14 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, return; } - if (Builtin.ID == BuiltinValueKind::CreateAsyncTask) { + if (Builtin.ID == BuiltinValueKind::CreateAsyncTask || + Builtin.ID == BuiltinValueKind::CreateAsyncTaskFuture) { auto flags = args.claimNext(); auto parentTask = args.claimNext(); + auto futureResultType = + (Builtin.ID == BuiltinValueKind::CreateAsyncTaskFuture) + ? args.claimNext() + : nullptr; auto taskFunction = args.claimNext(); auto taskContext = args.claimNext(); @@ -237,7 +242,8 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, IGF.emitNativeStrongRetain(taskContext, IGF.getDefaultAtomicity()); auto newTaskAndContext = emitTaskCreate( - IGF, flags, parentTask, taskFunction, taskContext); + IGF, flags, parentTask, futureResultType, taskFunction, taskContext, + substitutions); // Cast back to NativeObject/RawPointer. auto newTask = IGF.Builder.CreateExtractValue(newTaskAndContext, { 0 }); @@ -249,6 +255,7 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, return; } + // If this is an LLVM IR intrinsic, lower it to an intrinsic call. const IntrinsicInfo &IInfo = IGF.getSILModule().getIntrinsicInfo(FnId); llvm::Intrinsic::ID IID = IInfo.ID; diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 0744ea7d5f50b..65fbb3fc302ac 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -156,6 +156,8 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType, typeInfos.push_back(&errorTypeInfo); valTypes.push_back(errorType); + bool canHaveValidError = substitutedType->hasErrorResult(); + // IndirectResultTypes *indirectResults...; auto indirectResults = fnConv.getIndirectSILResults(); for (auto indirectResult : indirectResults) { @@ -196,15 +198,35 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType, } // SelfType self?; - bool hasLocalContextParameter = hasSelfContextParameter(substitutedType); - bool canHaveValidError = substitutedType->hasErrorResult(); - bool hasLocalContext = (hasLocalContextParameter || canHaveValidError); + bool hasSelf = hasSelfContextParameter(substitutedType); SILParameterInfo localContextParameter = - hasLocalContextParameter ? parameters.back() : SILParameterInfo(); - if (hasLocalContextParameter) { + hasSelf ? parameters.back() : SILParameterInfo(); + if (hasSelf) { parameters = parameters.drop_back(); } + Optional localContextInfo = llvm::None; + if (hasSelf) { + assert(originalType->getRepresentation() != + SILFunctionTypeRepresentation::Thick); + SILType ty = IGM.silConv.getSILType(localContextParameter, substitutedType, + IGM.getMaximalTypeExpansionContext()); + auto argumentLoweringType = + getArgumentLoweringType(ty.getASTType(), localContextParameter, + /*isNoEscape*/ true); + + auto &ti = IGM.getTypeInfoForLowered(argumentLoweringType); + valTypes.push_back(ty); + typeInfos.push_back(&ti); + localContextInfo = {ty, localContextParameter.getConvention()}; + } else { + auto &ti = IGM.getNativeObjectTypeInfo(); + SILType ty = SILType::getNativeObjectType(IGM.Context); + valTypes.push_back(ty); + typeInfos.push_back(&ti); + localContextInfo = {ty, substitutedType->getCalleeConvention()}; + } + // ArgTypes formalArguments...; for (auto parameter : parameters) { SILType ty = IGM.silConv.getSILType(parameter, substitutedType, @@ -230,31 +252,6 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType, typeInfos.push_back(&bindingsTI); } - Optional localContextInfo = llvm::None; - if (hasLocalContext) { - if (hasLocalContextParameter) { - SILType ty = - IGM.silConv.getSILType(localContextParameter, substitutedType, - IGM.getMaximalTypeExpansionContext()); - auto argumentLoweringType = - getArgumentLoweringType(ty.getASTType(), localContextParameter, - /*isNoEscape*/ true); - - auto &ti = IGM.getTypeInfoForLowered(argumentLoweringType); - valTypes.push_back(ty); - typeInfos.push_back(&ti); - localContextInfo = {ty, localContextParameter.getConvention()}; - } else { - // TODO: DETERMINE: Is there a field in this case to match the sync ABI? - auto &ti = IGM.getNativeObjectTypeInfo(); - SILType ty = SILType::getNativeObjectType(IGM.Context); - valTypes.push_back(ty); - typeInfos.push_back(&ti); - localContextInfo = {ty, substitutedType->getCalleeConvention()}; - } - } - - Optional trailingWitnessInfo; if (originalType->getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod) { @@ -778,10 +775,6 @@ void SignatureExpansion::addAsyncParameters() { ParamIRTypes.push_back(IGM.SwiftTaskPtrTy); ParamIRTypes.push_back(IGM.SwiftExecutorPtrTy); ParamIRTypes.push_back(IGM.SwiftContextPtrTy); - if (FnType->getRepresentation() == SILFunctionTypeRepresentation::Thick) { - IGM.addSwiftSelfAttributes(Attrs, ParamIRTypes.size()); - ParamIRTypes.push_back(IGM.RefCountedPtrTy); - } } void SignatureExpansion::addCoroutineContextParameter() { @@ -2314,10 +2307,6 @@ class AsyncCallEmission final : public CallEmission { asyncExplosion.add(IGF.getAsyncTask()); asyncExplosion.add(IGF.getAsyncExecutor()); asyncExplosion.add(contextBuffer.getAddress()); - if (getCallee().getRepresentation() == - SILFunctionTypeRepresentation::Thick) { - asyncExplosion.add(getCallee().getSwiftContext()); - } super::setArgs(asyncExplosion, false, witnessMetadata); SILFunctionConventions fnConv(getCallee().getSubstFunctionType(), IGF.getSILModule()); @@ -2380,11 +2369,18 @@ class AsyncCallEmission final : public CallEmission { auto bindingsAddr = bindingLayout.project(IGF, context, /*offsets*/ None); layout.getBindings().save(IGF, bindingsAddr, llArgs); } - if (selfValue) { - Explosion selfExplosion; - selfExplosion.add(selfValue); + auto isThick = + getCallee().getRepresentation() == SILFunctionTypeRepresentation::Thick; + if (selfValue || isThick) { + Explosion localExplosion; + if (selfValue) { + assert(!isThick); + localExplosion.add(selfValue); + } else { + localExplosion.add(getCallee().getSwiftContext()); + } auto fieldLayout = layout.getLocalContextLayout(); - saveValue(fieldLayout, selfExplosion, isOutlined); + saveValue(fieldLayout, localExplosion, isOutlined); } } void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override { @@ -3595,41 +3591,64 @@ void irgen::emitTaskCancel(IRGenFunction &IGF, llvm::Value *task) { llvm::Value *irgen::emitTaskCreate( IRGenFunction &IGF, llvm::Value *flags, llvm::Value *parentTask, - llvm::Value *taskFunction, llvm::Value *localContextInfo) { + llvm::Value *futureResultType, + llvm::Value *taskFunction, llvm::Value *localContextInfo, + SubstitutionMap subs) { parentTask = IGF.Builder.CreateBitOrPointerCast( parentTask, IGF.IGM.SwiftTaskPtrTy); - taskFunction = IGF.Builder.CreateBitOrPointerCast( - taskFunction, IGF.IGM.AsyncFunctionPointerPtrTy); // Determine the size of the async context for the closure. ASTContext &ctx = IGF.IGM.IRGen.SIL.getASTContext(); auto extInfo = ASTExtInfoBuilder().withAsync().withThrows().build(); - auto taskFunctionType = FunctionType::get( - { }, ctx.TheEmptyTupleType, extInfo); + AnyFunctionType *taskFunctionType; + if (futureResultType) { + auto genericParam = GenericTypeParamType::get(0, 0, ctx); + auto genericSig = GenericSignature::get({genericParam}, {}); + taskFunctionType = GenericFunctionType::get( + genericSig, { }, genericParam, extInfo); + + taskFunctionType = Type(taskFunctionType).subst(subs)->castTo(); + } else { + taskFunctionType = FunctionType::get( + { }, ctx.TheEmptyTupleType, extInfo); + } CanSILFunctionType taskFunctionCanSILType = IGF.IGM.getLoweredType(taskFunctionType).castTo(); auto layout = getAsyncContextLayout( - IGF.IGM, taskFunctionCanSILType, taskFunctionCanSILType, - SubstitutionMap()); + IGF.IGM, taskFunctionCanSILType, taskFunctionCanSILType, subs); // Call the function. - auto *result = IGF.Builder.CreateCall( - IGF.IGM.getTaskCreateFuncFn(), - { flags, parentTask, taskFunction }); + llvm::CallInst *result; + llvm::Value *theSize, *theFunction; + std::tie(theFunction, theSize) = + getAsyncFunctionAndSize(IGF, SILFunctionTypeRepresentation::Thick, + FunctionPointer::forExplosionValue( + IGF, taskFunction, taskFunctionCanSILType), + localContextInfo); + theFunction = IGF.Builder.CreateBitOrPointerCast( + theFunction, IGF.IGM.TaskContinuationFunctionPtrTy); + theSize = IGF.Builder.CreateZExtOrBitCast(theSize, IGF.IGM.SizeTy); + if (futureResultType) { + result = IGF.Builder.CreateCall( + IGF.IGM.getTaskCreateFutureFuncFn(), + { flags, parentTask, futureResultType, theFunction, theSize }); + } else { + result = IGF.Builder.CreateCall(IGF.IGM.getTaskCreateFuncFn(), + {flags, parentTask, theFunction, theSize}); + } result->setDoesNotThrow(); result->setCallingConv(IGF.IGM.SwiftCC); // Write the local context information into the initial context for the task. - if (layout.hasLocalContext()) { - // Dig out the initial context returned from task creation. - auto initialContext = IGF.Builder.CreateExtractValue(result, { 1 }); - Address initialContextAddr = layout.emitCastTo(IGF, initialContext); - - auto localContextLayout = layout.getLocalContextLayout(); - auto localContextAddr = localContextLayout.project( - IGF, initialContextAddr, llvm::None); - IGF.Builder.CreateStore(localContextInfo, localContextAddr); - } + assert(layout.hasLocalContext()); + // Dig out the initial context returned from task creation. + auto initialContext = IGF.Builder.CreateExtractValue(result, {1}); + Address initialContextAddr = layout.emitCastTo(IGF, initialContext); + + auto localContextLayout = layout.getLocalContextLayout(); + auto localContextAddr = + localContextLayout.project(IGF, initialContextAddr, llvm::None); + IGF.Builder.CreateStore(localContextInfo, localContextAddr); return result; } diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index bf3b63b0bc545..cda8bcdf3d265 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -81,8 +81,8 @@ namespace irgen { // }; // ResultTypes directResults...; // }; + // SelfType self; // ArgTypes formalArguments...; - // SelfType self?; // }; struct AsyncContextLayout : StructLayout { struct ArgumentInfo { @@ -177,7 +177,14 @@ namespace irgen { return getIndexAfterDirectReturns(); } } - unsigned getFirstArgumentIndex() { return getIndexAfterUnion(); } + unsigned getLocalContextIndex() { + assert(hasLocalContext()); + return getIndexAfterUnion(); + } + unsigned getIndexAfterLocalContext() { + return getIndexAfterUnion() + (hasLocalContext() ? 1 : 0); + } + unsigned getFirstArgumentIndex() { return getIndexAfterLocalContext(); } unsigned getIndexAfterArguments() { return getFirstArgumentIndex() + getArgumentCount(); } @@ -188,24 +195,16 @@ namespace irgen { unsigned getIndexAfterBindings() { return getIndexAfterArguments() + (hasBindings() ? 1 : 0); } - unsigned getLocalContextIndex() { - assert(hasLocalContext()); - return getIndexAfterBindings(); - } - unsigned getIndexAfterLocalContext() { - return getIndexAfterBindings() + - (hasLocalContext() ? 1 : 0); - } unsigned getSelfMetadataIndex() { assert(hasTrailingWitnesses()); - return getIndexAfterLocalContext(); + return getIndexAfterBindings(); } unsigned getSelfWitnessTableIndex() { assert(hasTrailingWitnesses()); - return getIndexAfterLocalContext() + 1; + return getIndexAfterBindings() + 1; } unsigned getIndexAfterTrailingWitnesses() { - return getIndexAfterLocalContext() + (hasTrailingWitnesses() ? 2 : 0); + return getIndexAfterBindings() + (hasTrailingWitnesses() ? 2 : 0); } public: @@ -399,11 +398,16 @@ namespace irgen { void emitTaskCancel(IRGenFunction &IGF, llvm::Value *task); - /// Emit a class to swift_task_create[_f] with the given flags, parent task, - /// and task function. + /// Emit a class to swift_task_create[_f] or swift_task_create_future[__f] + /// with the given flags, parent task, and task function. + /// + /// When \c futureResultType is non-null, calls the future variant to create + /// a future. llvm::Value *emitTaskCreate( IRGenFunction &IGF, llvm::Value *flags, llvm::Value *parentTask, - llvm::Value *taskFunction, llvm::Value *localContextInfo); + llvm::Value *futureResultType, + llvm::Value *taskFunction, llvm::Value *localContextInfo, + SubstitutionMap subs); /// Allocate task local storage for the provided dynamic size. Address emitAllocAsyncContext(IRGenFunction &IGF, llvm::Value *sizeValue); diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 87aaf5fb3f40f..a103fb0dc1d27 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -2144,13 +2144,17 @@ static llvm::Function *emitObjCMetadataUpdateFunction(IRGenModule &IGM, /// ancestry. This lets us attach categories to the class even though it /// does not have statically-emitted metadata. bool IRGenModule::hasObjCResilientClassStub(ClassDecl *D) { - assert(getClassMetadataStrategy(D) == ClassMetadataStrategy::Resilient); +#ifndef NDEBUG + auto strategy = getClassMetadataStrategy(D); + assert(strategy == ClassMetadataStrategy::Resilient || + strategy == ClassMetadataStrategy::Singleton); +#endif + return ObjCInterop && !D->isGenericContext(); } -void IRGenModule::emitObjCResilientClassStub(ClassDecl *D) { - assert(hasObjCResilientClassStub(D)); - +llvm::Constant *IRGenModule::emitObjCResilientClassStub( + ClassDecl *D, bool isPublic) { ConstantInitBuilder builder(*this); auto fields = builder.beginStruct(ObjCFullResilientClassStubTy); fields.addInt(SizeTy, 0); // reserved @@ -2178,9 +2182,13 @@ void IRGenModule::emitObjCResilientClassStub(ClassDecl *D) { objcStub = llvm::ConstantExpr::getPointerCast(objcStub, ObjCResilientClassStubTy->getPointerTo()); - entity = LinkEntity::forObjCResilientClassStub( - D, TypeMetadataAddress::AddressPoint); - defineAlias(entity, objcStub); + if (isPublic) { + entity = LinkEntity::forObjCResilientClassStub( + D, TypeMetadataAddress::AddressPoint); + defineAlias(entity, objcStub); + } + + return objcStub; } static llvm::Constant *doEmitClassPrivateData( diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 40a1fd9dfc573..c430c140c8eae 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -1019,7 +1019,6 @@ class AsyncPartialApplicationForwarderEmission llvm::Value *contextBuffer; Size contextSize; Address context; - llvm::Value *heapContextBuffer; unsigned currentArgumentIndex; struct DynamicFunction { using Kind = DynamicFunctionKind; @@ -1072,13 +1071,13 @@ class AsyncPartialApplicationForwarderEmission task = origParams.claimNext(); executor = origParams.claimNext(); contextBuffer = origParams.claimNext(); - heapContextBuffer = origParams.claimNext(); } void begin() override { super::begin(); + assert(task); + assert(executor); assert(contextBuffer); - assert(heapContextBuffer); context = layout.emitCastTo(subIGF, contextBuffer); } bool transformArgumentToNative(SILParameterInfo origParamInfo, Explosion &in, @@ -1125,7 +1124,9 @@ class AsyncPartialApplicationForwarderEmission SILParameterInfo getParameterInfo(unsigned index) override { return origType->getParameters()[index]; } - llvm::Value *getContext() override { return heapContextBuffer; } + llvm::Value *getContext() override { + return loadValue(layout.getLocalContextLayout()); + } llvm::Value *getDynamicFunctionPointer() override { assert(dynamicFunction && dynamicFunction->pointer); auto *context = dynamicFunction->context; @@ -1248,8 +1249,15 @@ class AsyncPartialApplicationForwarderEmission asyncExplosion.add(contextBuffer); if (dynamicFunction && dynamicFunction->kind == DynamicFunction::Kind::PartialApply) { + // Just before making the call, replace the old thick context with the + // new thick context so that (1) the new thick context is never used by + // this partial apply forwarder and (2) the old thick context is never + // used by the callee partial apply forwarder. assert(dynamicFunction->context); - asyncExplosion.add(dynamicFunction->context); + auto fieldLayout = layout.getLocalContextLayout(); + Explosion explosion; + explosion.add(dynamicFunction->context); + saveValue(fieldLayout, explosion); } return subIGF.Builder.CreateCall(fnPtr.getAsFunction(subIGF), @@ -1766,7 +1774,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, } // Pass a placeholder for thin function calls. - } else if (origType->hasErrorResult()) { + } else if (origType->hasErrorResult() && !origType->isAsync()) { emission->addArgument(llvm::UndefValue::get(IGM.RefCountedPtrTy)); } diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index ff00733b9c922..fa61fe002d619 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -3794,23 +3794,44 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl, if (IGM.ObjCInterop) { switch (strategy) { case ClassMetadataStrategy::Resilient: - // Even non-@objc classes can have Objective-C categories attached, so - // we always emit a resilient class stub as long as -enable-objc-interop - // is set. + // We always emit a resilient class stub as long as -enable-objc-interop + // is set. You can define @objc members in an extension of a resilient + // class across a module boundary, and this category is attached to the + // class stub. if (IGM.hasObjCResilientClassStub(classDecl)) { - IGM.emitObjCResilientClassStub(classDecl); + auto *stub = IGM.emitObjCResilientClassStub( + classDecl, /*isPublic=*/true); - if (classDecl->isObjC()) { - auto *stub = IGM.getAddrOfObjCResilientClassStub( - classDecl, NotForDefinition, - TypeMetadataAddress::AddressPoint); + // If the class has Objective-C ancestry but does *not* have generic + // ancestry, it appears in the generated header. We emit an Objective-C + // class symbol aliased to the class stub for Clang to reference. + if (classDecl->isObjC()) emitObjCClassSymbol(IGM, classDecl, stub); + // Note that if the class has generic ancestry, isObjC() is false. + // This is because such classes cannot appear in the generated header, + // because their generic superclasses cannot appear in the generated + // header either. However, we still want to emit the class stub in + // the __objc_stublist section of the binary, so that they are visited + // by objc_copyClassList(). + if (classDecl->checkAncestry(AncestryFlags::ObjC)) IGM.addObjCClassStub(stub); - } } break; + case ClassMetadataStrategy::Singleton: + // If the class has Objective-C ancestry, we emit the class stub and + // add it to the __obj_stublist. Note that the stub is not public in + // this case, since there is no reason to reference directly; it only + // exists so that objc_copyClassList() can find it. + if (IGM.hasObjCResilientClassStub(classDecl)) { + if (classDecl->checkAncestry(AncestryFlags::ObjC)) { + auto *stub = IGM.emitObjCResilientClassStub( + classDecl, /*isPublic=*/false); + IGM.addObjCClassStub(stub); + } + } + break; case ClassMetadataStrategy::Update: @@ -3820,7 +3841,7 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl, emitObjCClassSymbol(IGM, classDecl, var); IGM.addObjCClass(var, - classDecl->getAttrs().hasAttribute()); + classDecl->getAttrs().hasAttribute()); break; } } diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index af2ca7f5208e7..570dd528015bf 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -1085,8 +1085,6 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM, std::string encodingString; - auto fnClangTy = fnType->getClangTypeInfo().getType(); - // Return type. { auto clangType = IGM.getClangType(resultType.getASTType()); diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp index 48b75e473a0f8..f7456162291e5 100644 --- a/lib/IRGen/GenOpaque.cpp +++ b/lib/IRGen/GenOpaque.cpp @@ -545,6 +545,9 @@ StackAddress IRGenFunction::emitDynamicAlloca(llvm::Type *eltTy, } else { byteCount = Builder.CreateMul(arraySize, IGM.getSize(Size(eltSize))); } + // The task allocator wants size increments in the mulitple of + // MaximumAlignment. + byteCount = alignUpToMaximumAlignment(IGM.SizeTy, byteCount); auto address = emitTaskAlloc(byteCount, align); return {address, address.getAddress()}; // In coroutines, call llvm.coro.alloca.alloc. diff --git a/lib/IRGen/IRGenFunction.cpp b/lib/IRGen/IRGenFunction.cpp index e6cbbeac8a263..ecab8bdf4e423 100644 --- a/lib/IRGen/IRGenFunction.cpp +++ b/lib/IRGen/IRGenFunction.cpp @@ -14,7 +14,7 @@ // performs IR generation for function bodies. // //===----------------------------------------------------------------------===// - +#include "swift/ABI/MetadataValues.h" #include "swift/AST/IRGenOptions.h" #include "swift/Basic/SourceLoc.h" #include "swift/IRGen/Linking.h" @@ -507,3 +507,9 @@ void IRGenFunction::emitTaskDealloc(Address address) { call->setDoesNotThrow(); call->setCallingConv(IGM.SwiftCC); } + +llvm::Value *IRGenFunction::alignUpToMaximumAlignment(llvm::Type *sizeTy, llvm::Value *val) { + auto *alignMask = llvm::ConstantInt::get(sizeTy, MaximumAlignment - 1); + auto *invertedMask = Builder.CreateNot(alignMask); + return Builder.CreateAnd(Builder.CreateAdd(val, alignMask), invertedMask); +} diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index ea6de515dbf93..5f96c684379bc 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -460,6 +460,8 @@ class IRGenFunction { Alignment alignment); void emitTaskDealloc(Address address); + llvm::Value *alignUpToMaximumAlignment(llvm::Type *sizeTy, llvm::Value *val); + //--- Expression emission //------------------------------------------------------ public: diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index b3a41840e387d..8f535746af5b3 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -1636,7 +1636,7 @@ private: \ bool hasObjCResilientClassStub(ClassDecl *D); /// Emit a resilient class stub. - void emitObjCResilientClassStub(ClassDecl *D); + llvm::Constant *emitObjCResilientClassStub(ClassDecl *D, bool isPublic); private: llvm::Constant * diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index fb0aa07479832..37da8e13c7b0b 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -1754,9 +1754,12 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, // Even if we don't have a 'self', if we have an error result, we // should have a placeholder argument here. - } else if (funcTy->hasErrorResult() || - funcTy->getRepresentation() == SILFunctionTypeRepresentation::Thick) - { + // + // For async functions, there will be a thick context within the async + // context whenever there is no self context. + } else if (funcTy->isAsync() || funcTy->hasErrorResult() || + funcTy->getRepresentation() == + SILFunctionTypeRepresentation::Thick) { llvm::Value *contextPtr = emission->getContext(); (void)contextPtr; assert(contextPtr->getType() == IGF.IGM.RefCountedPtrTy); @@ -4627,6 +4630,17 @@ void IRGenSILFunction::visitIsEscapingClosureInst( setLoweredExplosion(i, out); } +static bool isCallToSwiftTaskAlloc(llvm::Value *val) { + auto *call = dyn_cast(val); + if (!call) + return false; + auto *callee = call->getCalledFunction(); + if (!callee) + return false; + auto isTaskAlloc = callee->getName().equals("swift_task_alloc"); + return isTaskAlloc; +} + void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i, const TypeInfo &type, llvm::Value *addr) { @@ -4644,6 +4658,11 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i, else if (auto *CoroAllocaGet = dyn_cast(Op0)) { if (CoroAllocaGet->getIntrinsicID() == llvm::Intrinsic::coro_alloca_get) addr = CoroAllocaGet; + } else if (auto *call = dyn_cast(Op0)) { + addr = call; + bool isTaskAlloc = isCallToSwiftTaskAlloc(call); + assert(isTaskAlloc && "expecting call to swift_task_alloc"); + (void)isTaskAlloc; } } @@ -4659,7 +4678,7 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i, // At this point addr must be an alloca or an undef. assert(isa(addr) || isa(addr) || - isa(addr)); + isa(addr) || isCallToSwiftTaskAlloc(addr)); auto Indirection = DirectValue; if (!IGM.IRGen.Opts.DisableDebuggerShadowCopies && diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt index 550af6bf5954a..c9759508cabc0 100644 --- a/lib/Parse/CMakeLists.txt +++ b/lib/Parse/CMakeLists.txt @@ -22,7 +22,6 @@ add_swift_host_library(swiftParse STATIC ParseStmt.cpp ParseType.cpp PersistentParserState.cpp - Scope.cpp SyntaxParsingCache.cpp SyntaxParsingContext.cpp) _swift_gyb_target_sources(swiftParse PRIVATE diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 424769d1f15c0..dea3b0fc6e87a 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -717,13 +717,12 @@ bool Parser::parseSpecializeAttributeArguments( // Parse the where clause. if (Tok.is(tok::kw_where)) { - SourceLoc whereLoc; + SourceLoc whereLoc, endLoc; SmallVector requirements; - bool firstTypeInComplete; - parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete, + parseGenericWhereClause(whereLoc, endLoc, requirements, /* AllowLayoutConstraints */ true); TrailingWhereClause = - TrailingWhereClause::create(Context, whereLoc, requirements); + TrailingWhereClause::create(Context, whereLoc, endLoc, requirements); } return true; } @@ -1053,12 +1052,12 @@ bool Parser::parseDifferentiableAttributeArguments( // Parse a trailing 'where' clause if any. if (Tok.is(tok::kw_where)) { - SourceLoc whereLoc; + SourceLoc whereLoc, endLoc; SmallVector requirements; - bool firstTypeInComplete; - parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete, + parseGenericWhereClause(whereLoc, endLoc, requirements, /*AllowLayoutConstraints*/ true); - whereClause = TrailingWhereClause::create(Context, whereLoc, requirements); + whereClause = + TrailingWhereClause::create(Context, whereLoc, endLoc, requirements); } return false; } @@ -3813,7 +3812,7 @@ void Parser::setLocalDiscriminator(ValueDecl *D) { return; if (auto TD = dyn_cast(D)) - if (!getScopeInfo().isInactiveConfigBlock()) + if (!InInactiveClauseEnvironment) SF.LocalTypeDecls.insert(TD); const Identifier name = D->getBaseIdentifier(); @@ -3869,11 +3868,6 @@ Parser::parseDecl(ParseDeclOptions Flags, if (Tok.is(tok::pound_if)) { auto IfConfigResult = parseIfConfig( [&](SmallVectorImpl &Decls, bool IsActive) { - Optional scope; - if (!IsActive) - scope.emplace(this, getScopeInfo().getCurrentScope()->getKind(), - /*inactiveConfigBlock=*/true); - ParserStatus Status; bool PreviousHadSemi = true; SyntaxParsingContext DeclListCtx(SyntaxContext, @@ -4286,20 +4280,6 @@ static Parser::ParseDeclOptions getMemberParseDeclOptions( } } -static ScopeKind getMemberParseScopeKind(IterableDeclContext *idc) { - auto decl = idc->getDecl(); - switch (decl->getKind()) { - case DeclKind::Extension: return ScopeKind::Extension; - case DeclKind::Enum: return ScopeKind::EnumBody; - case DeclKind::Protocol: return ScopeKind::ProtocolBody; - case DeclKind::Class: return ScopeKind::ClassBody; - case DeclKind::Struct: return ScopeKind::StructBody; - - default: - llvm_unreachable("Bad iterable decl context kinds."); - } -} - std::pair, Optional> Parser::parseDeclListDelayed(IterableDeclContext *IDC) { Decl *D = const_cast(IDC->getDecl()); @@ -4343,12 +4323,6 @@ Parser::parseDeclListDelayed(IterableDeclContext *IDC) { if (!Tok.is(tok::l_brace)) return {std::vector(), None}; - // Re-enter the lexical scope. The top-level scope is needed because - // delayed parsing of members happens with a fresh parser, where there is - // no context. - Scope TopLevelScope(this, ScopeKind::TopLevel); - - Scope S(this, getMemberParseScopeKind(IDC)); ContextChange CC(*this, DC); SourceLoc LBLoc = consumeToken(tok::l_brace); (void)LBLoc; @@ -4492,7 +4466,6 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl &Inherited, SyntaxParsingContext InheritanceContext(SyntaxContext, SyntaxKind::TypeInheritanceClause); - Scope S(this, ScopeKind::InheritanceClause); consumeToken(tok::colon); SyntaxParsingContext TypeListContext(SyntaxContext, @@ -4878,19 +4851,17 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) { TrailingWhereClause *trailingWhereClause = nullptr; bool trailingWhereHadCodeCompletion = false; if (Tok.is(tok::kw_where)) { - SourceLoc whereLoc; + SourceLoc whereLoc, endLoc; SmallVector requirements; - bool firstTypeInComplete; - auto whereStatus = parseGenericWhereClause(whereLoc, requirements, - firstTypeInComplete); + auto whereStatus = parseGenericWhereClause(whereLoc, endLoc, requirements); if (whereStatus.hasCodeCompletion()) { if (isCodeCompletionFirstPass()) return whereStatus; trailingWhereHadCodeCompletion = true; } if (!requirements.empty()) { - trailingWhereClause = TrailingWhereClause::create(Context, whereLoc, - requirements); + trailingWhereClause = + TrailingWhereClause::create(Context, whereLoc, endLoc, requirements); } status |= whereStatus; } @@ -4909,7 +4880,6 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) { { ContextChange CC(*this, ext); - Scope S(this, ScopeKind::Extension); if (parseMemberDeclList(LBLoc, RBLoc, diag::expected_lbrace_extension, @@ -5190,9 +5160,6 @@ parseDeclTypeAlias(Parser::ParseDeclOptions Flags, DeclAttributes &Attributes) { DebuggerContextChange DCC(*this, Id, DeclKind::TypeAlias); - Optional GenericsScope; - GenericsScope.emplace(this, ScopeKind::Generics); - // Parse a generic parameter list if it is present. GenericParamList *genericParams = nullptr; if (startsWithLess(Tok)) { @@ -5266,10 +5233,6 @@ parseDeclTypeAlias(Parser::ParseDeclOptions Flags, DeclAttributes &Attributes) { } } - // Exit the scope introduced for the generic parameters. - GenericsScope.reset(); - - addToScope(TAD); return DCC.fixupParserResult(Status, TAD); } @@ -5307,10 +5270,6 @@ ParserResult Parser::parseDeclAssociatedType(Parser::ParseDeclOptions // Reject generic parameters with a specific error. if (startsWithLess(Tok)) { - // Introduce a throwaway scope to capture the generic parameters. We - // don't want them visible anywhere! - Scope S(this, ScopeKind::Generics); - if (auto genericParams = parseGenericParameters().getPtrOrNull()) { diagnose(genericParams->getLAngleLoc(), diag::associated_type_generic_parameter_list) @@ -5362,7 +5321,6 @@ ParserResult Parser::parseDeclAssociatedType(Parser::ParseDeclOptions assocType->getAttrs() = Attributes; if (!Inherited.empty()) assocType->setInherited(Context.AllocateCopy(Inherited)); - addToScope(assocType); return makeParserResult(Status, assocType); } @@ -5547,10 +5505,6 @@ void Parser::skipSILUntilSwiftDecl() { // Tell the lexer we're about to start lexing SIL. Lexer::SILBodyRAII sbr(*L); - // Enter a top-level scope. This is necessary as parseType may need to setup - // child scopes for generic params. - Scope topLevel(this, ScopeKind::TopLevel); - while (!Tok.is(tok::eof) && !isStartOfSwiftDecl()) { // SIL pound dotted paths need to be skipped specially as they can contain // decl keywords like 'subscript'. @@ -6286,20 +6240,6 @@ Parser::parseDeclVar(ParseDeclOptions Flags, // into (should we have one). This happens for properties and global // variables in libraries. - // Record the variables that we're trying to initialize. This allows us - // to cleanly reject "var x = x" when "x" isn't bound to an enclosing - // decl (even though names aren't injected into scope when the initializer - // is parsed). - SmallVector Vars; - Vars.append(DisabledVars.begin(), DisabledVars.end()); - pattern->collectVariables(Vars); - - llvm::SaveAndRestore - RestoreCurVars(DisabledVars, Vars); - - llvm::SaveAndRestore - RestoreReason(DisabledVarReason, diag::var_init_self_referential); - // If we have no local context to parse the initial value into, create one // for the PBD we'll eventually create. This allows us to have reasonable // DeclContexts for any closures that may live inside of initializers. @@ -6372,9 +6312,6 @@ Parser::parseDeclVar(ParseDeclOptions Flags, return makeResult(makeParserCodeCompletionStatus()); } - // Add all parsed vardecls to this scope. - addPatternVariablesToScope(pattern); - // Propagate back types for simple patterns, like "var A, B : T". if (auto *TP = dyn_cast(pattern)) { if (isa(TP->getSubPattern()) && PatternInit == nullptr) { @@ -6537,8 +6474,6 @@ ParserResult Parser::parseDeclFunc(SourceLoc StaticLoc, DebuggerContextChange DCC(*this, SimpleName, DeclKind::Func); // Parse the generic-params, if present. - Optional GenericsScope; - GenericsScope.emplace(this, ScopeKind::Generics); GenericParamList *GenericParams; auto GenericParamResult = maybeParseGenericParams(); GenericParams = GenericParamResult.getPtrOrNull(); @@ -6640,10 +6575,6 @@ ParserResult Parser::parseDeclFunc(SourceLoc StaticLoc, parseAbstractFunctionBody(FD); } - // Exit the scope introduced for the generic parameters. - GenericsScope.reset(); - - addToScope(FD); return DCC.fixupParserResult(FD); } @@ -6652,14 +6583,7 @@ ParserResult Parser::parseDeclFunc(SourceLoc StaticLoc, BraceStmt *Parser::parseAbstractFunctionBodyImpl(AbstractFunctionDecl *AFD) { assert(Tok.is(tok::l_brace)); - // Enter the arguments for the function into a new function-body scope. We - // need this even if there is no function body to detect argument name - // duplication. - if (auto *P = AFD->getImplicitSelfDecl()) - addToScope(P); - addParametersToScope(AFD->getParameters()); - - // Establish the new context. + // Establish the new context. ParseFunctionBody CC(*this, AFD); setLocalDiscriminatorToParamList(AFD->getParameters()); @@ -6757,7 +6681,6 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) { return; } - Scope S(this, ScopeKind::FunctionBody); (void)parseAbstractFunctionBodyImpl(AFD); } @@ -6786,10 +6709,6 @@ BraceStmt *Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) { // Rewind to '{' of the function body. restoreParserPosition(BeginParserPosition); - // Re-enter the lexical scope. - Scope TopLevelScope(this, ScopeKind::TopLevel); - Scope S(this, ScopeKind::FunctionBody); - return parseAbstractFunctionBodyImpl(AFD); } @@ -6823,7 +6742,6 @@ ParserResult Parser::parseDeclEnum(ParseDeclOptions Flags, // Parse the generic-params, if present. GenericParamList *GenericParams = nullptr; { - Scope S(this, ScopeKind::Generics); auto Result = maybeParseGenericParams(); GenericParams = Result.getPtrOrNull(); if (Result.hasCodeCompletion()) @@ -6861,8 +6779,6 @@ ParserResult Parser::parseDeclEnum(ParseDeclOptions Flags, SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock); SourceLoc LBLoc, RBLoc; { - Scope S(this, ScopeKind::EnumBody); - if (parseMemberDeclList(LBLoc, RBLoc, diag::expected_lbrace_enum, diag::expected_rbrace_enum, @@ -6872,8 +6788,6 @@ ParserResult Parser::parseDeclEnum(ParseDeclOptions Flags, ED->setBraces({LBLoc, RBLoc}); - addToScope(ED); - return DCC.fixupParserResult(Status, ED); } @@ -7100,7 +7014,6 @@ ParserResult Parser::parseDeclStruct(ParseDeclOptions Flags, // Parse the generic-params, if present. GenericParamList *GenericParams = nullptr; { - Scope S(this, ScopeKind::Generics); auto Result = maybeParseGenericParams(); GenericParams = Result.getPtrOrNull(); if (Result.hasCodeCompletion()) @@ -7143,8 +7056,6 @@ ParserResult Parser::parseDeclStruct(ParseDeclOptions Flags, SourceLoc LBLoc, RBLoc; { // Parse the body. - Scope S(this, ScopeKind::StructBody); - if (parseMemberDeclList(LBLoc, RBLoc, diag::expected_lbrace_struct, diag::expected_rbrace_struct, @@ -7154,8 +7065,6 @@ ParserResult Parser::parseDeclStruct(ParseDeclOptions Flags, SD->setBraces({LBLoc, RBLoc}); - addToScope(SD); - return DCC.fixupParserResult(Status, SD); } @@ -7188,7 +7097,6 @@ ParserResult Parser::parseDeclClass(ParseDeclOptions Flags, // Parse the generic-params, if present. GenericParamList *GenericParams = nullptr; { - Scope S(this, ScopeKind::Generics); auto Result = maybeParseGenericParams(); GenericParams = Result.getPtrOrNull(); if (Result.hasCodeCompletion()) @@ -7254,8 +7162,6 @@ ParserResult Parser::parseDeclClass(ParseDeclOptions Flags, SourceLoc LBLoc, RBLoc; { // Parse the body. - Scope S(this, ScopeKind::ClassBody); - if (parseMemberDeclList(LBLoc, RBLoc, diag::expected_lbrace_class, diag::expected_rbrace_class, @@ -7265,8 +7171,6 @@ ParserResult Parser::parseDeclClass(ParseDeclOptions Flags, CD->setBraces({LBLoc, RBLoc}); - addToScope(CD); - return DCC.fixupParserResult(Status, CD); } @@ -7303,7 +7207,6 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) { // produce a specific diagnostic if present. if (startsWithLess(Tok)) { diagnose(Tok, diag::generic_arguments_protocol); - Scope S(this, ScopeKind::Generics); maybeParseGenericParams(); } @@ -7342,7 +7245,6 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) { CodeCompletion->setParsedDecl(Proto); ContextChange CC(*this, Proto); - Scope ProtocolBodyScope(this, ScopeKind::ProtocolBody); // Parse the body. { @@ -7406,8 +7308,6 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc, } // Parse the generic-params, if present. - Optional GenericsScope; - GenericsScope.emplace(this, ScopeKind::Generics); GenericParamList *GenericParams; auto Result = maybeParseGenericParams(); @@ -7576,7 +7476,6 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) { } // Parse the generic-params, if present. - Scope S(this, ScopeKind::Generics); auto GPResult = maybeParseGenericParams(); GenericParamList *GenericParams = GPResult.getPtrOrNull(); if (GPResult.hasCodeCompletion()) { diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 76b4f9fc051ea..3d62d971408b7 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1958,7 +1958,6 @@ ParserResult Parser::parseExprStringLiteral() { ParserStatus Status; { - Scope S(this, ScopeKind::Brace); SmallVector Stmts; // Make the variable which will contain our temporary value. @@ -1968,7 +1967,6 @@ ParserResult Parser::parseExprStringLiteral() { Context.Id_dollarInterpolation, CurDeclContext); InterpolationVar->setImplicit(true); InterpolationVar->setUserAccessible(false); - addToScope(InterpolationVar); setLocalDiscriminator(InterpolationVar); Stmts.push_back(InterpolationVar); @@ -2203,54 +2201,13 @@ Expr *Parser::parseExprIdentifier() { hasGenericArgumentList = !args.empty(); } - ValueDecl *D = nullptr; - // When doing incremental re-parsing for SwiftSyntax this check may emit bogus - // diagnostic. Also really the syntactic parser should not be doing name - // lookups, so disable this check when parsing for SwiftSyntax. - if (!InPoundIfEnvironment && !Context.LangOpts.ParseForSyntaxTreeOnly) { - D = lookupInScope(name); - - 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()); - } - } - } - } - } - - Expr *E; - if (D == nullptr || D->getAttrs().hasAttribute()) { - if (name.getBaseName().isEditorPlaceholder()) { - IDSyntaxContext.setCreateSyntax(SyntaxKind::EditorPlaceholderExpr); - return parseExprEditorPlaceholder(IdentTok, name.getBaseIdentifier()); - } - - auto refKind = DeclRefKind::Ordinary; - E = new (Context) UnresolvedDeclRefExpr(name, refKind, loc); - } else if (auto TD = dyn_cast(D)) { - // When parsing default argument expressions for generic functions, - // we haven't built a FuncDecl or re-parented the GenericTypeParamDecls - // to the FuncDecl yet. Other than that, we should only ever find - // global or local declarations here. - assert(!TD->getDeclContext()->isTypeContext() || - isa(TD)); - E = TypeExpr::createForDecl(loc, TD, /*DC*/ nullptr); - } else { - E = new (Context) DeclRefExpr(D, loc, /*Implicit=*/false); + if (name.getBaseName().isEditorPlaceholder()) { + IDSyntaxContext.setCreateSyntax(SyntaxKind::EditorPlaceholderExpr); + return parseExprEditorPlaceholder(IdentTok, name.getBaseIdentifier()); } + + auto refKind = DeclRefKind::Ordinary; + Expr *E = new (Context) UnresolvedDeclRefExpr(name, refKind, loc); if (hasGenericArgumentList) { E = UnresolvedSpecializeExpr::create(Context, E, LAngleLoc, args, @@ -2773,14 +2730,10 @@ ParserResult Parser::parseExprClosure() { auto *closure = new (Context) ClosureExpr( bracketRange, capturedSelfDecl, params, asyncLoc, throwsLoc, arrowLoc, inLoc, explicitResultType, discriminator, CurDeclContext); - // The arguments to the func are defined in their own scope. - Scope S(this, ScopeKind::ClosureParams); ParseFunctionBody cc(*this, closure); // Handle parameters. if (params) { - // Add the parameters into scope. - addParametersToScope(params); setLocalDiscriminatorToParamList(params); } else { // There are no parameters; allow anonymous closure variables. @@ -2789,10 +2742,6 @@ ParserResult Parser::parseExprClosure() { // users who are refactoring code by adding names. AnonClosureVars.push_back({{}, leftBrace}); } - - // Add capture list variables to scope. - for (auto c : captureList) - addToScope(c.Var); // Parse the body. SmallVector bodyElements; @@ -3646,23 +3595,6 @@ void Parser::validateCollectionElement(ParserResult element) { } } -void Parser::addPatternVariablesToScope(ArrayRef Patterns) { - for (Pattern *Pat : Patterns) { - Pat->forEachVariable([&](VarDecl *VD) { - if (VD->hasName()) { - // Add any variable declarations to the current scope. - addToScope(VD); - } - }); - } -} - -void Parser::addParametersToScope(ParameterList *PL) { - for (auto param : *PL) - if (param->hasName()) - addToScope(param); -} - /// Parse availability query specification. diff --git a/lib/Parse/ParseGeneric.cpp b/lib/Parse/ParseGeneric.cpp index 969635bdd3cb6..c0095cc656ab7 100644 --- a/lib/Parse/ParseGeneric.cpp +++ b/lib/Parse/ParseGeneric.cpp @@ -117,9 +117,6 @@ Parser::parseGenericParametersBeforeWhere(SourceLoc LAngleLoc, // Attach attributes. Param->getAttrs() = attributes; - // Add this parameter to the scope. - addToScope(Param); - // Parse the comma, if the list continues. HasNextParam = consumeIf(tok::comma); } while (HasNextParam); @@ -140,11 +137,11 @@ Parser::parseGenericParameters(SourceLoc LAngleLoc) { // Parse the optional where-clause. SourceLoc WhereLoc; + SourceLoc EndLoc; SmallVector Requirements; - bool FirstTypeInComplete; if (Tok.is(tok::kw_where) && - parseGenericWhereClause(WhereLoc, Requirements, - FirstTypeInComplete).isErrorOrHasCompletion()) { + parseGenericWhereClause(WhereLoc, EndLoc, Requirements) + .isErrorOrHasCompletion()) { Invalid = true; } @@ -261,16 +258,14 @@ Parser::diagnoseWhereClauseInGenericParamList(const GenericParamList * /// same-type-requirement: /// type-identifier '==' type ParserStatus Parser::parseGenericWhereClause( - SourceLoc &WhereLoc, + SourceLoc &WhereLoc, SourceLoc &EndLoc, SmallVectorImpl &Requirements, - bool &FirstTypeInComplete, bool AllowLayoutConstraints) { SyntaxParsingContext ClauseContext(SyntaxContext, SyntaxKind::GenericWhereClause); ParserStatus Status; // Parse the 'where'. WhereLoc = consumeToken(tok::kw_where); - FirstTypeInComplete = false; SyntaxParsingContext ReqListContext(SyntaxContext, SyntaxKind::GenericRequirementList); bool HasNextReq; @@ -283,7 +278,7 @@ ParserStatus Parser::parseGenericWhereClause( if (Tok.is(tok::code_complete)) { if (CodeCompletion) CodeCompletion->completeGenericRequirement(); - consumeToken(tok::code_complete); + EndLoc = consumeToken(tok::code_complete); Status.setHasCodeCompletionAndIsError(); break; } @@ -295,7 +290,6 @@ ParserStatus Parser::parseGenericWhereClause( if (FirstType.hasCodeCompletion()) { BodyContext->setTransparent(); Status.setHasCodeCompletionAndIsError(); - FirstTypeInComplete = true; } if (FirstType.isNull()) { @@ -383,8 +377,10 @@ ParserStatus Parser::parseGenericWhereClause( } } while (HasNextReq); - if (Requirements.empty()) - WhereLoc = SourceLoc(); + if (!Requirements.empty()) + EndLoc = Requirements.back().getSourceRange().End; + else if (EndLoc.isInvalid()) + EndLoc = WhereLoc; return Status; } @@ -396,31 +392,26 @@ parseFreestandingGenericWhereClause(GenericContext *genCtx) { assert(Tok.is(tok::kw_where) && "Shouldn't call this without a where"); SmallVector Requirements; - SourceLoc WhereLoc; - bool FirstTypeInComplete; - auto result = parseGenericWhereClause(WhereLoc, Requirements, - FirstTypeInComplete); - if (result.isErrorOrHasCompletion() || Requirements.empty()) - return result; + SourceLoc WhereLoc, EndLoc; + auto result = parseGenericWhereClause(WhereLoc, EndLoc, Requirements); genCtx->setTrailingWhereClause( - TrailingWhereClause::create(Context, WhereLoc, Requirements)); + TrailingWhereClause::create(Context, WhereLoc, EndLoc, Requirements)); - return ParserStatus(); + return result; } /// Parse a where clause after a protocol or associated type declaration. ParserStatus Parser::parseProtocolOrAssociatedTypeWhereClause( TrailingWhereClause *&trailingWhere, bool isProtocol) { assert(Tok.is(tok::kw_where) && "Shouldn't call this without a where"); - SourceLoc whereLoc; + SourceLoc whereLoc, endLoc; SmallVector requirements; - bool firstTypeInComplete; auto whereStatus = - parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete); + parseGenericWhereClause(whereLoc, endLoc, requirements); if (whereStatus.isSuccess() && !whereStatus.hasCodeCompletion()) { trailingWhere = - TrailingWhereClause::create(Context, whereLoc, requirements); + TrailingWhereClause::create(Context, whereLoc, endLoc, requirements); } else if (whereStatus.hasCodeCompletion()) { return whereStatus; } diff --git a/lib/Parse/ParseIfConfig.cpp b/lib/Parse/ParseIfConfig.cpp index 4dd005cb9cef9..f0b97006cd8c1 100644 --- a/lib/Parse/ParseIfConfig.cpp +++ b/lib/Parse/ParseIfConfig.cpp @@ -635,7 +635,7 @@ ParserResult Parser::parseIfConfig( // Don't evaluate if it's in '-parse' mode, etc. shouldEvaluatePoundIfDecls() && // If it's in inactive #if ... #endif block, there's no point to do it. - !getScopeInfo().isInactiveConfigBlock() && + !InInactiveClauseEnvironment && // If this directive contains code completion location, 'isActive' is // determined solely by which block has the completion token. !codeCompletionClauseLoc.isValid(); diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 5da41db1c609b..bcd4464ae7a45 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -289,15 +289,6 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl &Entries, bool isConditionalBlock = isActiveConditionalBlock || ConditionalBlockKind == BraceItemListKind::InactiveConditionalBlock; - // If we're not parsing an active #if block, form a new lexical scope. - Optional initScope; - if (!isActiveConditionalBlock) { - auto scopeKind = IsTopLevel ? ScopeKind::TopLevel : ScopeKind::Brace; - initScope.emplace(this, scopeKind, - ConditionalBlockKind == - BraceItemListKind::InactiveConditionalBlock); - } - ParserStatus BraceItemsStatus; bool PreviousHadSemi = true; @@ -1125,7 +1116,6 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result, // unresolved_pattern_expr nodes, instead of as proper pattern nodes. patternResult.get()->forEachVariable([&](VarDecl *VD) { P.setLocalDiscriminator(VD); - if (VD->hasName()) P.addToScope(VD); boundDecls.push_back(VD); }); @@ -1136,7 +1126,6 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result, // same number and same names in this pattern as were declared in a // previous pattern (and later we will make sure they have the same // types). - Scope guardScope(&P, ScopeKind::CaseVars); SmallVector repeatedDecls; patternResult.get()->forEachVariable([&](VarDecl *VD) { if (!VD->hasName()) @@ -1156,8 +1145,6 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result, } repeatedDecls.push_back(VD); P.setLocalDiscriminator(VD); - if (VD->hasName()) - P.addToScope(VD); }); for (auto previous : boundDecls) { @@ -1594,8 +1581,6 @@ Parser::parseStmtConditionElement(SmallVectorImpl &result, // them as being having a non-pattern-binding initializer. ThePattern.get()->forEachVariable([&](VarDecl *VD) { setLocalDiscriminator(VD); - if (VD->hasName()) - addToScope(VD); }); return Status; } @@ -1691,8 +1676,6 @@ ParserResult Parser::parseStmtIf(LabeledStmtInfo LabelInfo, // A scope encloses the condition and true branch for any variables bound // by a conditional binding. The else branch does *not* see these variables. { - Scope S(this, ScopeKind::IfVars); - auto recoverWithCond = [&](ParserStatus Status, StmtCondition Condition) -> ParserResult { if (Condition.empty()) { @@ -1835,19 +1818,6 @@ ParserResult Parser::parseStmtGuard() { return recoverWithCond(Status, Condition); } - // Before parsing the body, disable all of the bound variables so that they - // cannot be used unbound. - SmallVector Vars; - for (auto &elt : Condition) - if (auto pattern = elt.getPatternOrNull()) - pattern->collectVariables(Vars); - Vars.append(DisabledVars.begin(), DisabledVars.end()); - llvm::SaveAndRestore - RestoreCurVars(DisabledVars, Vars); - - llvm::SaveAndRestore - RestoreReason(DisabledVarReason, diag::bound_var_guard_body); - Body = parseBraceItemList(diag::expected_lbrace_after_guard); if (Body.isNull()) return recoverWithCond(Status, Condition); @@ -1865,8 +1835,6 @@ ParserResult Parser::parseStmtWhile(LabeledStmtInfo LabelInfo) { SyntaxContext->setCreateSyntax(SyntaxKind::WhileStmt); SourceLoc WhileLoc = consumeToken(tok::kw_while); - Scope S(this, ScopeKind::WhileVars); - ParserStatus Status; StmtCondition Condition; @@ -2050,8 +2018,6 @@ ParserResult Parser::parseStmtDo(LabeledStmtInfo labelInfo, ParserResult Parser::parseStmtCatch() { SyntaxParsingContext CatchClauseCtxt(SyntaxContext, SyntaxKind::CatchClause); // A catch block has its own scope for variables bound out of the pattern. - Scope S(this, ScopeKind::CatchVars); - SourceLoc catchLoc = consumeToken(tok::kw_catch); SmallVector boundDecls; @@ -2090,17 +2056,9 @@ ParserResult Parser::parseStmtCatch() { caseBodyDecls.emplace(Result); } - // Add a scope so that the parser can find our body bound decls if it emits - // optimized accesses. - Optional BodyScope; if (caseBodyDecls) { - BodyScope.emplace(this, ScopeKind::CatchVars); for (auto *v : *caseBodyDecls) { setLocalDiscriminator(v); - // If we had any bad redefinitions, we already diagnosed them against the - // first case label item. - if (v->hasName()) - addToScope(v, false /*diagnoseRedefinitions*/); } } @@ -2235,16 +2193,7 @@ ParserResult Parser::parseStmtForEach(LabeledStmtInfo LabelInfo) { // Recover. skipUntilDeclStmtRBrace(tok::l_brace, tok::kw_where); } - - // Introduce a new scope and place the variables in the pattern into that - // scope. - // FIXME: We may want to merge this scope with the scope introduced by - // the stmt-brace, as in C++. - Scope S(this, ScopeKind::ForeachVars); - // Introduce variables to the current scope. - addPatternVariablesToScope(pattern.get()); - // Parse the 'where' expression if present. ParserResult Where; SourceLoc WhereLoc; @@ -2519,8 +2468,6 @@ struct FallthroughFinder : ASTWalker { ParserResult Parser::parseStmtCase(bool IsActive) { SyntaxParsingContext CaseContext(SyntaxContext, SyntaxKind::SwitchCase); - // A case block has its own scope for variables bound out of the pattern. - Scope S(this, ScopeKind::CaseVars, !IsActive); ParserStatus Status; @@ -2571,17 +2518,9 @@ ParserResult Parser::parseStmtCase(bool IsActive) { assert(!CaseLabelItems.empty() && "did not parse any labels?!"); - // Add a scope so that the parser can find our body bound decls if it emits - // optimized accesses. - Optional BodyScope; if (CaseBodyDecls) { - BodyScope.emplace(this, ScopeKind::CaseVars); for (auto *v : *CaseBodyDecls) { setLocalDiscriminator(v); - // If we had any bad redefinitions, we already diagnosed them against the - // first case label item. - if (v->hasName()) - addToScope(v, false /*diagnoseRedefinitions*/); } } diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index cd9ad96813d91..610955149fe77 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -252,8 +252,7 @@ ParserResult Parser::parseType() { } ParserResult Parser::parseSILBoxType(GenericParamList *generics, - const TypeAttributes &attrs, - Optional &GenericsScope) { + const TypeAttributes &attrs) { auto LBraceLoc = consumeToken(tok::l_brace); SmallVector Fields; @@ -286,11 +285,7 @@ ParserResult Parser::parseSILBoxType(GenericParamList *generics, } auto RBraceLoc = consumeToken(tok::r_brace); - - // The generic arguments are taken from the enclosing scope. Pop the - // box layout's scope now. - GenericsScope.reset(); - + SourceLoc LAngleLoc, RAngleLoc; SmallVector Args; if (startsWithLess(Tok)) { @@ -339,28 +334,19 @@ ParserResult Parser::parseType(Diag<> MessageID, TypeAttributes attrs; parseTypeAttributeList(specifier, specifierLoc, attrs); - Optional GenericsScope; - Optional patternGenericsScope; - // Parse generic parameters in SIL mode. GenericParamList *generics = nullptr; SourceLoc substitutedLoc; GenericParamList *patternGenerics = nullptr; if (isInSILMode()) { - // If this is part of a sil function decl, generic parameters are visible in - // the function body; otherwise, they are visible when parsing the type. - if (!IsSILFuncDecl) - GenericsScope.emplace(this, ScopeKind::Generics); generics = maybeParseGenericParams().getPtrOrNull(); if (Tok.is(tok::at_sign) && peekToken().getText() == "substituted") { consumeToken(tok::at_sign); substitutedLoc = consumeToken(tok::identifier); - patternGenericsScope.emplace(this, ScopeKind::Generics); patternGenerics = maybeParseGenericParams().getPtrOrNull(); if (!patternGenerics) { diagnose(Tok.getLoc(), diag::sil_function_subst_expected_generics); - patternGenericsScope.reset(); } } } @@ -369,9 +355,8 @@ ParserResult Parser::parseType(Diag<> MessageID, if (isInSILMode() && Tok.is(tok::l_brace)) { if (patternGenerics) { diagnose(Tok.getLoc(), diag::sil_function_subst_expected_function); - patternGenericsScope.reset(); } - return parseSILBoxType(generics, attrs, GenericsScope); + return parseSILBoxType(generics, attrs); } ParserResult ty = parseTypeSimpleOrComposition(MessageID); @@ -519,10 +504,6 @@ ParserResult Parser::parseType(Diag<> MessageID, // Parse pattern substitutions. These must exist if we had pattern // generics above. if (patternGenerics) { - // These substitutions are outside of the scope of the - // pattern generics. - patternGenericsScope.reset(); - auto result = parseSubstitutions(patternSubsTypes); if (!result || patternSubsTypes.empty()) { diagnose(Tok, diag::sil_function_subst_expected_subs); @@ -533,10 +514,6 @@ ParserResult Parser::parseType(Diag<> MessageID, } if (generics) { - // These substitutions are outside of the scope of the - // invocation generics. - GenericsScope.reset(); - if (auto result = parseSubstitutions(invocationSubsTypes)) if (!*result) return makeParserError(); } @@ -555,8 +532,6 @@ ParserResult Parser::parseType(Diag<> MessageID, // Only function types may be generic. auto brackets = firstGenerics->getSourceRange(); diagnose(brackets.Start, diag::generic_non_function); - GenericsScope.reset(); - patternGenericsScope.reset(); // Forget any generic parameters we saw in the type. class EraseTypeParamWalker : public ASTWalker { @@ -772,12 +747,6 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) { IdentTypeRepr *ITR = nullptr; if (!ComponentsR.empty()) { - // Lookup element #0 through our current scope chains in case it is some - // thing local (this returns null if nothing is found). - if (auto Entry = lookupInScope(ComponentsR[0]->getNameRef())) - if (auto *TD = dyn_cast(Entry)) - ComponentsR[0]->setValue(TD, nullptr); - ITR = IdentTypeRepr::create(Context, ComponentsR); } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 166456285ee3b..a072c64df0bb5 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -159,9 +159,6 @@ void Parser::performCodeCompletionSecondPassImpl( // Set the parser position to the start of the delayed decl or the body. restoreParserPosition(getParserPosition(startLoc, prevLoc)); - // Re-enter the lexical scope. - Scope S(this, info.takeScope()); - DeclContext *DC = info.ParentContext; switch (info.Kind) { diff --git a/lib/Parse/PersistentParserState.cpp b/lib/Parse/PersistentParserState.cpp index 4e4d15e4dd072..680cb6551e0b6 100644 --- a/lib/Parse/PersistentParserState.cpp +++ b/lib/Parse/PersistentParserState.cpp @@ -39,14 +39,12 @@ void PersistentParserState::setCodeCompletionDelayedDeclState( prevOffset = SM.getLocOffsetInBuffer(PreviousLoc, BufferID); CodeCompletionDelayedDeclStat.reset(new CodeCompletionDelayedDeclState( - Kind, Flags, ParentContext, ScopeInfo.saveCurrentScope(), startOffset, - endOffset, prevOffset)); + Kind, Flags, ParentContext, startOffset, endOffset, prevOffset)); } void PersistentParserState::restoreCodeCompletionDelayedDeclState( const CodeCompletionDelayedDeclState &other) { CodeCompletionDelayedDeclStat.reset(new CodeCompletionDelayedDeclState( other.Kind, other.Flags, other.ParentContext, - ScopeInfo.saveCurrentScope(), other.StartOffset, other.EndOffset, - other.PrevOffset)); + other.StartOffset, other.EndOffset, other.PrevOffset)); } diff --git a/lib/Parse/Scope.cpp b/lib/Parse/Scope.cpp deleted file mode 100644 index 23bc6211b78f9..0000000000000 --- a/lib/Parse/Scope.cpp +++ /dev/null @@ -1,180 +0,0 @@ -//===--- Scope.cpp - Scope Implementation ---------------------------------===// -// -// 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 file implements semantic analysis for Swift declarations. -// -//===----------------------------------------------------------------------===// - -#include "swift/Parse/Scope.h" -#include "swift/Parse/Parser.h" -#include "llvm/ADT/Twine.h" - -using namespace swift; - -//===----------------------------------------------------------------------===// -// Scope Implementation -//===----------------------------------------------------------------------===// - -static bool isResolvableScope(ScopeKind SK) { - switch (SK) { - case ScopeKind::Extension: - case ScopeKind::EnumBody: - case ScopeKind::StructBody: - case ScopeKind::ClassBody: - case ScopeKind::ProtocolBody: - case ScopeKind::TopLevel: - case ScopeKind::InheritanceClause: - return false; - case ScopeKind::FunctionBody: - case ScopeKind::Generics: - case ScopeKind::Brace: - case ScopeKind::ForeachVars: - case ScopeKind::ClosureParams: - case ScopeKind::CaseVars: - case ScopeKind::CatchVars: - case ScopeKind::IfVars: - case ScopeKind::WhileVars: - return true; - } - - llvm_unreachable("Unhandled ScopeKind in switch."); -} - -Scope::Scope(Parser *P, ScopeKind SC, bool isInactiveConfigBlock) - : Scope(P->getScopeInfo(), SC, isInactiveConfigBlock) {} - -Scope::Scope(ScopeInfo &SI, ScopeKind SC, bool isInactiveConfigBlock) - : SI(SI), HTScope(SI.HT, SI.CurScope ? &SI.CurScope->HTScope : nullptr), - PrevScope(SI.CurScope), PrevResolvableDepth(SI.ResolvableDepth), Kind(SC), - IsInactiveConfigBlock(isInactiveConfigBlock) { - assert(PrevScope || Kind == ScopeKind::TopLevel); - - if (SI.CurScope) { - Depth = SI.CurScope->Depth + 1; - IsInactiveConfigBlock |= SI.CurScope->IsInactiveConfigBlock; - } else { - Depth = 0; - } - SI.CurScope = this; - if (!isResolvableScope(Kind)) - SI.ResolvableDepth = Depth + 1; -} - -Scope::Scope(Parser *P, SavedScope &&SS): - SI(P->getScopeInfo()), - HTScope(std::move(SS.HTDetachedScope)), - PrevScope(SI.CurScope), - PrevResolvableDepth(SI.ResolvableDepth), - Depth(SS.Depth), - Kind(SS.Kind), - IsInactiveConfigBlock(SS.IsInactiveConfigBlock) { - - SI.CurScope = this; - if (!isResolvableScope(Kind)) - SI.ResolvableDepth = Depth + 1; -} - -bool Scope::isResolvable() const { - return isResolvableScope(Kind); -} - -//===----------------------------------------------------------------------===// -// ScopeInfo Implementation -//===----------------------------------------------------------------------===// - -/// checkValidOverload - Check whether it is ok for D1 and D2 to be declared at -/// the same scope. This check is a transitive relationship, so if "D1 is a -/// valid overload of D2" and "D2 is a valid overload of D3" then we know that -/// D1/D3 are valid overloads and we don't have to check all permutations. -static bool checkValidOverload(const ValueDecl *D1, const ValueDecl *D2, - Parser &P) { - // Currently, there is no restriction on overloading. - return false; -} - - -/// addToScope - Register the specified decl as being in the current lexical -/// scope. -void ScopeInfo::addToScope(ValueDecl *D, Parser &TheParser, - bool diagnoseRedefinitions) { - if (!CurScope->isResolvable()) - return; - - assert(CurScope->getDepth() >= ResolvableDepth && - "inserting names into a non-resolvable scope"); - - // If we have a shadowed variable definition, check to see if we have a - // redefinition: two definitions in the same scope with the same name. - ScopedHTTy::iterator EntryI = HT.begin(CurScope->HTScope, D->getName()); - - // A redefinition is a hit in the scoped table at the same depth. - if (EntryI != HT.end() && EntryI->first == CurScope->getDepth()) { - ValueDecl *PrevDecl = EntryI->second; - - // If this is in a resolvable scope, diagnose redefinitions. Later - // phases will handle scopes like module-scope, etc. - if (CurScope->getDepth() >= ResolvableDepth) { - if (diagnoseRedefinitions) { - return TheParser.diagnoseRedefinition(PrevDecl, D); - } - return; - } - - // If this is at top-level scope, validate that the members of the overload - // set all agree. - - // Check to see if D and PrevDecl are valid in the same overload set. - if (checkValidOverload(D, PrevDecl, TheParser)) - return; - - // Note: we don't check whether all of the elements of the overload set have - // different argument types. This is checked later. - } - - HT.insertIntoScope(CurScope->HTScope, - D->getName(), - std::make_pair(CurScope->getDepth(), D)); -} - - -// Disable the "for use only in debugger" warning. -#if SWIFT_COMPILER_IS_MSVC -#pragma warning(push) -#pragma warning(disable : 4996) -#endif - -void ScopeInfo::dump() const { -#ifndef NDEBUG - // Dump out the current list of scopes. - if (!CurScope->isResolvable()) - return; - - assert(CurScope->getDepth() >= ResolvableDepth && - "Attempting to dump a non-resolvable scope?!"); - - llvm::dbgs() << "--- Dumping ScopeInfo ---\n"; - std::function func = - [&](const decltype(HT)::DebugVisitValueTy &iter) -> void { - llvm::dbgs() << "DeclName: " << iter->getKey() << "\n" - << "KeyScopeID: " << iter->getValue().first << "\n" - << "Decl: "; - iter->getValue().second->dumpRef(llvm::dbgs()); - llvm::dbgs() << "\n"; - }; - HT.debugVisit(std::move(func)); - llvm::dbgs() << "\n"; -#endif -} - -#if SWIFT_COMPILER_IS_MSVC -#pragma warning(pop) -#endif diff --git a/lib/SIL/IR/OperandOwnership.cpp b/lib/SIL/IR/OperandOwnership.cpp index 7eb96b2d0bfbe..91cc2282dd0a0 100644 --- a/lib/SIL/IR/OperandOwnership.cpp +++ b/lib/SIL/IR/OperandOwnership.cpp @@ -879,6 +879,7 @@ CONSTANT_OWNERSHIP_BUILTIN(Owned, LifetimeEnding, COWBufferForReading) CONSTANT_OWNERSHIP_BUILTIN(Owned, LifetimeEnding, UnsafeGuaranteed) CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, CancelAsyncTask) CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, CreateAsyncTask) +CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, CreateAsyncTaskFuture) #undef CONSTANT_OWNERSHIP_BUILTIN diff --git a/lib/SIL/IR/ValueOwnership.cpp b/lib/SIL/IR/ValueOwnership.cpp index 8798bf1813ed3..c3789c4508f8b 100644 --- a/lib/SIL/IR/ValueOwnership.cpp +++ b/lib/SIL/IR/ValueOwnership.cpp @@ -544,6 +544,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, GlobalStringTablePointer) CONSTANT_OWNERSHIP_BUILTIN(Owned, GetCurrentAsyncTask) CONSTANT_OWNERSHIP_BUILTIN(None, CancelAsyncTask) CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTask) +CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTaskFuture) #undef CONSTANT_OWNERSHIP_BUILTIN diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index a03a3199408eb..36573f822eb8c 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -1507,7 +1507,6 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result, if (P.Tok.is(tok::oper_binary_unspaced) && P.Tok.getText() == ".<") { P.consumeStartingCharacterOfCurrentToken(tok::period); // Create a new scope to avoid type redefinition errors. - Scope genericsScope(&P, ScopeKind::Generics); auto *genericParams = P.maybeParseGenericParams().getPtrOrNull(); assert(genericParams); auto *derivativeGenEnv = handleSILGenericParams(genericParams, &P.SF); @@ -2026,8 +2025,6 @@ parseSILDifferentiabilityWitnessConfigAndFunction(Parser &P, SILParser &SP, GenericSignature witnessGenSig = GenericSignature(); SourceLoc witnessGenSigStartLoc = P.getEndOfPreviousLoc(); { - // Create a new scope to avoid type redefinition errors. - Scope genericsScope(&P, ScopeKind::Generics); auto *genericParams = P.maybeParseGenericParams().getPtrOrNull(); if (genericParams) { auto *witnessGenEnv = handleSILGenericParams(genericParams, &P.SF); @@ -2098,10 +2095,7 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired) { // Type of the SILDeclRef is optional to be compatible with the old format. if (!P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":")) { // Parse the type for SILDeclRef. - Optional GenericsScope; - GenericsScope.emplace(&P, ScopeKind::Generics); ParserResult TyR = P.parseType(); - GenericsScope.reset(); if (TyR.isNull()) return true; @@ -3133,7 +3127,6 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B, StringRef objcString; SmallVector operandTypes; { - Scope genericsScope(&P, ScopeKind::Generics); patternParams = P.maybeParseGenericParams().getPtrOrNull(); patternEnv = handleSILGenericParams(patternParams, &P.SF); @@ -5762,7 +5755,6 @@ bool SILParserState::parseDeclSIL(Parser &P) { SILType FnType; SourceLoc FnNameLoc; - Scope S(&P, ScopeKind::TopLevel); bool isTransparent = false; IsSerialized_t isSerialized = IsNotSerialized; bool isCanonical = false; @@ -5797,7 +5789,6 @@ bool SILParserState::parseDeclSIL(Parser &P) { { // Construct a Scope for the function body so TypeAliasDecl can be added to // the scope. - Scope Body(&P, ScopeKind::FunctionBody); GenericEnvironment *GenericEnv = nullptr; GenericParamList *GenericParams = nullptr; if (FunctionState.parseSILType(FnType, GenericEnv, GenericParams, @@ -6010,7 +6001,6 @@ bool SILParserState::parseSILGlobal(Parser &P) { IsSerialized_t isSerialized = IsNotSerialized; bool isLet = false; - Scope S(&P, ScopeKind::TopLevel); SILParser State(P); if (parseSILLinkage(GlobalLinkage, P) || parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr, @@ -6076,8 +6066,6 @@ bool SILParserState::parseSILProperty(Parser &P) { GenericParamList *patternParams; GenericEnvironment *patternEnv; - Scope toplevelScope(&P, ScopeKind::TopLevel); - Scope genericsScope(&P, ScopeKind::Generics); patternParams = P.maybeParseGenericParams().getPtrOrNull(); patternEnv = handleSILGenericParams(patternParams, &P.SF); @@ -6168,7 +6156,6 @@ bool SILParserState::parseSILVTable(Parser &P) { // We need to turn on InSILBody to parse SILDeclRef. Lexer::SILBodyRAII Tmp(*P.L); - Scope S(&P, ScopeKind::TopLevel); // Parse the entry list. std::vector vtableEntries; if (P.Tok.isNot(tok::r_brace)) { @@ -6373,10 +6360,6 @@ ProtocolConformanceRef SILParser::parseProtocolConformance( ProtocolDecl *&proto, GenericEnvironment *&genericEnv, GenericParamList *&genericParams) { - // Parse generic params for the protocol conformance. We need to make sure - // they have the right scope. - Scope GenericsScope(&P, ScopeKind::Generics); - // Make sure we don't leave it uninitialized in the caller genericEnv = nullptr; @@ -6654,12 +6637,6 @@ bool SILParserState::parseSILWitnessTable(Parser &P) { WitnessState, M)) return true; - Scope S(&P, ScopeKind::TopLevel); - // We should use WitnessTableBody. This ensures that the generic params - // are visible. - Optional BodyScope; - BodyScope.emplace(&P, ScopeKind::FunctionBody); - // Parse the protocol conformance. ProtocolDecl *proto; GenericEnvironment *witnessEnv = nullptr; @@ -6690,7 +6667,6 @@ bool SILParserState::parseSILWitnessTable(Parser &P) { // We ignore empty witness table without normal protocol conformance. if (!wt && theConformance) wt = SILWitnessTable::create(M, *Linkage, theConformance); - BodyScope.reset(); return false; } @@ -6731,7 +6707,6 @@ bool SILParserState::parseSILWitnessTable(Parser &P) { wt->setLinkage(*Linkage); wt->convertToDefinition(witnessEntries, conditionalConformances, isSerialized); - BodyScope.reset(); return false; } @@ -6751,12 +6726,6 @@ bool SILParserState::parseSILDefaultWitnessTable(Parser &P) { Optional Linkage; parseSILLinkage(Linkage, P); - Scope S(&P, ScopeKind::TopLevel); - // We should use WitnessTableBody. This ensures that the generic params - // are visible. - Optional BodyScope; - BodyScope.emplace(&P, ScopeKind::FunctionBody); - // Parse the protocol. ProtocolDecl *protocol = parseProtocolDecl(P, WitnessState); if (!protocol) @@ -6796,7 +6765,6 @@ bool SILParserState::parseSILDefaultWitnessTable(Parser &P) { Linkage = SILLinkage::Public; SILDefaultWitnessTable::create(M, *Linkage, protocol, witnessEntries); - BodyScope.reset(); return false; } @@ -6837,9 +6805,6 @@ bool SILParserState::parseSILDifferentiabilityWitness(Parser &P) { return true; } - Scope scope(&P, ScopeKind::TopLevel); - Scope body(&P, ScopeKind::FunctionBody); - // We need to turn on InSILBody to parse the function references. Lexer::SILBodyRAII tmp(*P.L); @@ -6878,7 +6843,6 @@ bool SILParserState::parseSILDifferentiabilityWitness(Parser &P) { P.consumeToken(tok::identifier); if (P.parseToken(tok::colon, diag::sil_diff_witness_expected_token, ":")) return true; - Scope body(&P, ScopeKind::FunctionBody); if (State.parseSILFunctionRef(silLoc, jvp)) return true; } @@ -6887,7 +6851,6 @@ bool SILParserState::parseSILDifferentiabilityWitness(Parser &P) { P.consumeToken(tok::identifier); if (P.parseToken(tok::colon, diag::sil_diff_witness_expected_token, ":")) return true; - Scope body(&P, ScopeKind::FunctionBody); if (State.parseSILFunctionRef(silLoc, vjp)) return true; } @@ -7089,8 +7052,6 @@ bool SILParserState::parseSILScope(Parser &P) { Lexer::SILBodyRAII Tmp(*P.L); GenericEnvironment *IgnoredEnv = nullptr; GenericParamList *IgnoredParams = nullptr; - Scope S(&P, ScopeKind::TopLevel); - Scope Body(&P, ScopeKind::FunctionBody); if ((ScopeState.parseGlobalName(FnName)) || P.parseToken(tok::colon, diag::expected_sil_colon_value_ref) || ScopeState.parseSILType(Ty, IgnoredEnv, IgnoredParams, true)) diff --git a/lib/SIL/Utils/MemAccessUtils.cpp b/lib/SIL/Utils/MemAccessUtils.cpp index f2f4e38e596fb..06acf6cc78ba3 100644 --- a/lib/SIL/Utils/MemAccessUtils.cpp +++ b/lib/SIL/Utils/MemAccessUtils.cpp @@ -369,8 +369,9 @@ bool swift::isLetAddress(SILValue address) { // RC-identical would confuse ARC optimization, which might eliminate a retain // of such an object completely. // -// The SILVerifier checks that none of these operations cast a nontrivial value -// to a reference except unconditional_checked_cast[_value]. +// The SILVerifier checks that none of these operations cast a trivial value to +// a reference except unconditional_checked_cast[_value], which is checked By +// SILDynamicCastInst::isRCIdentityPreserving(). bool swift::isRCIdentityPreservingCast(SingleValueInstruction *svi) { switch (svi->getKind()) { default: @@ -1803,6 +1804,7 @@ static void visitBuiltinAddress(BuiltinInst *builtin, case BuiltinValueKind::TSanInoutAccess: case BuiltinValueKind::CancelAsyncTask: case BuiltinValueKind::CreateAsyncTask: + case BuiltinValueKind::CreateAsyncTaskFuture: return; // General memory access to a pointer in first operand position. diff --git a/lib/SIL/Verifier/LinearLifetimeChecker.cpp b/lib/SIL/Verifier/LinearLifetimeChecker.cpp index 44b45cb7c74da..e7b306f7a2387 100644 --- a/lib/SIL/Verifier/LinearLifetimeChecker.cpp +++ b/lib/SIL/Verifier/LinearLifetimeChecker.cpp @@ -551,9 +551,17 @@ LinearLifetimeChecker::Error LinearLifetimeChecker::checkValueImpl( Optional> leakingBlockCallback, Optional> nonConsumingUseOutsideLifetimeCallback) { - assert((!consumingUses.empty() - || deadEndBlocks.isDeadEnd(value->getParentBlock())) && - "Must have at least one consuming user?!"); + // FIXME: rdar://71240363. This assert does not make sense because + // consumingUses in some cases only contains the destroying uses. Owned values + // may not be destroyed because they may be converted to + // ValueOwnershipKind::None on all paths reaching a return. Instead, this + // utility needs to find liveness first considering all uses (or at least all + // uses that may be on a lifetime boundary). We probably then won't need this + // assert, but I'm leaving the FIXME as a placeholder for that work. + // + // assert((!consumingUses.empty() + // || deadEndBlocks.isDeadEnd(value->getParentBlock())) && + // "Must have at least one consuming user?!"); State state(value, visitedBlocks, errorBuilder, leakingBlockCallback, nonConsumingUseOutsideLifetimeCallback, consumingUses, diff --git a/lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp b/lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp index a0542056d2a17..0bb259c58d37b 100644 --- a/lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp +++ b/lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp @@ -245,7 +245,8 @@ bool GatherWritesVisitor::visitUse(Operand *op, AccessUseType useTy) { if (auto *pa = dyn_cast(user)) { auto argConv = ApplySite(user).getArgumentConvention(*op); - if (argConv == SILArgumentConvention::Indirect_In_Guaranteed) { + if (pa->isOnStack() && + argConv == SILArgumentConvention::Indirect_In_Guaranteed) { return true; } @@ -267,12 +268,11 @@ bool GatherWritesVisitor::visitUse(Operand *op, AccessUseType useTy) { if (!op->get()->getType().isAddress() && !user->mayWriteToMemory()) { return true; } - // If we did not recognize the user, just return conservatively that it was - // written to in a way we did not understand. + // If we did not recognize the user, print additional error diagnostics and + // return false to force SIL verification to fail. llvm::errs() << "Function: " << user->getFunction()->getName() << "\n"; llvm::errs() << "Value: " << op->get(); llvm::errs() << "Unknown instruction: " << *user; - llvm::report_fatal_error("Unexpected instruction using borrowed address?!"); return false; } diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 2b73d53ee4dac..a3eff5370bd22 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -1958,6 +1958,17 @@ class SILVerifier : public SILVerifierBase { "Inst with qualified ownership in a function that is not qualified"); } + void checkUncheckedOwnershipConversionInst( + UncheckedOwnershipConversionInst *uoci) { + require( + F.hasOwnership(), + "Inst with qualified ownership in a function that is not qualified"); + require(!uoci->getType().isAddress(), + "cannot convert ownership of an address"); + require(uoci->getType() == uoci->getOperand()->getType(), + "converting ownership does not affect the type"); + } + template void checkAccessEnforcement(AI *AccessInst) { if (AccessInst->getModule().getStage() != SILStage::Raw) { @@ -3020,7 +3031,7 @@ class SILVerifier : public SILVerifierBase { "requirement Self parameter must conform to called protocol"); auto lookupType = AMI->getLookupType(); - if (getOpenedArchetypeOf(lookupType)) { + if (getOpenedArchetypeOf(lookupType) || isa(lookupType)) { require(AMI->getTypeDependentOperands().size() == 1, "Must have a type dependent operand for the opened archetype"); verifyOpenedArchetype(AMI, lookupType); @@ -3028,7 +3039,7 @@ class SILVerifier : public SILVerifierBase { require(AMI->getTypeDependentOperands().empty(), "Should not have an operand for the opened existential"); } - if (!isa(lookupType)) { + if (!isa(lookupType) && !isa(lookupType)) { require(AMI->getConformance().isConcrete(), "concrete type lookup requires concrete conformance"); auto conformance = AMI->getConformance().getConcrete(); diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index 45da41510e50e..ce45359885199 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -1430,11 +1430,45 @@ static ManagedValue emitBuiltinCreateAsyncTask( auto apply = SGF.B.createBuiltin( loc, ctx.getIdentifier(getBuiltinName(BuiltinValueKind::CreateAsyncTask)), - SGF.getLoweredType(getAsyncTaskAndContextType(ctx)), SubstitutionMap(), + SGF.getLoweredType(getAsyncTaskAndContextType(ctx)), subs, { flags, parentTask, function }); return SGF.emitManagedRValueWithCleanup(apply); } +// Emit SIL for the named builtin: createAsyncTaskFuture. +static ManagedValue emitBuiltinCreateAsyncTaskFuture( + SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs, + ArrayRef args, SGFContext C) { + ASTContext &ctx = SGF.getASTContext(); + auto flags = args[0].forward(SGF); + auto parentTask = args[1].borrow(SGF, loc).forward(SGF); + + // Form the metatype of the result type. + CanType futureResultType = + Type( + MetatypeType::get(GenericTypeParamType::get(0, 0, SGF.getASTContext()))) + .subst(subs)->getCanonicalType(); + CanType anyTypeType = ExistentialMetatypeType::get( + ProtocolCompositionType::get(ctx, { }, false))->getCanonicalType(); + auto &anyTypeTL = SGF.getTypeLowering(anyTypeType); + auto &futureResultTL = SGF.getTypeLowering(futureResultType); + auto futureResultMetadata = SGF.emitExistentialErasure( + loc, futureResultType, futureResultTL, anyTypeTL, { }, C, + [&](SGFContext C) -> ManagedValue { + return ManagedValue::forTrivialObjectRValue( + SGF.B.createMetatype(loc, SGF.getLoweredType(futureResultType))); + }).borrow(SGF, loc).forward(SGF); + + auto function = args[2].borrow(SGF, loc).forward(SGF); + auto apply = SGF.B.createBuiltin( + loc, + ctx.getIdentifier( + getBuiltinName(BuiltinValueKind::CreateAsyncTaskFuture)), + SGF.getLoweredType(getAsyncTaskAndContextType(ctx)), subs, + { flags, parentTask, futureResultMetadata, function }); + return SGF.emitManagedRValueWithCleanup(apply); +} + Optional SpecializedEmitter::forDecl(SILGenModule &SGM, SILDeclRef function) { // Only consider standalone declarations in the Builtin module. diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp index c8c58c8bee4f9..f9c0eac952315 100644 --- a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp +++ b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp @@ -167,6 +167,7 @@ static bool isBarrier(SILInstruction *inst) { case BuiltinValueKind::UnsafeGuaranteedEnd: case BuiltinValueKind::CancelAsyncTask: case BuiltinValueKind::CreateAsyncTask: + case BuiltinValueKind::CreateAsyncTaskFuture: return true; } } diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index 7a84967671844..e568c54b35995 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -22,6 +22,64 @@ using namespace swift; using namespace constraints; +bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete() const { + // Generic parameters are always potentially incomplete. + if (isGenericParameter()) + return true; + + // If current type variable is associated with a code completion token + // it's possible that it doesn't have enough contextual information + // to be resolved to anything so let's delay considering it until everything + // else is resolved. + if (AssociatedCodeCompletionToken) + return true; + + auto *locator = TypeVar->getImpl().getLocator(); + if (!locator) + return false; + + if (locator->isLastElement()) { + // If subtyping is allowed and this is a result of an implicit member chain, + // let's delay binding it to an optional until its object type resolved too or + // it has been determined that there is no possibility to resolve it. Otherwise + // we might end up missing solutions since it's allowed to implicitly unwrap + // base type of the chain but it can't be done early - type variable + // representing chain's result type has a different l-valueness comparing + // to generic parameter of the optional. + if (llvm::any_of(Bindings, [&](const PotentialBinding &binding) { + if (binding.Kind != AllowedBindingKind::Subtypes) + return false; + + auto objectType = binding.BindingType->getOptionalObjectType(); + return objectType && objectType->isTypeVariableOrMember(); + })) + return true; + } + + if (isHole()) { + // If the base of the unresolved member reference like `.foo` + // couldn't be resolved we'd want to bind it to a hole at the + // very last moment possible, just like generic parameters. + if (locator->isLastElement()) + return true; + + // Delay resolution of the code completion expression until + // the very end to give it a chance to be bound to some + // contextual type even if it's a hole. + if (locator->directlyAt()) + return true; + + // Delay resolution of the `nil` literal to a hole until + // the very end to give it a change to be bound to some + // other type, just like code completion expression which + // relies solely on contextual information. + if (locator->directlyAt()) + return true; + } + + return false; +} + void ConstraintSystem::PotentialBindings::inferTransitiveProtocolRequirements( const ConstraintSystem &cs, llvm::SmallDenseMap @@ -462,30 +520,23 @@ void ConstraintSystem::PotentialBindings::finalize( // If there are no bindings, typeVar may be a hole. if (cs.shouldAttemptFixes() && Bindings.empty() && TypeVar->getImpl().canBindToHole()) { - IsHole = true; // If the base of the unresolved member reference like `.foo` // couldn't be resolved we'd want to bind it to a hole at the // very last moment possible, just like generic parameters. auto *locator = TypeVar->getImpl().getLocator(); - if (locator->isLastElement()) - PotentiallyIncomplete = true; // Delay resolution of the code completion expression until // the very end to give it a chance to be bound to some // contextual type even if it's a hole. - if (locator->directlyAt()) { + if (locator->directlyAt()) FullyBound = true; - PotentiallyIncomplete = true; - } // Delay resolution of the `nil` literal to a hole until // the very end to give it a change to be bound to some // other type, just like code completion expression which // relies solely on contextual information. - if (locator->directlyAt()) { + if (locator->directlyAt()) FullyBound = true; - PotentiallyIncomplete = true; - } // If this type variable is associated with a code completion token // and it failed to infer any bindings let's adjust hole's locator @@ -513,17 +564,6 @@ void ConstraintSystem::PotentialBindings::finalize( std::rotate(AnyTypePos, AnyTypePos + 1, Bindings.end()); } } - - // Determine if the bindings only constrain the type variable from above with - // an existential type; such a binding is not very helpful because it's - // impossible to enumerate the existential type's subtypes. - if (!Bindings.empty()) { - SubtypeOfExistentialType = - llvm::all_of(Bindings, [](const PotentialBinding &binding) { - return binding.BindingType->isExistentialType() && - binding.Kind == AllowedBindingKind::Subtypes; - }); - } } Optional @@ -678,9 +718,6 @@ void ConstraintSystem::PotentialBindings::addPotentialBinding( if (!isViable(binding)) return; - if (binding.isDefaultableBinding()) - ++NumDefaultableBindings; - Bindings.push_back(std::move(binding)); } @@ -709,7 +746,7 @@ bool ConstraintSystem::PotentialBindings::isViable( bool ConstraintSystem::PotentialBindings::favoredOverDisjunction( Constraint *disjunction) const { - if (IsHole || FullyBound) + if (isHole() || FullyBound) return false; // If this bindings are for a closure and there are no holes, @@ -889,10 +926,8 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint( // bindings and use it when forming a hole if there are no other bindings // available. if (auto *locator = bindingTypeVar->getImpl().getLocator()) { - if (locator->directlyAt()) { + if (locator->directlyAt()) result.AssociatedCodeCompletionToken = locator->getAnchor(); - result.PotentiallyIncomplete = true; - } } switch (constraint->getKind()) { @@ -931,24 +966,6 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint( return None; } - // If subtyping is allowed and this is a result of an implicit member chain, - // let's delay binding it to an optional until its object type resolved too or - // it has been determined that there is no possibility to resolve it. Otherwise - // we might end up missing solutions since it's allowed to implicitly unwrap - // base type of the chain but it can't be done early - type variable - // representing chain's result type has a different l-valueness comparing - // to generic parameter of the optional. - if (kind == AllowedBindingKind::Subtypes) { - auto *locator = typeVar->getImpl().getLocator(); - if (locator && - locator->isLastElement()) { - auto objectType = type->getOptionalObjectType(); - if (objectType && objectType->isTypeVariableOrMember()) { - result.PotentiallyIncomplete = true; - } - } - } - if (type->is() && !typeVar->getImpl().canBindToInOut()) type = LValueType::get(type->getInOutObjectType()); if (type->is() && !typeVar->getImpl().canBindToLValue()) @@ -987,20 +1004,6 @@ bool ConstraintSystem::PotentialBindings::infer( case ConstraintKind::ArgumentConversion: case ConstraintKind::OperatorArgumentConversion: case ConstraintKind::OptionalObject: { - // If there is a `bind param` constraint associated with - // current type variable, result should be aware of that - // fact. Binding set might be incomplete until - // this constraint is resolved, because we currently don't - // look-through constraints expect to `subtype` to try and - // find related bindings. - // This only affects type variable that appears one the - // right-hand side of the `bind param` constraint and - // represents result type of the closure body, because - // left-hand side gets types from overload choices. - if (constraint->getKind() == ConstraintKind::BindParam && - constraint->getSecondType()->isEqual(TypeVar)) - PotentiallyIncomplete = true; - auto binding = cs.getPotentialBindingForRelationalConstraint(*this, constraint); if (!binding) diff --git a/lib/Sema/ConstraintGraph.cpp b/lib/Sema/ConstraintGraph.cpp index 8450dda8e72c4..a91d87f545aac 100644 --- a/lib/Sema/ConstraintGraph.cpp +++ b/lib/Sema/ConstraintGraph.cpp @@ -1117,7 +1117,7 @@ bool ConstraintGraph::contractEdges() { bool isNotContractable = true; if (auto bindings = CS.inferBindingsFor(tyvar1)) { // Holes can't be contracted. - if (bindings.IsHole) + if (bindings.isHole()) continue; for (auto &binding : bindings.Bindings) { diff --git a/lib/Sema/PreCheckExpr.cpp b/lib/Sema/PreCheckExpr.cpp index 32a05f091e5c9..4cae305fc7ede 100644 --- a/lib/Sema/PreCheckExpr.cpp +++ b/lib/Sema/PreCheckExpr.cpp @@ -380,15 +380,15 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, ValueDecl *localDeclAfterUse = nullptr; auto isValid = [&](ValueDecl *D) { + // References to variables injected by lldb are always valid. + if (isa(D) && cast(D)->isDebuggerVar()) + return true; + // If we find something in the current context, it must be a forward // reference, because otherwise if it was in scope, it would have // been returned by the call to ASTScope::lookupLocalDecls() above. if (D->getDeclContext()->isLocalContext() && - D->getDeclContext() == DC && - (Context.LangOpts.DisableParserLookup || - (Loc.isValid() && D->getLoc().isValid() && - Context.SourceMgr.isBeforeInBuffer(Loc, D->getLoc()) && - !isa(D)))) { + D->getDeclContext() == DC) { localDeclAfterUse = D; return false; } diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index bf074b989d5f4..e4c6753671406 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -401,9 +401,6 @@ template static void diagnoseDuplicateDecls(const T &decls) { llvm::SmallDenseMap names; for (auto *current : decls) { - if (!current->getASTContext().LangOpts.DisableParserLookup) - return; - if (!current->hasName() || current->isImplicit()) continue; @@ -528,13 +525,11 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const { otherDefinitions.append(found.begin(), found.end()); } } else if (currentDC->isLocalContext()) { - if (ctx.LangOpts.DisableParserLookup) { - if (!current->isImplicit()) { - ASTScope::lookupLocalDecls(currentFile, current->getBaseName(), - current->getLoc(), - /*stopAfterInnermostBraceStmt=*/true, - otherDefinitions); - } + if (!current->isImplicit()) { + ASTScope::lookupLocalDecls(currentFile, current->getBaseName(), + current->getLoc(), + /*stopAfterInnermostBraceStmt=*/true, + otherDefinitions); } } else { assert(currentDC->isModuleScopeContext()); diff --git a/stdlib/cmake/modules/AddSwiftStdlib.cmake b/stdlib/cmake/modules/AddSwiftStdlib.cmake index f60c67c1368cf..e35637f696cf7 100644 --- a/stdlib/cmake/modules/AddSwiftStdlib.cmake +++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake @@ -402,10 +402,10 @@ function(_add_target_variant_link_flags) list(APPEND library_search_directories ${CMAKE_BINARY_DIR}/winsdk_lib_${LFLAGS_ARCH}_symlinks) elseif("${LFLAGS_SDK}" STREQUAL "HAIKU") - list(APPEND link_libraries "bsd" "atomic") + list(APPEND link_libraries "bsd") list(APPEND result "-Wl,-Bsymbolic") elseif("${LFLAGS_SDK}" STREQUAL "ANDROID") - list(APPEND link_libraries "dl" "log" "atomic") + list(APPEND link_libraries "dl" "log") # We need to add the math library, which is linked implicitly by libc++ list(APPEND result "-lm") diff --git a/stdlib/public/Concurrency/Task.cpp b/stdlib/public/Concurrency/Task.cpp index c2e5464204df3..ece1da25be26a 100644 --- a/stdlib/public/Concurrency/Task.cpp +++ b/stdlib/public/Concurrency/Task.cpp @@ -213,10 +213,7 @@ AsyncTaskAndContext swift::swift_task_create_future_f( // This means that we never get rid of this allocation. size_t amountToAllocate = headerSize + initialContextSize; - // TODO: if this is necessary we need to teach LLVM lowering to request async - // context sizes that are mulitple of that maximum alignment. - // For now disable this assert. - // assert(amountToAllocate % MaximumAlignment == 0); + assert(amountToAllocate % MaximumAlignment == 0); void *allocation = malloc(amountToAllocate); diff --git a/stdlib/public/Concurrency/Task.swift b/stdlib/public/Concurrency/Task.swift index fc478b95dd3ac..a161a6f6cd3fa 100644 --- a/stdlib/public/Concurrency/Task.swift +++ b/stdlib/public/Concurrency/Task.swift @@ -79,14 +79,16 @@ extension Task { /// TODO: Define the details of task priority; It is likely to be a concept /// similar to Darwin Dispatch's QoS; bearing in mind that priority is not as /// much of a thing on other platforms (i.e. server side Linux systems). - public struct Priority: Comparable { - public static let `default`: Task.Priority = .init() // TODO: replace with actual values + public enum Priority: Int, Comparable { + case userInteractive = 0x21 + case userInitiated = 0x19 + case `default` = 0x15 + case utility = 0x11 + case background = 0x09 + case unspecified = 0x00 - // TODO: specifics of implementation are not decided yet - private let __value: Int = 0 - - public static func < (lhs: Self, rhs: Self) -> Bool { - lhs.__value < rhs.__value + public static func < (lhs: Priority, rhs: Priority) -> Bool { + lhs.rawValue < rhs.rawValue } } } @@ -94,7 +96,6 @@ extension Task { // ==== Task Handle ------------------------------------------------------------ extension Task { - /// A task handle refers to an in-flight `Task`, /// allowing for potentially awaiting for its result or canceling it. /// @@ -102,9 +103,8 @@ extension Task { /// i.e. the task will run regardless of the handle still being present or not. /// Dropping a handle however means losing the ability to await on the task's result /// and losing the ability to cancel it. - @_frozen public struct Handle { - private let task: Builtin.NativeObject + let task: Builtin.NativeObject /// Wait for the task to complete, returning (or throwing) its result. /// @@ -121,7 +121,18 @@ extension Task { /// and throwing a specific error or using `checkCancellation` the error /// thrown out of the task will be re-thrown here. public func get() async throws -> Success { - fatalError("\(#function) not implemented yet.") + let rawResult = taskFutureWait( + on: task, waiting: Builtin.getCurrentAsyncTask()) + switch TaskFutureWaitResult(raw: rawResult) { + case .executing: + fatalError("don't know how to synchronously return") + + case .success(let result): + return result + + case .failure(let error): + throw error + } } /// Attempt to cancel the task. @@ -138,6 +149,78 @@ extension Task { } } +// ==== Job Flags -------------------------------------------------------------- + +extension Task { + /// Flags for schedulable jobs. + /// + /// This is a port of the C++ FlagSet. + struct JobFlags { + /// Kinds of schedulable jobs. + enum Kind : Int { + case task = 0 + }; + + /// The actual bit representation of these flags. + var bits: Int = 0 + + /// The kind of job described by these flags. + var kind: Kind { + get { + Kind(rawValue: bits & 0xFF)! + } + + set { + bits = (bits & ~0xFF) | newValue.rawValue + } + } + + /// Whether this is an asynchronous task. + var isAsyncTask: Bool { kind == .task } + + /// The priority given to the job. + var priority: Priority { + get { + Priority(rawValue: (bits & 0xFF00) >> 8)! + } + + set { + bits = (bits & ~0xFF00) | (newValue.rawValue << 8) + } + } + + /// Whether this is a child task. + var isChildTask: Bool { + get { + (bits & (1 << 24)) != 0 + } + + set { + if newValue { + bits = bits | 1 << 24 + } else { + bits = (bits & ~(1 << 24)) + } + } + } + + /// Whether this is a future. + var isFuture: Bool { + get { + (bits & (1 << 25)) != 0 + } + + set { + if newValue { + bits = bits | 1 << 25 + } else { + bits = (bits & ~(1 << 25)) + } + } + } + } +} + // ==== Detached Tasks --------------------------------------------------------- extension Task { @@ -172,9 +255,22 @@ extension Task { /// tasks result or `cancel` it. public static func runDetached( priority: Priority = .default, - operation: () async -> T + operation: @escaping () async -> T ) -> Handle { - fatalError("\(#function) not implemented yet.") + // Set up the job flags for a new task. + var flags = JobFlags() + flags.kind = .task + flags.priority = priority + flags.isFuture = true + + // Create the asynchronous task future. + let (task, context) = + Builtin.createAsyncTaskFuture(flags.bits, nil, operation) + + // FIXME: Launch the task on an executor... somewhere.... + runTask(task) + + return Handle(task: task) } /// Run given throwing `operation` as part of a new top-level task. @@ -209,9 +305,24 @@ extension Task { /// throw the error the operation has thrown when awaited on. public static func runDetached( priority: Priority = .default, - operation: () async throws -> T + operation: @escaping () async throws -> T ) -> Handle { - fatalError("\(#function) not implemented yet.") + // Set up the job flags for a new task. + var flags = JobFlags() + flags.kind = .task + flags.priority = priority + flags.isFuture = true + + // Create the asynchronous task future. + let (task, context) = + Builtin.createAsyncTaskFuture(flags.bits, nil, operation) + + print(task) + + // FIXME: Launch the task on an executor... somewhere.... + runTask(task) + + return Handle(task: task) } } @@ -314,3 +425,48 @@ public func runAsync(_ asyncFun: @escaping () async -> ()) { let childTask = Builtin.createAsyncTask(0, nil, asyncFun) runTask(childTask.0) } + +/// Describes the result of waiting for a future. +enum TaskFutureWaitResult { + /// The future is still executing, and our waiting task has been placed + /// on its queue for when the future completes. + case executing + + /// The future has succeeded with the given value. + case success(T) + + /// The future has thrown the given error. + case failure(Error) + + /// Initialize this instance from a raw result, taking any instance within + /// that result. + init(raw: RawTaskFutureWaitResult) { + switch raw.kind { + case 0: + self = .executing + + case 1: + // Take the value on success + let storagePtr = raw.storage.bindMemory(to: T.self, capacity: 1) + self = .success(UnsafeMutablePointer(mutating: storagePtr).move()) + + case 2: + // Take the error on error. + self = .failure(unsafeBitCast(raw.storage, to: Error.self)) + + default: + assert(false) + self = .executing + } + } +} + +struct RawTaskFutureWaitResult { + let kind: Int + let storage: UnsafeRawPointer +} + +@_silgen_name("swift_task_future_wait") +func taskFutureWait( + on task: Builtin.NativeObject, waiting waitingTask: Builtin.NativeObject +) -> RawTaskFutureWaitResult diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp index 09bc0b6b258b4..fb93b26722f8a 100644 --- a/stdlib/public/Reflection/TypeLowering.cpp +++ b/stdlib/public/Reflection/TypeLowering.cpp @@ -2121,7 +2121,9 @@ class LowerType return TC.getReferenceTypeInfo(Kind, ReferenceTI->getReferenceCounting()); if (auto *EnumTI = dyn_cast(TI)) { - if (EnumTI->isOptional() && Kind == ReferenceKind::Weak) { + if (EnumTI->isOptional() && + (Kind == ReferenceKind::Weak || Kind == ReferenceKind::Unowned || + Kind == ReferenceKind::Unmanaged)) { auto *TI = TC.getTypeInfo(EnumTI->getCases()[0].TR, ExternalTypeInfo); return rebuildStorageTypeInfo(TI, Kind); } diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 0f84659f09296..b3d8a857a2044 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -259,19 +259,13 @@ else() endif() endif() -if(SWIFT_PRIMARY_VARIANT_SDK STREQUAL ANDROID) - # workaround for libatomic needing to be after object files for swiftCore.so - list(APPEND swift_core_private_link_libraries atomic) -elseif(SWIFT_PRIMARY_VARIANT_SDK STREQUAL CYGWIN) +if(SWIFT_PRIMARY_VARIANT_SDK STREQUAL CYGWIN) # TODO(compnerd) cache this variable to permit re-configuration execute_process(COMMAND "cygpath" "-u" "$ENV{SYSTEMROOT}" OUTPUT_VARIABLE ENV_SYSTEMROOT) list(APPEND swift_core_private_link_libraries "${ENV_SYSTEMROOT}/system32/psapi.dll") elseif(SWIFT_PRIMARY_VARIANT_SDK STREQUAL FREEBSD) find_library(EXECINFO_LIBRARY execinfo) list(APPEND swift_core_private_link_libraries ${EXECINFO_LIBRARY}) - # workaround for libatomic needing to be after object files for swiftCore.so - list(APPEND swift_core_private_link_libraries - ${SWIFTLIB_DIR}/clang/lib/freebsd/libclang_rt.builtins-${SWIFT_PRIMARY_VARIANT_ARCH}.a) elseif(SWIFT_PRIMARY_VARIANT_SDK STREQUAL LINUX) if(SWIFT_BUILD_STATIC_STDLIB) list(APPEND swift_core_private_link_libraries) diff --git a/test/Casting/Casts.swift b/test/Casting/Casts.swift index 6a7c73d63964e..6a9a7594a0f4e 100644 --- a/test/Casting/Casts.swift +++ b/test/Casting/Casts.swift @@ -795,4 +795,90 @@ CastsTests.test("AnyObject.Type -> AnyObject") { } #endif +protocol Fruit {} +CastsTests.test("Generic type validation [SR-13812]") { + func check(a: A.Type, b: B.Type) -> Bool { + return (a is B.Type) + } + struct Apple: Fruit {} + expectFalse(check(a: Apple.self, b: Fruit.self)) + expectFalse(Apple.self is Fruit.Protocol) + expectTrue(Apple.self is Fruit.Type) +} + +CastsTests.test("Cast failure for Any! holding Error struct [SR-8964]") { + struct MyError: Error {} + let a: Any! = MyError() + let b: Any = a + expectTrue(b is Error) +} + +CastsTests.test("Cannot cast from Any? to Existential [SR-1999]") { + let a = Float(1) as Any as? Float + expectNotNil(a) + + let b = Float(1) as Any as? CustomStringConvertible + expectNotNil(b) + + let c = Optional.some(Float(1)) as Any as? Float + expectNotNil(c) + + let d = Optional.some(Float(1)) as Any as? CustomStringConvertible + expectNotNil(d) +} + +protocol A {} +CastsTests.test("Failing cast from Any to Optional [SR-6279]") { + struct B: A {} + + // If we have an optional instance, stored as an `Any` + let b: A? = B() + let c = b as Any + + // This fails to cast, should succeed. + let d = c as? A + expectNotNil(d) + + // There is a workaround, but not ideal. + func cast(_ t: T, to: U.Type) -> U? { + return t as? U + } + let f = cast(c, to: Any?.self) as? A + expectNotNil(f) +} + +protocol SuperProtocol{} +CastsTests.test("Casting Objects retained from KeyPaths to Protocols is not working properly") { + // This is the simplified reproduction from rdar://59844232 which doesn't + // actually use KeyPaths + class SubClass : SuperProtocol{} + let value = SubClass() as Any? as Any + + expectNotNil(value as? SubClass) + expectNotNil(value as? SuperProtocol) +} + +#if _runtime(_ObjC) +// Known to still be broken, but we can document the issue here +public protocol SomeProtocol {} +extension NSString: SomeProtocol {} +CastsTests.test("NSDictionary -> Dictionary casting [SR-12025]") { + // Create NSDictionary with one entry + var a = NSMutableDictionary() + a[NSString("key")] = NSString("value") + + let v = NSString("value") + let v2 = v as? SomeProtocol + expectNotNil(v2) + + // Test casting of the dictionary + let b = a as? [String:SomeProtocol] + expectFailure { expectNotNil(b) } // Expect non-nil, but see nil + let c = a as? [String:Any] + expectNotNil(c) // Non-nil (as expected) + let d = c as? [String:SomeProtocol] + expectNotNil(d) // Non-nil (as expected) +} +#endif + runAllTests() diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift index 2d9a1d7d2742e..6670bdc2ff375 100644 --- a/test/Constraints/tuple.swift +++ b/test/Constraints/tuple.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift // Test various tuple constraints. diff --git a/test/Constraints/tuple_parser_lookup.swift b/test/Constraints/tuple_parser_lookup.swift deleted file mode 100644 index a3acaf4f356e4..0000000000000 --- a/test/Constraints/tuple_parser_lookup.swift +++ /dev/null @@ -1,337 +0,0 @@ -// 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/Frontend/skip-function-bodies.swift b/test/Frontend/skip-function-bodies.swift index b2711efea575c..fed02446b3cde 100644 --- a/test/Frontend/skip-function-bodies.swift +++ b/test/Frontend/skip-function-bodies.swift @@ -7,12 +7,13 @@ // RUN: not %target-swift-frontend -c %s -experimental-skip-non-inlinable-function-bodies-without-types %s 2>&1 | %FileCheck %s --check-prefix ERROR // RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-all-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR // RUN: not %target-swift-frontend -c %s -experimental-skip-all-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR -// ERROR: -experimental-skip-*-function-bodies do not support emitting IR +// ERROR: the -experimental-skip-*-function-bodies* flags do not support emitting IR -// Warn when trying to build SwiftONoneSupport with skip non-inlinable -// function bodies enabled +// Warn when trying to build SwiftONoneSupport with any skip enabled // RUN: %target-swift-frontend -typecheck -experimental-skip-non-inlinable-function-bodies -module-name SwiftOnoneSupport %s 2>&1 | %FileCheck %s --check-prefix WARNING -// WARNING: module 'SwiftOnoneSupport' cannot be built with -experimental-skip-non-inlinable-function-bodies; this option has been automatically disabled +// RUN: %target-swift-frontend -typecheck -experimental-skip-non-inlinable-function-bodies-without-types -module-name SwiftOnoneSupport %s 2>&1 | %FileCheck %s --check-prefix WARNING +// RUN: %target-swift-frontend -typecheck -experimental-skip-all-function-bodies -module-name SwiftOnoneSupport %s 2>&1 | %FileCheck %s --check-prefix WARNING +// WARNING: module 'SwiftOnoneSupport' cannot be built with any of the -experimental-skip-*-function-bodies* flags; they have been automatically disabled // Check skipped bodies are neither typechecked nor SILgen'd // RUN: %target-swift-frontend -emit-sil -emit-sorted-sil -experimental-skip-non-inlinable-function-bodies -debug-forbid-typecheck-prefix NEVERTYPECHECK -debug-forbid-typecheck-prefix INLINENOTYPECHECK %s -o %t/Skip.noninlinable.sil diff --git a/test/IRGen/async/builtins.sil b/test/IRGen/async/builtins.sil index 6a6b82784a048..221a0faec81a8 100644 --- a/test/IRGen/async/builtins.sil +++ b/test/IRGen/async/builtins.sil @@ -34,7 +34,7 @@ sil hidden [ossa] @launch_task : $@convention(method) @async (Int, Optional, %2: @guaranteed $@async @callee_guaranteed () -> (@error Error)): %3 = begin_borrow %1 : $Optional // CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[FN_CONTEXT:%.*]]) - // CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create( + // CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create_f( // CHECK-NEXT: [[NEW_CONTEXT_RAW:%.*]] = extractvalue %swift.async_task_and_context [[NEW_TASK_AND_CONTEXT]], 1 // CHECK-NEXT: [[NEW_CONTEXT:%.*]] = bitcast %swift.context* [[NEW_CONTEXT_RAW]] to // CHECK-NEXT: [[CONTEXT_INFO_LOC:%.*]] = getelementptr inbounds <{{.*}}>* [[NEW_CONTEXT]] @@ -45,3 +45,22 @@ bb0(%0 : $Int, %1: @unowned $Optional, %2: @guaranteed $@a %21 = tuple () return %21 : $() } + +// CHECK-LABEL: define hidden swiftcc void @launch_future +sil hidden [ossa] @launch_future : $@convention(method) (Int, Optional, @guaranteed @async @callee_guaranteed @substituted <Ï„_0_0> () -> (@out Ï„_0_0, @error Error) for , @in_guaranteed T) -> () { +bb0(%0 : $Int, %1: @unowned $Optional, %2: @guaranteed $@async @callee_guaranteed @substituted <Ï„_0_0> () -> (@out Ï„_0_0, @error Error) for , %3: $*T): + %4 = begin_borrow %1 : $Optional + // CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[FN_CONTEXT:%.*]]) + %9 = metatype $@thick T.Type + %10 = init_existential_metatype %9 : $@thick T.Type, $@thick Any.Type + // CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create_future_f( + // CHECK-NEXT: [[NEW_CONTEXT_RAW:%.*]] = extractvalue %swift.async_task_and_context [[NEW_TASK_AND_CONTEXT]], 1 + // CHECK-NEXT: [[NEW_CONTEXT:%.*]] = bitcast %swift.context* [[NEW_CONTEXT_RAW]] to + // CHECK-NEXT: [[CONTEXT_INFO_LOC:%.*]] = getelementptr inbounds <{{.*}}>* [[NEW_CONTEXT]] + // CHECK-NEXT: store %swift.refcounted* [[FN_CONTEXT]], %swift.refcounted** [[CONTEXT_INFO_LOC]] + %20 = builtin "createAsyncTaskFuture"(%0 : $Int, %4 : $Optional, %10 : $@thick Any.Type, %2 : $@async @callee_guaranteed @substituted <Ï„_0_0> () -> (@out Ï„_0_0, @error Error) for ) : $(Builtin.NativeObject, Builtin.RawPointer) + end_borrow %4 : $Optional + destroy_value %20 : $(Builtin.NativeObject, Builtin.RawPointer) + %21 = tuple () + return %21 : $() +} diff --git a/test/IRGen/async/debug.swift b/test/IRGen/async/debug.swift new file mode 100644 index 0000000000000..f3ab0787a4764 --- /dev/null +++ b/test/IRGen/async/debug.swift @@ -0,0 +1,15 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir -enable-experimental-concurrency -g | %FileCheck %s +// REQUIRES: concurrency + +// Don't assert on dynamically sized variables. +// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s5debug1fyxxYKlF" + +public func f(_ value: Success) async throws -> Success { + switch Result.success(value) { + case .success(let success): + return success + + case .failure(let error): + throw error; + } +} diff --git a/test/IRGen/async/partial_apply.sil b/test/IRGen/async/partial_apply.sil index 27ad0e1f41cb2..8f7068cd469d3 100644 --- a/test/IRGen/async/partial_apply.sil +++ b/test/IRGen/async/partial_apply.sil @@ -53,7 +53,7 @@ entry(%a : $SwiftClass, %b: $SwiftClass): %t = tuple() return %t : $() } -// CHECK-LABEL: define internal swiftcc void @"$s22generic_captured_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s22generic_captured_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil public_external @generic_captured_param : $@async @convention(thin) (Int, @inout T) -> Int sil @partial_apply_generic_capture : $@async @convention(thin) (Int) -> @async @callee_owned (Int) -> Int { @@ -95,7 +95,7 @@ bb0(%x : $SwiftClass): sil public_external @indirect_guaranteed_captured_class_param : $@async @convention(thin) (Int, @in_guaranteed SwiftClass) -> Int // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_indirect_guaranteed_class_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s40indirect_guaranteed_captured_class_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s40indirect_guaranteed_captured_class_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_indirect_guaranteed_class_param : $@async @convention(thin) (@in SwiftClass) -> @async @callee_owned (Int) -> Int { bb0(%x : $*SwiftClass): @@ -107,7 +107,7 @@ bb0(%x : $*SwiftClass): sil public_external @indirect_consumed_captured_class_param : $@async @convention(thin) (Int, @in SwiftClass) -> Int // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_indirect_consumed_class_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s38indirect_consumed_captured_class_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s38indirect_consumed_captured_class_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_indirect_consumed_class_param : $@async @convention(thin) (@in SwiftClass) -> @async @callee_owned (Int) -> Int { bb0(%x : $*SwiftClass): @@ -126,7 +126,7 @@ struct SwiftClassPair { var x: SwiftClass, y: SwiftClass } sil public_external @guaranteed_captured_class_pair_param : $@async @convention(thin) (Int, @guaranteed SwiftClassPair) -> Int // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_guaranteed_class_pair_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s36guaranteed_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s36guaranteed_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_guaranteed_class_pair_param : $@async @convention(thin) (@owned SwiftClassPair) -> @async @callee_owned (Int) -> Int { bb0(%x : $SwiftClassPair): @@ -138,7 +138,7 @@ bb0(%x : $SwiftClassPair): sil public_external @indirect_guaranteed_captured_class_pair_param : $@async @convention(thin) (Int, @in_guaranteed SwiftClassPair) -> Int // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_indirect_guaranteed_class_pair_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s45indirect_guaranteed_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s45indirect_guaranteed_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_indirect_guaranteed_class_pair_param : $@async @convention(thin) (@in SwiftClassPair) -> @async @callee_owned (Int) -> Int { bb0(%x : $*SwiftClassPair): @@ -150,7 +150,7 @@ bb0(%x : $*SwiftClassPair): sil public_external @indirect_consumed_captured_class_pair_param : $@async @convention(thin) (Int, @in SwiftClassPair) -> Int // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_indirect_consumed_class_pair_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s43indirect_consumed_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s43indirect_consumed_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_indirect_consumed_class_pair_param : $@async @convention(thin) (@in SwiftClassPair) -> @async @callee_owned (Int) -> Int { bb0(%x : $*SwiftClassPair): @@ -162,7 +162,7 @@ bb0(%x : $*SwiftClassPair): sil public_external @captured_fixed_and_dependent_params : $@async @convention(thin) (@owned SwiftClass, @in A, Int) -> () // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_indirect_non_fixed_layout(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s35captured_fixed_and_dependent_paramsTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s35captured_fixed_and_dependent_paramsTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_indirect_non_fixed_layout : $@async @convention(thin) (@owned SwiftClass, @in T, Int) -> @async @callee_owned () -> () { bb0(%a : $SwiftClass, %b : $*T, %c : $Int): %f = function_ref @captured_fixed_and_dependent_params : $@async @convention(thin) (@owned SwiftClass, @in B, Int) -> () @@ -179,7 +179,7 @@ bb0(%x : $*T): return %p : $@async @callee_owned () -> @out T } -// CHECK-LABEL: define internal swiftcc void @"$s28captured_dependent_out_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s28captured_dependent_out_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_dynamic_with_out_param : $@async @convention(thin) (Int32, @owned @async @callee_owned (Int32) -> @out T) -> @async @callee_owned () -> @out T { bb0(%x : $Int32, %f : $@async @callee_owned (Int32) -> @out T): @@ -208,8 +208,8 @@ sil public_external @receive_closure : $@async @convention(thin) () { bb0(%0 : $Base): @@ -251,7 +251,7 @@ bb0(%0 : $Int): return %result : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_complex_generic_function(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s24complex_generic_functionTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s24complex_generic_functionTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { struct ComplexBoundedType {} @@ -290,7 +290,7 @@ enum GenericEnum { sil public_external @generic_indirect_return : $@async @convention(thin) (Int) -> @owned GenericEnum // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_generic_indirect_return(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s23generic_indirect_returnTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s23generic_indirect_returnTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_generic_indirect_return : $@async @convention(thin) (Int) -> @async @callee_owned () -> @owned GenericEnum { bb0(%0 : $Int): %fn = function_ref @generic_indirect_return :$@async @convention(thin) (Int) -> @owned GenericEnum @@ -307,7 +307,7 @@ enum GenericEnum2 { sil public_external @generic_indirect_return2 : $@async @convention(thin) (Int) -> @owned GenericEnum2 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_generic_indirect_return2(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s24generic_indirect_return2TA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s24generic_indirect_return2TA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_generic_indirect_return2 : $@async @convention(thin) (Int) -> @async @callee_owned () -> @owned GenericEnum2 { bb0(%0 : $Int): %fn = function_ref @generic_indirect_return2 :$@async @convention(thin) (Int) -> @owned GenericEnum2 @@ -406,7 +406,7 @@ bb0(%x : $*SwiftClassPair): sil public_external @use_closure2 : $@async @convention(thin) (@noescape @async @callee_guaranteed (Int) -> Int) -> () // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_stack_callee_guaranteed_indirect_guaranteed_class_pair_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s45indirect_guaranteed_captured_class_pair_paramTA.70"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s45indirect_guaranteed_captured_class_pair_paramTA.70"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil @partial_apply_stack_callee_guaranteed_indirect_guaranteed_class_pair_param : $@async @convention(thin) (@in_guaranteed SwiftClassPair) -> () { bb0(%x : $*SwiftClassPair): @@ -420,7 +420,7 @@ bb0(%x : $*SwiftClassPair): } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_stack_callee_guaranteed_indirect_in_class_pair_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s37indirect_in_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s37indirect_in_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil public_external @indirect_in_captured_class_pair_param : $@async @convention(thin) (Int, @in SwiftClassPair) -> Int @@ -438,7 +438,7 @@ bb0(%x : $*SwiftClassPair): // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @partial_apply_stack_callee_guaranteed_indirect_in_constant_class_pair_param(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s46indirect_in_constant_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s46indirect_in_constant_captured_class_pair_paramTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil public_external @indirect_in_constant_captured_class_pair_param : $@async @convention(thin) (Int, @in_constant SwiftClassPair) -> Int diff --git a/test/IRGen/async/partial_apply_forwarder.sil b/test/IRGen/async/partial_apply_forwarder.sil index ebc995edd7d63..466aae534137c 100644 --- a/test/IRGen/async/partial_apply_forwarder.sil +++ b/test/IRGen/async/partial_apply_forwarder.sil @@ -29,7 +29,7 @@ bb0(%0 : $*S): return %2 : $@async @callee_owned (@in O) -> () } -// CHECK-LABEL: define internal swiftcc void @"$s23unspecialized_uncurriedTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s23unspecialized_uncurriedTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil hidden @specialized_curried : $@async @convention(thin) (@owned E) -> @owned @async @callee_owned () -> @owned D { bb0(%0 : $E): @@ -41,7 +41,7 @@ bb0(%0 : $E): sil hidden_external @unspecialized_uncurried : $@async @convention(method) <Ï„_0_0 where Ï„_0_0 : P> (@guaranteed E) -> @owned D<Ï„_0_0> -// CHECK-LABEL: define internal swiftcc void @"$s7takingPTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s7takingPTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil hidden_external @takingP : $@async @convention(method) <Ï„_0_0 where Ï„_0_0 : P> (@in_guaranteed Ï„_0_0) -> () sil hidden @reabstract_context : $@async @convention(thin) (@owned C) -> () { @@ -73,7 +73,7 @@ sil hidden_external @takingQAndEmpty : $@async @convention(thin) <Ï„_0_0 where sil hidden_external @takingEmptyAndQ : $@async @convention(thin) <Ï„_0_0 where Ï„_0_0 : Q> (EmptyType, @owned WeakBox<Ï„_0_0>) -> () // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @bind_polymorphic_param_from_context(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s7takingQTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s7takingQTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil public @bind_polymorphic_param_from_context : $@async @convention(thin) <Ï„_0_1>(@in Ï„_0_1) -> @owned @async @callee_owned () -> () { bb0(%0 : $*Ï„_0_1): @@ -102,7 +102,7 @@ bb0(%0 : $*Ï„_0_1, %2: $EmptyType): } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @bind_polymorphic_param_from_forwarder_parameter(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s7takingQTA.19"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s7takingQTA.19"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil public @bind_polymorphic_param_from_forwarder_parameter : $@async @convention(thin) <Ï„_0_1>(@in Ï„_0_1) -> () { bb0(%0 : $*Ï„_0_1): @@ -120,7 +120,7 @@ struct S { sil hidden_external @takingQAndS : $@async @convention(thin) <Ï„_0_0 where Ï„_0_0 : Q> (S, @owned WeakBox<Ï„_0_0>) -> () // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @bind_polymorphic_param_from_context_with_layout(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s11takingQAndSTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s11takingQAndSTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { sil public @bind_polymorphic_param_from_context_with_layout : $@async @convention(thin) <Ï„_0_1>(@in Ï„_0_1, S) -> @owned @async @callee_owned () -> () { bb0(%0 : $*Ï„_0_1, %1: $S): %2 = alloc_ref $WeakBox> @@ -152,7 +152,7 @@ bb0: } // CHECK-LABEL: define hidden swiftcc void @specializes_closure_returning_closure(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { -// CHECK-LABEL: define internal swiftcc void @"$s15returns_closureTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]+}}) {{#[0-9]+}} { +// CHECK-LABEL: define internal swiftcc void @"$s15returns_closureTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]+}} { protocol MyEquatable { static func isEqual (lhs: Self, rhs: Self) -> Builtin.Int1 } diff --git a/test/IRGen/async/run-partialapply-capture-generic_conformer-and-generic-to-void.sil b/test/IRGen/async/run-partialapply-capture-generic_conformer-and-generic-to-void.sil index 73a23172b029e..1292308ec8075 100644 --- a/test/IRGen/async/run-partialapply-capture-generic_conformer-and-generic-to-void.sil +++ b/test/IRGen/async/run-partialapply-capture-generic_conformer-and-generic-to-void.sil @@ -56,7 +56,7 @@ sil_witness_table ObserverImpl : Observer module main { associated_type Result : () } -// CHECK-LL: define internal swiftcc void @"$sTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$sTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil hidden @witness_method : $@async @convention(thin) (@in S) -> @owned @async @callee_owned (@in O) -> () { bb0(%0 : $*S): %1 = witness_method $S, #Observable.subscribe : $@async @convention(witness_method: Observable) <Ï„_0_0 where Ï„_0_0 : Observable><Ï„_1_0 where Ï„_1_0 : Observer, Ï„_0_0.Result == Ï„_1_0.Result> (@in Ï„_1_0, @in_guaranteed Ï„_0_0) -> () diff --git a/test/IRGen/async/run-partialapply-capture-inout-generic-and-in-generic-to-generic.sil b/test/IRGen/async/run-partialapply-capture-inout-generic-and-in-generic-to-generic.sil index 2e9fe56168f8c..c09bcb94ef04e 100644 --- a/test/IRGen/async/run-partialapply-capture-inout-generic-and-in-generic-to-generic.sil +++ b/test/IRGen/async/run-partialapply-capture-inout-generic-and-in-generic-to-generic.sil @@ -22,7 +22,7 @@ sil public_external @printInt64 : $@convention(thin) (Int64) -> () // CHECK-LL: @inGenericAndInoutGenericToGenericAD = // CHECK-LL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @inGenericAndInoutGenericToGeneric(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { -// CHECK-LL: define internal swiftcc void @"$s017inGenericAndInoutb2ToB0TA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s017inGenericAndInoutb2ToB0TA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil @inGenericAndInoutGenericToGeneric : $@async @convention(thin) (@in T, @inout T) -> @out T { entry(%out : $*T, %in : $*T, %inout : $*T): %printGeneric = function_ref @printGeneric : $@convention(thin) (@in_guaranteed T) -> () diff --git a/test/IRGen/async/run-partialapply-capture-int64-int64-throws-to-int64.sil b/test/IRGen/async/run-partialapply-capture-int64-int64-throws-to-int64.sil new file mode 100644 index 0000000000000..42961d66b1674 --- /dev/null +++ b/test/IRGen/async/run-partialapply-capture-int64-int64-throws-to-int64.sil @@ -0,0 +1,97 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift-dylib(%t/%target-library-name(PrintShims)) %S/../../Inputs/print-shims.swift -module-name PrintShims -emit-module -emit-module-path %t/PrintShims.swiftmodule +// RUN: %target-codesign %t/%target-library-name(PrintShims) +// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency -parse-sil %s -emit-ir -I %t -L %t -lPrintShim | %FileCheck %s --check-prefix=CHECK-LL +// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency -parse-sil %s -module-name main -o %t/main -I %t -L %t -lPrintShims %target-rpath(%t) +// RUN: %target-codesign %t/main +// RUN: %target-run %t/main %t/%target-library-name(PrintShims) | %FileCheck %s + +// REQUIRES: executable_test +// REQUIRES: swift_test_mode_optimize_none +// REQUIRES: concurrency +// UNSUPPORTED: use_os_stdlib +// UNSUPPORTED: CPU=arm64e + +import Builtin +import Swift +import PrintShims +import _Concurrency + +sil public_external @printGeneric : $@convention(thin) (@in_guaranteed T) -> () +sil public_external @printInt64 : $@convention(thin) (Int64) -> () + +sil hidden @createAndInvokeClosure : $@async @convention(thin) () -> () { +bb0: + %captured_literal = integer_literal $Builtin.Int64, 783247897 + %captured = struct $Int64 (%captured_literal : $Builtin.Int64) + %createPartialApply = function_ref @createPartialApply : $@async @convention(thin) (Int64) -> @owned @async @callee_guaranteed (Int64) -> (Int64, @error Error) + %partialApply = apply %createPartialApply(%captured) : $@async @convention(thin) (Int64) -> @owned @async @callee_guaranteed (Int64) -> (Int64, @error Error) + strong_retain %partialApply : $@async @callee_guaranteed (Int64) -> (Int64, @error Error) + %applied_literal = integer_literal $Builtin.Int64, 7823478 + %applied = struct $Int64 (%applied_literal : $Builtin.Int64) + try_apply %partialApply(%applied) : $@async @callee_guaranteed (Int64) -> (Int64, @error Error), normal success, error failure + +success(%sum : $Int64): + %printInt64 = function_ref @printInt64 : $@convention(thin) (Int64) -> () + %result = apply %printInt64(%sum) : $@convention(thin) (Int64) -> () // CHECK: 791071375 + br exit + +failure(%error : $Error): + br exit + +exit: + strong_release %partialApply : $@async @callee_guaranteed (Int64) -> (Int64, @error Error) + strong_release %partialApply : $@async @callee_guaranteed (Int64) -> (Int64, @error Error) + %out = tuple () + return %out : $() +} + +// CHECK-LL: @closureAD = +// CHECK-LL: define internal swiftcc void @closure(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} +// CHECK-LL: define internal swiftcc void @"$s7closureTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} +sil hidden @createPartialApply : $@async @convention(thin) (Int64) -> @owned @async @callee_guaranteed (Int64) -> (Int64, @error Error) { +bb0(%captured : $Int64): + %closure = function_ref @closure : $@async @convention(thin) (Int64, Int64) -> (Int64, @error Error) + %partialApply = partial_apply [callee_guaranteed] %closure(%captured) : $@async @convention(thin) (Int64, Int64) -> (Int64, @error Error) + return %partialApply : $@async @callee_guaranteed (Int64) -> (Int64, @error Error) +} + +sil private @closure : $@async @convention(thin) (Int64, Int64) -> (Int64, @error Error) { +bb0(%one : $Int64, %two : $Int64): + %printInt64 = function_ref @printInt64 : $@convention(thin) (Int64) -> () + %printInt64_1 = apply %printInt64(%one) : $@convention(thin) (Int64) -> () + %printInt64_2 = apply %printInt64(%two) : $@convention(thin) (Int64) -> () + %one_builtin = struct_extract %one : $Int64, #Int64._value + %two_builtin = struct_extract %two : $Int64, #Int64._value + %flag = integer_literal $Builtin.Int1, -1 + %sumAndOverflowed = builtin "sadd_with_overflow_Int64"(%one_builtin : $Builtin.Int64, %two_builtin : $Builtin.Int64, %flag : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %sum_builtin = tuple_extract %sumAndOverflowed : $(Builtin.Int64, Builtin.Int1), 0 + %overflowed = tuple_extract %sumAndOverflowed : $(Builtin.Int64, Builtin.Int1), 1 + cond_fail %overflowed : $Builtin.Int1, "arithmetic overflow" + %sum = struct $Int64 (%sum_builtin : $Builtin.Int64) + return %sum : $Int64 +} +// Defined in _Concurrency +sil public_external @$s12_Concurrency8runAsyncyyyyYcF : $@convention(thin) (@guaranteed @async @callee_guaranteed () -> ()) -> () + +sil @test_case : $@convention(thin) @async () -> () { + %createAndInvokeClosure = function_ref @createAndInvokeClosure : $@async @convention(thin) () -> () + %createAndInvokeClosure_result = apply %createAndInvokeClosure() : $@async @convention(thin) () -> () + + %void = tuple() + return %void : $() +} + +sil @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 { +bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>): + + %2 = function_ref @test_case : $@convention(thin) @async () -> () + %3 = thin_to_thick_function %2 : $@convention(thin) @async () -> () to $@async @callee_guaranteed () -> () + %4 = function_ref @$s12_Concurrency8runAsyncyyyyYcF : $@convention(thin) (@guaranteed @async @callee_guaranteed () -> ()) -> () + %5 = apply %4(%3) : $@convention(thin) (@guaranteed @async @callee_guaranteed () -> ()) -> () + + %6 = integer_literal $Builtin.Int32, 0 + %7 = struct $Int32 (%6 : $Builtin.Int32) + return %7 : $Int32 +} + diff --git a/test/IRGen/async/run-partialapply-capture-int64-int64-to-int64.sil b/test/IRGen/async/run-partialapply-capture-int64-int64-to-int64.sil index d796816bfcac0..df55ebf1a8ab4 100644 --- a/test/IRGen/async/run-partialapply-capture-int64-int64-to-int64.sil +++ b/test/IRGen/async/run-partialapply-capture-int64-int64-to-int64.sil @@ -39,7 +39,7 @@ bb0: // CHECK-LL: @closureAD = // CHECK-LL: define internal swiftcc void @closure(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} -// CHECK-LL: define internal swiftcc void @"$s7closureTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} +// CHECK-LL: define internal swiftcc void @"$s7closureTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} sil hidden @createPartialApply : $@async @convention(thin) (Int64) -> @owned @async @callee_guaranteed (Int64) -> Int64 { bb0(%captured : $Int64): %closure = function_ref @closure : $@async @convention(thin) (Int64, Int64) -> Int64 diff --git a/test/IRGen/async/run-partialapply-capture-int64-to-generic.sil b/test/IRGen/async/run-partialapply-capture-int64-to-generic.sil index 5ebd94cf6a372..180488f9d9247 100644 --- a/test/IRGen/async/run-partialapply-capture-int64-to-generic.sil +++ b/test/IRGen/async/run-partialapply-capture-int64-to-generic.sil @@ -26,8 +26,8 @@ bb0(%x : $Int32, %f : $@async @callee_owned (Int32) -> @out T): return %p : $@async @callee_owned () -> @out T } -// CHECK-LL: define internal swiftcc void @"$sTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { -// CHECK-LL: define internal swiftcc void @"$s6calleeTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$sTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s6calleeTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil @callee : $@async @convention(thin) (Int32, @in_guaranteed T) -> @out T { entry(%out_t : $*T, %x : $Int32, %in_t : $*T): %printGeneric = function_ref @printGeneric : $@convention(thin) (@in_guaranteed T) -> () diff --git a/test/IRGen/async/run-partialapply-capture-struct_classinstance_classinstance-and-int64-to-int64.sil b/test/IRGen/async/run-partialapply-capture-struct_classinstance_classinstance-and-int64-to-int64.sil index 1cfd096f7ce11..052c2f8c8f163 100644 --- a/test/IRGen/async/run-partialapply-capture-struct_classinstance_classinstance-and-int64-to-int64.sil +++ b/test/IRGen/async/run-partialapply-capture-struct_classinstance_classinstance-and-int64-to-int64.sil @@ -64,7 +64,7 @@ struct S { var x: C, y: C } // CHECK-LL: @structClassInstanceClassInstanceAndInt64ToInt64AD = // CHECK-LL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @structClassInstanceClassInstanceAndInt64ToInt64(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { -// CHECK-LL: define internal swiftcc void @"$s019structClassInstancebc10AndInt64ToE0TA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s019structClassInstancebc10AndInt64ToE0TA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil @structClassInstanceClassInstanceAndInt64ToInt64 : $@async @convention(thin) (Int64, @guaranteed S) -> Int64 { entry(%in : $Int64, %s : $S): %s_addr = alloc_stack $S diff --git a/test/IRGen/async/run-partialapply-capture-structgeneric_classinstance_to_struct_and_error.sil b/test/IRGen/async/run-partialapply-capture-structgeneric_classinstance_to_struct_and_error.sil index c93ef5dbdffea..7286331630346 100644 --- a/test/IRGen/async/run-partialapply-capture-structgeneric_classinstance_to_struct_and_error.sil +++ b/test/IRGen/async/run-partialapply-capture-structgeneric_classinstance_to_struct_and_error.sil @@ -54,7 +54,7 @@ entry(%a2_at_a3_addr : $*A2): } // CHECK-LL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @repo(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { -// CHECK-LL: define internal swiftcc void @"$s7amethodTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s7amethodTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil @repo : $@async @convention(thin) (@in_guaranteed A2) -> @owned @async @callee_guaranteed () -> (@owned A1, @error Error) { bb0(%0 : $*A2): %1 = load %0 : $*A2 diff --git a/test/IRGen/async/run-partialapply-capture-structgeneric_polymorphic_constrained-to-void.sil b/test/IRGen/async/run-partialapply-capture-structgeneric_polymorphic_constrained-to-void.sil index 20c22d8ae8130..41bcbeaa77559 100644 --- a/test/IRGen/async/run-partialapply-capture-structgeneric_polymorphic_constrained-to-void.sil +++ b/test/IRGen/async/run-partialapply-capture-structgeneric_polymorphic_constrained-to-void.sil @@ -33,7 +33,7 @@ sil_witness_table BaseProducer : Q module main { public class WeakBox {} sil_vtable WeakBox {} -// CHECK-LL: define internal swiftcc void @"$s7takingQTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s7takingQTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil hidden @takingQ : $@async @convention(thin) <Ï„_0_0 where Ï„_0_0 : Q> (@owned WeakBox<Ï„_0_0>) -> () { entry(%box : $WeakBox<Ï„_0_0>): %box_addr = alloc_stack $WeakBox<Ï„_0_0> diff --git a/test/IRGen/async/run-partialapply-capture-type_structgeneric_polymorphic_constrained-to-void.sil b/test/IRGen/async/run-partialapply-capture-type_structgeneric_polymorphic_constrained-to-void.sil index be23bdc652f0d..9f2112c2f8306 100644 --- a/test/IRGen/async/run-partialapply-capture-type_structgeneric_polymorphic_constrained-to-void.sil +++ b/test/IRGen/async/run-partialapply-capture-type_structgeneric_polymorphic_constrained-to-void.sil @@ -46,7 +46,7 @@ entry(%box : $WeakBox<Ï„_0_0>): } -// CHECK-LL: define internal swiftcc void @"$s7takingQTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s7takingQTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil public @bind_polymorphic_param_from_forwarder_parameter : $@async @convention(thin) <Ï„_0_1>(@in Ï„_0_1) -> @callee_owned @async (@owned WeakBox>) -> () { bb0(%0 : $*Ï„_0_1): %1 = alloc_ref $WeakBox> diff --git a/test/IRGen/async/run-partialapply-capture-type_thin-and-classinstance-to-void.sil b/test/IRGen/async/run-partialapply-capture-type_thin-and-classinstance-to-void.sil index ca545afb1956f..41ec9afe6d3da 100644 --- a/test/IRGen/async/run-partialapply-capture-type_thin-and-classinstance-to-void.sil +++ b/test/IRGen/async/run-partialapply-capture-type_thin-and-classinstance-to-void.sil @@ -62,7 +62,7 @@ sil_vtable C { struct S {} // CHECK-LL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @structtypeSAndClassinstanceCToVoid(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { -// CHECK-LL: define internal swiftcc void @"$s34structtypeSAndClassinstanceCToVoidTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}, %swift.refcounted* swiftself {{%[0-9]*}}) {{#[0-9]*}} { +// CHECK-LL: define internal swiftcc void @"$s34structtypeSAndClassinstanceCToVoidTA"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} { sil @structtypeSAndClassinstanceCToVoid : $@async @convention(thin) (@thin S.Type, @owned C) -> () { entry(%S_type: $@thin S.Type, %C_instance: $C): %S_type_addr = alloc_stack $@thick S.Type diff --git a/test/IRGen/class_update_callback_with_stub.swift b/test/IRGen/class_update_callback_with_stub.swift index c6d0d206d2182..0334be855da34 100644 --- a/test/IRGen/class_update_callback_with_stub.swift +++ b/test/IRGen/class_update_callback_with_stub.swift @@ -105,7 +105,7 @@ import resilient_objc_class // -- ... but they do appear in the stub list // CHECK-LABEL: @objc_class_stubs = internal global -// CHECK-SAME: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMs" +// CHECK-SAME: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMt" // CHECK-SAME: , section "__DATA,__objc_stublist,regular,no_dead_strip" // -- The category list @@ -128,7 +128,7 @@ import resilient_objc_class // -- Class symbol for NSObject-derived class points at the class stub -// CHECK: @"OBJC_CLASS_$__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass" = alias %objc_class_stub, %objc_class_stub* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMs" +// CHECK: @"OBJC_CLASS_$__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass" = alias %objc_class_stub, {{.*}} @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMt" // -- Metadata update callbacks referenced from class stubs diff --git a/test/IRGen/objc_generic_class_stub.swift b/test/IRGen/objc_generic_class_stub.swift new file mode 100644 index 0000000000000..5a1f742d0533a --- /dev/null +++ b/test/IRGen/objc_generic_class_stub.swift @@ -0,0 +1,21 @@ + +// RUN: %empty-directory(%t) +// RUN: %build-irgen-test-overlays +// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -primary-file %s -emit-ir | %FileCheck %s + +// REQUIRES: objc_interop + +// REQUIRES: rdar71476765 + +import Foundation + +public class GenericNSObjectSubclass : NSObject {} + +public class ConcreteNSObjectSubclass : GenericNSObjectSubclass {} + +// Note the stub here is internal; it's only purpose is to appear in the stub list +// so that it can be realized by objc_copyClassList(): + +// CHECK-LABEL: @"$s23objc_generic_class_stub24ConcreteNSObjectSubclassCMt" = internal global %objc_full_class_stub { i64 0, i64 1, %objc_class* (%objc_class*, i8*)* @"$s23objc_generic_class_stub24ConcreteNSObjectSubclassCMU" } + +// CHECK-LABEL: @objc_class_stubs = internal global {{.*}} @"$s23objc_generic_class_stub24ConcreteNSObjectSubclassCMt" {{.*}}, section "__DATA,__objc_stublist,regular,no_dead_strip" diff --git a/test/Interpreter/async.swift b/test/Interpreter/async.swift new file mode 100644 index 0000000000000..c7e79a812bf94 --- /dev/null +++ b/test/Interpreter/async.swift @@ -0,0 +1,41 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency %s -module-name main -o %t/main +// RUN: %target-codesign %t/main +// RUN: %target-run %t/main | %FileCheck %s + +// REQUIRES: concurrency +// UNSUPPORTED: use_os_stdlib +// UNSUPPORTED: CPU=arm64e + + +func sayHello() async { + print("hello") +} + +func sayGeneric(_ msg: T) async { + await sayHello() + print(msg) +} + +func sayWithClosure(_ action: () async -> ()) async { + await action() + print("hallo welt") +} + +runAsync { + // CHECK: hello + await sayHello() + + // CHECK: hello + // CHECK: world + await sayGeneric("world") + + + // CHECK: hello + // CHECK: and now in german + // CHECK: hallo welt + await sayWithClosure { + await sayHello() + print("and now in german") + } +} diff --git a/test/NameLookup/edge-cases.swift b/test/NameLookup/edge-cases.swift index cc0798480b43c..3ec6b4aafdadd 100644 --- a/test/NameLookup/edge-cases.swift +++ b/test/NameLookup/edge-cases.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift struct A {} struct B {} diff --git a/test/Parse/matching_patterns.swift b/test/Parse/matching_patterns.swift index abaf38e7aa06d..a2a34c75825b6 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 -disable-parser-lookup +// RUN: %target-typecheck-verify-swift -swift-version 4 -I %S/Inputs -enable-source-import import imported_enums diff --git a/test/Parse/matching_patterns_parser_lookup.swift b/test/Parse/matching_patterns_parser_lookup.swift deleted file mode 100644 index 172689808f50f..0000000000000 --- a/test/Parse/matching_patterns_parser_lookup.swift +++ /dev/null @@ -1,332 +0,0 @@ -// 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 7baf7e3ceb554..feea31d5caa7d 100644 --- a/test/Parse/switch.swift +++ b/test/Parse/switch.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift // TODO: Implement tuple equality in the library. // BLOCKED: diff --git a/test/Parse/switch_parser_lookup.swift b/test/Parse/switch_parser_lookup.swift deleted file mode 100644 index 34a6398d7869b..0000000000000 --- a/test/Parse/switch_parser_lookup.swift +++ /dev/null @@ -1,647 +0,0 @@ -// 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/SIL/ownership-verifier/load_borrow_invalidation_partial_apply.sil b/test/SIL/ownership-verifier/load_borrow_invalidation_partial_apply.sil index f5f8d2660eb73..3527c94749693 100644 --- a/test/SIL/ownership-verifier/load_borrow_invalidation_partial_apply.sil +++ b/test/SIL/ownership-verifier/load_borrow_invalidation_partial_apply.sil @@ -1,4 +1,5 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -inline %s -o /dev/null +// RUN: %target-sil-opt -enable-sil-verify-all -inline %s -verify-continue-on-failure=true -o /dev/null 2>&1 | %FileCheck %s +// REQUIRES: asserts // Tests here are patterns we should not consider as broken @@ -37,6 +38,7 @@ bb0(%0 : $*WrapperStruct): return %res : $() } +// CHECK-NOT: Function: 'caller1' sil [ossa] @caller1 : $@convention(thin) (@owned WrapperStruct) -> () { bb0(%0 : @owned $WrapperStruct): %stk = alloc_stack $WrapperStruct @@ -49,6 +51,9 @@ bb0(%0 : @owned $WrapperStruct): return %res : $() } +// CHECK-LABEL: Begin Error in function caller2 +// CHECK: SIL verification failed: Found load borrow that is invalidated by a local write?!: loadBorrowImmutabilityAnalysis.isImmutable(LBI) +// CHECK-LABEL: End Error in function caller2 sil [ossa] @caller2 : $@convention(thin) (@owned WrapperStruct) -> () { bb0(%0 : @owned $WrapperStruct): %stk = alloc_stack $WrapperStruct diff --git a/test/SILGen/async_builtins.swift b/test/SILGen/async_builtins.swift index f505123fac6cb..0df74f6ea3faf 100644 --- a/test/SILGen/async_builtins.swift +++ b/test/SILGen/async_builtins.swift @@ -25,4 +25,16 @@ public struct X { print("child is done") } } + + // CHECK-LABEL: sil hidden [ossa] @$s4test1XV12launchFutureyyxlF : $@convention(method) (@in_guaranteed T, X) -> () + func launchFuture(_ value: T) { + // CHECK: builtin "createAsyncTaskFuture"([[ZERO:%.*]] : $Int, [[NIL:%.*]] : $Optional, [[FN:%.*]] : $@async @callee_guaranteed @substituted <Ï„_0_0> () -> (@out Ï„_0_0, @error Error) for ) : $(Builtin.NativeObject, Builtin.RawPointer) + let task = Builtin.createAsyncTaskFuture(0, nil) { () async throws -> T in + return value + } + } + + public func launchRocker(closure: @escaping () async throws -> T) { + _ = Builtin.createAsyncTaskFuture(0, nil, closure) + } } diff --git a/test/SILOptimizer/load_borrow_verify.sil b/test/SILOptimizer/load_borrow_verify.sil index 143ea1b36341a..ae0c2b70c7538 100644 --- a/test/SILOptimizer/load_borrow_verify.sil +++ b/test/SILOptimizer/load_borrow_verify.sil @@ -76,4 +76,24 @@ bb0(%0 : @owned $AnyObject): dealloc_stack %1 : $*Optional %99 = tuple () return %99 : $() -} \ No newline at end of file +} + +// unchecked_ownership_conversion should not be considered a write to memory. +class ObjectWrapper { + var object: AnyObject +} + +// CHECK-LABEL: sil [ossa] @unchecked_ownership_conversion_test : $@convention(thin) (@guaranteed ObjectWrapper) -> @owned ObjectWrapper { +// CHECK: bb0(%0 : @guaranteed $ObjectWrapper): +// CHECK: load_borrow +// CHECK: unchecked_ownership_conversion %0 : $ObjectWrapper, @guaranteed to @owned +// CHECK: end_borrow +// CHECK-LABEL: } // end sil function 'unchecked_ownership_conversion_test' +sil [ossa] @unchecked_ownership_conversion_test : $@convention(thin) (@guaranteed ObjectWrapper) -> @owned ObjectWrapper { +bb0(%0 : @guaranteed $ObjectWrapper): + %1 = ref_element_addr %0 : $ObjectWrapper, #ObjectWrapper.object + %2 = load_borrow %1 : $*AnyObject + %3 = unchecked_ownership_conversion %0 : $ObjectWrapper, @guaranteed to @owned + end_borrow %2 : $AnyObject + return %3 : $ObjectWrapper +} diff --git a/test/Sema/diag_variable_used_in_initial.swift b/test/Sema/diag_variable_used_in_initial.swift index c60dc5c0dc0fa..b79c798877a13 100644 --- a/test/Sema/diag_variable_used_in_initial.swift +++ b/test/Sema/diag_variable_used_in_initial.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift class A1 { func foo1() -> Int {} diff --git a/test/Sema/diag_variable_used_in_initial_parser_lookup.swift b/test/Sema/diag_variable_used_in_initial_parser_lookup.swift deleted file mode 100644 index 6b2d7f900343e..0000000000000 --- a/test/Sema/diag_variable_used_in_initial_parser_lookup.swift +++ /dev/null @@ -1,56 +0,0 @@ -// 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/Sema/redeclaration-checking.swift b/test/Sema/redeclaration-checking.swift index fce87481f8783..8d5cedef565ee 100644 --- a/test/Sema/redeclaration-checking.swift +++ b/test/Sema/redeclaration-checking.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift // Test redeclaration checking in local context. diff --git a/test/decl/circularity.swift b/test/decl/circularity.swift index 29af1f663a23c..61d1272f843db 100644 --- a/test/decl/circularity.swift +++ b/test/decl/circularity.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift // 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 diff --git a/test/decl/circularity_parser_lookup.swift b/test/decl/circularity_parser_lookup.swift deleted file mode 100644 index be25472613ee6..0000000000000 --- a/test/decl/circularity_parser_lookup.swift +++ /dev/null @@ -1,114 +0,0 @@ -// 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/func/local-function-overload.swift b/test/decl/func/local-function-overload.swift index d5282632d8ed0..09d5948975337 100644 --- a/test/decl/func/local-function-overload.swift +++ b/test/decl/func/local-function-overload.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift func valid1() { func inner(_: Int) {} diff --git a/test/decl/typealias/generic.swift b/test/decl/typealias/generic.swift index 732800f558492..e8dfb69fef7b7 100644 --- a/test/decl/typealias/generic.swift +++ b/test/decl/typealias/generic.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift 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}} diff --git a/test/decl/typealias/generic_parser_lookup.swift b/test/decl/typealias/generic_parser_lookup.swift deleted file mode 100644 index 63c0cb22af2f0..0000000000000 --- a/test/decl/typealias/generic_parser_lookup.swift +++ /dev/null @@ -1,443 +0,0 @@ -// 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/variables.swift b/test/decl/var/variables.swift index e7a1ca04f05b9..538a7d7031a55 100644 --- a/test/decl/var/variables.swift +++ b/test/decl/var/variables.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift var t1 : Int var t2 = 10 diff --git a/test/decl/var/variables_parser_lookup.swift b/test/decl/var/variables_parser_lookup.swift deleted file mode 100644 index 8b2fa5c2aa080..0000000000000 --- a/test/decl/var/variables_parser_lookup.swift +++ /dev/null @@ -1,121 +0,0 @@ -// 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 605c00dcaccf1..98bb0a39090bc 100644 --- a/test/diagnostics/Localization/en_localization.swift +++ b/test/diagnostics/Localization/en_localization.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -localization-path %S/Inputs -locale en -disable-parser-lookup +// RUN: %target-typecheck-verify-swift -localization-path %S/Inputs -locale en _ = "HI! // expected-error@-1{{unterminated string literal}} diff --git a/test/diagnostics/Localization/en_localization_parser_lookup.swift b/test/diagnostics/Localization/en_localization_parser_lookup.swift deleted file mode 100644 index dd5ed8f861127..0000000000000 --- a/test/diagnostics/Localization/en_localization_parser_lookup.swift +++ /dev/null @@ -1,9 +0,0 @@ -// 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 c2acde077a92a..101ec8a3a0b79 100644 --- a/test/diagnostics/Localization/fr_localization.swift +++ b/test/diagnostics/Localization/fr_localization.swift @@ -1,7 +1,7 @@ // 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 -disable-parser-lookup +// RUN: %target-typecheck-verify-swift -localization-path %t -locale fr // 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! diff --git a/test/diagnostics/Localization/fr_localization_parser_lookup.swift b/test/diagnostics/Localization/fr_localization_parser_lookup.swift deleted file mode 100644 index b46efe97f06c2..0000000000000 --- a/test/diagnostics/Localization/fr_localization_parser_lookup.swift +++ /dev/null @@ -1,13 +0,0 @@ -// 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 2184a5d762fc5..83a66139a2722 100644 --- a/test/diagnostics/Localization/no_localization_files_and_wrong_path.swift +++ b/test/diagnostics/Localization/no_localization_files_and_wrong_path.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -localization-path /Not_exsisting_path -locale en -disable-parser-lookup +// RUN: %target-typecheck-verify-swift -localization-path /Not_exsisting_path -locale en // :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 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 deleted file mode 100644 index 88633ab4f03b3..0000000000000 --- a/test/diagnostics/Localization/no_localization_files_and_wrong_path_parser_lookup.swift +++ /dev/null @@ -1,11 +0,0 @@ -// 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 7feac3a7628b9..ef70a866ae6f6 100644 --- a/test/expr/closure/closures.swift +++ b/test/expr/closure/closures.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift var func6 : (_ fn : (Int,Int) -> Int) -> () var func6a : ((Int, Int) -> Int) -> () diff --git a/test/expr/closure/closures_parser_lookup.swift b/test/expr/closure/closures_parser_lookup.swift deleted file mode 100644 index 1ec9182c62d59..0000000000000 --- a/test/expr/closure/closures_parser_lookup.swift +++ /dev/null @@ -1,526 +0,0 @@ -// 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 d4dcbe24a27d1..308a52f5b43c7 100644 --- a/test/expr/expressions.swift +++ b/test/expr/expressions.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift //===----------------------------------------------------------------------===// // Tests and samples. diff --git a/test/expr/expressions_parser_lookup.swift b/test/expr/expressions_parser_lookup.swift deleted file mode 100644 index 582d59d7d5d12..0000000000000 --- a/test/expr/expressions_parser_lookup.swift +++ /dev/null @@ -1,947 +0,0 @@ -// 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/lit.cfg b/test/lit.cfg index 1983d4cf199b0..406e19badef2a 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -452,9 +452,6 @@ config.substitutions.append( ('%swift-dependency-tool', config.swift_dependency_ config.substitutions.append( ('%swift-syntax-test', config.swift_syntax_test) ) if 'syntax_parser_lib' in config.available_features: config.substitutions.append( ('%swift-syntax-parser-test', config.swift_syntax_parser_test) ) -# For testing on CI -if '-disable-parser-lookup' in config.swift_test_options: - config.available_features.add("disable-parser-lookup") config.substitutions.append( ('%swift-indent', config.swift_indent) ) config.substitutions.append( ('%llvm-link', config.llvm_link) ) config.substitutions.append( ('%swift-llvm-opt', config.swift_llvm_opt) ) diff --git a/test/stmt/statements.swift b/test/stmt/statements.swift index 2c1e4e5085bdd..b2cf3632f5808 100644 --- a/test/stmt/statements.swift +++ b/test/stmt/statements.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-parser-lookup +// RUN: %target-typecheck-verify-swift /* block comments */ /* /* nested too */ */ diff --git a/test/stmt/statements_parser_lookup.swift b/test/stmt/statements_parser_lookup.swift deleted file mode 100644 index caeb47ef5097a..0000000000000 --- a/test/stmt/statements_parser_lookup.swift +++ /dev/null @@ -1,723 +0,0 @@ -// 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/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp index a0398ae919818..c943ceff414bd 100644 --- a/tools/sil-opt/SILOpt.cpp +++ b/tools/sil-opt/SILOpt.cpp @@ -342,7 +342,6 @@ int main(int argc, char **argv) { // cache. Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath; Invocation.setParseStdlib(); - Invocation.getLangOptions().DisableParserLookup = true; Invocation.getLangOptions().DisableAvailabilityChecking = true; Invocation.getLangOptions().EnableAccessControl = false; Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false; diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt index e9079292919a5..1d182b4cb9d35 100644 --- a/unittests/Basic/CMakeLists.txt +++ b/unittests/Basic/CMakeLists.txt @@ -31,7 +31,6 @@ add_swift_unittest(SwiftBasicTests TaggedUnionTest.cpp ThreadSafeRefCntPointerTest.cpp TransformRangeTest.cpp - TreeScopedHashTableTest.cpp TypeLookupError.cpp UnicodeTest.cpp ValueEnumeratorTest.cpp diff --git a/unittests/Basic/TreeScopedHashTableTest.cpp b/unittests/Basic/TreeScopedHashTableTest.cpp deleted file mode 100644 index b9aa67c29b6f3..0000000000000 --- a/unittests/Basic/TreeScopedHashTableTest.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//===--- TreeScopedHashTableTest.cpp --------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "swift/Basic/TreeScopedHashTable.h" -#include "gtest/gtest.h" - -using namespace swift; - -TEST(TreeScopedHashTableTest, T1) { - using HashtableTy = TreeScopedHashTable; - using ScopeTy = HashtableTy::ScopeTy; - HashtableTy HT; - - auto S1 = new ScopeTy(HT, 0); - HT.insertIntoScope(*S1, 1, 1001); - HT.insertIntoScope(*S1, 2, 1002); - - auto S2 = new ScopeTy(HT, S1); - HT.insertIntoScope(*S2, 3, 2003); - HT.insertIntoScope(*S2, 4, 2004); - - EXPECT_EQ(1001U, HT.lookup(*S1, 1)); - EXPECT_EQ(1002U, HT.lookup(*S1, 2)); - EXPECT_EQ(0U, HT.lookup(*S1, 3)); - EXPECT_EQ(0U, HT.lookup(*S1, 4)); - - EXPECT_EQ(1001U, HT.lookup(*S2, 1)); - EXPECT_EQ(1002U, HT.lookup(*S2, 2)); - EXPECT_EQ(2003U, HT.lookup(*S2, 3)); - EXPECT_EQ(2004U, HT.lookup(*S2, 4)); - - delete S2; - delete S1; -} - -TEST(TreeScopedHashTableTest, T2) { - using HashtableTy = TreeScopedHashTable; - using ScopeTy = HashtableTy::ScopeTy; - HashtableTy HT; - - auto S1 = new ScopeTy(HT, 0); - HT.insertIntoScope(*S1, 1, 1001); - HT.insertIntoScope(*S1, 2, 1002); - - auto S2 = new ScopeTy(HT, S1); - HT.insertIntoScope(*S2, 3, 2003); - HT.insertIntoScope(*S2, 4, 2004); - - auto S3 = new ScopeTy(HT, S1); - HT.insertIntoScope(*S3, 1, 3001); - HT.insertIntoScope(*S3, 4, 3004); - - EXPECT_EQ(1001U, HT.lookup(*S1, 1)); - EXPECT_EQ(1002U, HT.lookup(*S1, 2)); - EXPECT_EQ(0U, HT.lookup(*S1, 3)); - EXPECT_EQ(0U, HT.lookup(*S1, 4)); - - EXPECT_EQ(1001U, HT.lookup(*S2, 1)); - EXPECT_EQ(1002U, HT.lookup(*S2, 2)); - EXPECT_EQ(2003U, HT.lookup(*S2, 3)); - EXPECT_EQ(2004U, HT.lookup(*S2, 4)); - - EXPECT_EQ(3001U, HT.lookup(*S3, 1)); - EXPECT_EQ(1002U, HT.lookup(*S3, 2)); - EXPECT_EQ(0U, HT.lookup(*S3, 3)); - EXPECT_EQ(3004U, HT.lookup(*S3, 4)); - - EXPECT_EQ(true, HT.count(*S3, 1)); - EXPECT_EQ(true, HT.count(*S3, 2)); - EXPECT_EQ(false, HT.count(*S3, 3)); - EXPECT_EQ(true, HT.count(*S3, 4)); - - delete S2; - - EXPECT_EQ(1001U, HT.lookup(*S1, 1)); - EXPECT_EQ(1002U, HT.lookup(*S1, 2)); - EXPECT_EQ(0U, HT.lookup(*S1, 3)); - EXPECT_EQ(0U, HT.lookup(*S1, 4)); - - EXPECT_EQ(3001U, HT.lookup(*S3, 1)); - EXPECT_EQ(1002U, HT.lookup(*S3, 2)); - EXPECT_EQ(0U, HT.lookup(*S3, 3)); - EXPECT_EQ(3004U, HT.lookup(*S3, 4)); - - delete S3; - - EXPECT_EQ(1001U, HT.lookup(*S1, 1)); - EXPECT_EQ(1002U, HT.lookup(*S1, 2)); - EXPECT_EQ(0U, HT.lookup(*S1, 3)); - EXPECT_EQ(0U, HT.lookup(*S1, 4)); - - delete S1; -} - -TEST(TreeScopedHashTableTest, IteratorTest) { - using HashtableTy = TreeScopedHashTable; - using ScopeTy = HashtableTy::ScopeTy; - HashtableTy HT; - - auto S1 = new ScopeTy(HT, 0); - HT.insertIntoScope(*S1, 1, 1001); - HT.insertIntoScope(*S1, 2, 1002); - - auto S2 = new ScopeTy(HT, S1); - HT.insertIntoScope(*S2, 1, 2001); - HT.insertIntoScope(*S2, 4, 2004); - - auto S3 = new ScopeTy(HT, S1); - HT.insertIntoScope(*S3, 1, 3001); - HT.insertIntoScope(*S3, 4, 3004); - - { - auto I = HT.begin(*S1, 1); - EXPECT_EQ(1001, *I); - I++; - EXPECT_EQ(HT.end(), I); - } - { - auto I = HT.begin(*S3, 1); - EXPECT_EQ(3001, *I); - I++; - EXPECT_EQ(1001, *I); - I++; - EXPECT_EQ(HT.end(), I); - } - - delete S3; - delete S2; - delete S1; -} - 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 deleted file mode 100644 index 93e2285cf083c..0000000000000 --- a/validation-test/compiler_crashers_2_fixed/0180-rdar45557325-parser-lookup.swift +++ /dev/null @@ -1,11 +0,0 @@ -// 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 af0f3b45e45d2..4058adff77613 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 -disable-parser-lookup +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -verify // REQUIRES: objc_interop diff --git a/validation-test/compiler_crashers_2_fixed/rdar71260862.swift b/validation-test/compiler_crashers_2_fixed/rdar71260862.swift index ee04cece7eccc..9c3721b32162c 100644 --- a/validation-test/compiler_crashers_2_fixed/rdar71260862.swift +++ b/validation-test/compiler_crashers_2_fixed/rdar71260862.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend %s -emit-ir -enable-library-evolution -enable-experimental-concurrency +// REQUIRES: concurrency public class X { public func f() async { }