diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 06723d7a3b931..77a00fc90fb6b 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -3362,6 +3362,9 @@ ERROR(override_class_declaration_in_extension,none, ERROR(override_with_more_effects,none, "cannot override non-%1 %0 with %1 %0", (DescriptiveDeclKind, StringRef)) +ERROR(override_typed_throws,none, + "%0 that throws %1 cannot override one that throws %2", + (DescriptiveDeclKind, Type, Type)) ERROR(override_throws_objc,none, "overriding a throwing @objc %select{method|initializer}0 with " "a non-throwing %select{method|initializer}0 is not supported", (bool)) diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 472a9f546fe6a..c896543ea964c 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -544,7 +544,7 @@ class ASTExtInfoBuilder { return bits == other.bits && (useClangTypes ? (clangTypeInfo == other.clangTypeInfo) : true) && globalActor.getPointer() == other.globalActor.getPointer() && - thrownError.getPointer() == thrownError.getPointer(); + thrownError.getPointer() == other.thrownError.getPointer(); } constexpr std::tuple diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index d7693f396d075..3d84b41f7af7e 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -3421,7 +3421,8 @@ static bool matchesFunctionType(CanAnyFunctionType fn1, CanAnyFunctionType fn2, if (matchMode.contains(TypeMatchFlags::AllowOverride)) { // Removing 'throwing' is ABI-compatible for synchronous functions, but // not for async ones. - if (ext2.isThrowing() && + if (ext2.isThrowing() && !ext1.isThrowing() && + ext2.getThrownError().isNull() && !(ext2.isAsync() && matchMode.contains(TypeMatchFlags::AllowABICompatible))) { ext1 = ext1.withThrows(true, ext2.getThrownError()); @@ -5065,6 +5066,28 @@ case TypeKind::Id: isUnchanged = false; } + llvm::Optional extInfo; + if (function->hasExtInfo()) { + extInfo = function->getExtInfo() + .withGlobalActor(globalActorType) + .withThrows(function->isThrowing(), thrownError); + + // If there was a generic thrown error and it substituted with + // 'any Error' or 'Never', map to 'throws' or non-throwing rather than + // maintaining the sugar. + if (auto origThrownError = function->getThrownError()) { + if (origThrownError->isTypeParameter() || + origThrownError->isTypeVariableOrMember()) { + // 'any Error' + if (thrownError->isEqual( + thrownError->getASTContext().getErrorExistentialType())) + extInfo = extInfo->withThrows(true, Type()); + else if (thrownError->isNever()) + extInfo = extInfo->withThrows(false, Type()); + } + } + } + if (auto genericFnType = dyn_cast(base)) { #ifndef NDEBUG // Check that generic parameters won't be transformed. @@ -5080,24 +5103,13 @@ case TypeKind::Id: if (isUnchanged) return *this; auto genericSig = genericFnType->getGenericSignature(); - if (!function->hasExtInfo()) - return GenericFunctionType::get(genericSig, substParams, resultTy); return GenericFunctionType::get( - genericSig, substParams, resultTy, - function->getExtInfo() - .withGlobalActor(globalActorType) - .withThrows(function->isThrowing(), thrownError)); + genericSig, substParams, resultTy, extInfo); } if (isUnchanged) return *this; - if (!function->hasExtInfo()) - return FunctionType::get(substParams, resultTy); - return FunctionType::get( - substParams, resultTy, - function->getExtInfo() - .withGlobalActor(globalActorType) - .withThrows(function->isThrowing(), thrownError)); + return FunctionType::get(substParams, resultTy, extInfo); } case TypeKind::ArraySlice: { diff --git a/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp b/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp index e6f6c6ff052e2..46186d6b55891 100644 --- a/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp +++ b/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp @@ -483,10 +483,11 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall, // targets must be taking a phi argument. SILBasicBlock *normalBB = forEachCall->getNormalBB(); SILBasicBlock *errorBB = forEachCall->getErrorBB(); - assert(errorBB->getSILPhiArguments().size() == 1 && - normalBB->getSILPhiArguments().size() == 1); + assert(normalBB->getSILPhiArguments().size() == 1); SILPhiArgument *normalArgument = normalBB->getSILPhiArguments()[0]; - SILPhiArgument *errorArgument = errorBB->getSILPhiArguments()[0]; + SILPhiArgument *errorArgument = nullptr; + if (errorBB->getSILPhiArguments().size() == 1) + errorArgument = errorBB->getSILPhiArguments()[0]; // A generator for creating a basic block for use as the target of the // "normal" branch of a try_apply. @@ -503,8 +504,12 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall, auto errorTargetGenerator = [&](SILBasicBlock *insertionBlock, SILValue borrowedElem, SILValue storeBorrow) { SILBasicBlock *newErrorBB = fun->createBasicBlockBefore(insertionBlock); - SILValue argument = newErrorBB->createPhiArgument( + SILValue argument; + if (errorArgument) { + argument = newErrorBB->createPhiArgument( errorArgument->getType(), errorArgument->getOwnershipKind()); + } + // Make the errorBB jump to the error target of the original forEach. SILBuilderWithScope builder(newErrorBB, forEachCall); if (storeBorrow) { @@ -513,7 +518,11 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall, if (borrowedElem) { builder.createEndBorrow(forEachLoc, borrowedElem); } - builder.createBranch(forEachLoc, errorBB, argument); + + if (argument) + builder.createBranch(forEachLoc, errorBB, argument); + else + builder.createBranch(forEachLoc, errorBB); return newErrorBB; }; diff --git a/lib/SILOptimizer/Mandatory/TransferNonSendable.cpp b/lib/SILOptimizer/Mandatory/TransferNonSendable.cpp index c50a44c724ad2..3dcb8939c2a13 100644 --- a/lib/SILOptimizer/Mandatory/TransferNonSendable.cpp +++ b/lib/SILOptimizer/Mandatory/TransferNonSendable.cpp @@ -647,7 +647,8 @@ class PartitionOpTranslator { if (auto tryApplyInst = dyn_cast(inst)) { foundResults.emplace_back(tryApplyInst->getNormalBB()->getArgument(0)); - foundResults.emplace_back(tryApplyInst->getErrorBB()->getArgument(0)); + if (tryApplyInst->getErrorBB()->getNumArguments() > 0) + foundResults.emplace_back(tryApplyInst->getErrorBB()->getArgument(0)); return; } diff --git a/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp index 06085700e4da5..10dbcc72165ad 100644 --- a/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp +++ b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp @@ -239,11 +239,19 @@ static FullApplySite speculateMonomorphicTarget(FullApplySite AI, // Split critical edges resulting from VirtAI. if (auto *TAI = dyn_cast(VirtAI)) { auto *ErrorBB = TAI->getFunction()->createBasicBlock(); - ErrorBB->createPhiArgument(TAI->getErrorBB()->getArgument(0)->getType(), - OwnershipKind::Owned); + SILArgument *ErrorArg = nullptr; + if (TAI->getErrorBB()->getNumArguments() == 1) { + ErrorArg = TAI->getErrorBB()->getArgument(0); + ErrorBB->createPhiArgument(ErrorArg->getType(), OwnershipKind::Owned); + } Builder.setInsertionPoint(ErrorBB); - Builder.createBranch(TAI->getLoc(), TAI->getErrorBB(), - {ErrorBB->getArgument(0)}); + + if (ErrorArg) { + Builder.createBranch(TAI->getLoc(), TAI->getErrorBB(), + {ErrorBB->getArgument(0)}); + } else { + Builder.createBranch(TAI->getLoc(), TAI->getErrorBB()); + } auto *NormalBB = TAI->getFunction()->createBasicBlock(); NormalBB->createPhiArgument(TAI->getNormalBB()->getArgument(0)->getType(), diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index d5d916ab3494b..474bdda2ae2f3 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -17,6 +17,7 @@ #include "TypeCheckAvailability.h" #include "TypeCheckConcurrency.h" #include "TypeCheckDecl.h" +#include "TypeCheckEffects.h" #include "TypeCheckObjC.h" #include "TypeChecker.h" #include "swift/AST/ASTVisitor.h" @@ -2036,16 +2037,54 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) { diags.diagnose(base, diag::overridden_here); } } - // If the overriding declaration is 'throws' but the base is not, - // complain. Do the same for 'async' + + // Check effects. if (auto overrideFn = dyn_cast(override)) { - if (overrideFn->hasThrows() && - !cast(base)->hasThrows()) { + // Determine the thrown errors in the base and override declarations. + auto baseFn = cast(base); + Type overrideThrownError = + overrideFn->getEffectiveThrownErrorType().value_or(ctx.getNeverType()); + Type baseThrownError = + baseFn->getEffectiveThrownErrorType().value_or(ctx.getNeverType()); + + if (baseThrownError && baseThrownError->hasTypeParameter()) { + auto subs = SubstitutionMap::getOverrideSubstitutions(base, override); + baseThrownError = baseThrownError.subst(subs); + baseThrownError = overrideFn->mapTypeIntoContext(baseThrownError); + } + + if (overrideThrownError) + overrideThrownError = overrideFn->mapTypeIntoContext(overrideThrownError); + + // Check for a subtyping relationship. + switch (compareThrownErrorsForSubtyping( + overrideThrownError, baseThrownError, overrideFn)) { + case ThrownErrorSubtyping::DropsThrows: diags.diagnose(override, diag::override_with_more_effects, override->getDescriptiveKind(), "throwing"); diags.diagnose(base, diag::overridden_here); + break; + + case ThrownErrorSubtyping::Mismatch: + diags.diagnose(override, diag::override_typed_throws, + override->getDescriptiveKind(), overrideThrownError, + baseThrownError); + diags.diagnose(base, diag::overridden_here); + break; + + case ThrownErrorSubtyping::ExactMatch: + case ThrownErrorSubtyping::Subtype: + // Proper subtyping. + break; + + case ThrownErrorSubtyping::Dependent: + // Only in already ill-formed code. + assert(ctx.Diags.hadAnyError()); + break; } + // If the override is 'async' but the base declaration is not, we have a + // problem. if (overrideFn->hasAsync() && !cast(base)->hasAsync()) { diags.diagnose(override, diag::override_with_more_effects, diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp index 0ae9263035c83..5217c8955975e 100644 --- a/lib/Sema/TypeCheckEffects.cpp +++ b/lib/Sema/TypeCheckEffects.cpp @@ -3549,6 +3549,13 @@ ThrownErrorSubtyping swift::compareThrownErrorsForSubtyping( Type subThrownError, Type superThrownError, DeclContext *dc ) { + // Deal with NULL errors. This should only occur when there is no standard + // library. + if (!subThrownError || !superThrownError) { + assert(!dc->getASTContext().getStdlibModule() && "NULL thrown error type"); + return ThrownErrorSubtyping::ExactMatch; + } + // Easy case: exact match. if (superThrownError->isEqual(subThrownError)) return ThrownErrorSubtyping::ExactMatch; diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index b069d1b06fe18..79310e935f230 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -298,7 +298,7 @@ endif() # STAGING: Temporarily avoids having to write #fileID in Swift.swiftinterface. list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-experimental-concise-pound-file") -list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Macros") +list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "TypedThrows") list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "FreestandingMacros") list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Extern") diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift index b16d4cdcef077..3a090d10f0a22 100644 --- a/stdlib/public/core/Collection.swift +++ b/stdlib/public/core/Collection.swift @@ -1190,9 +1190,10 @@ extension Collection { /// - Returns: An array containing the transformed elements of this /// sequence. @inlinable - public func map( - _ transform: (Element) throws -> T - ) rethrows -> [T] { + @_alwaysEmitIntoClient + public func map( + _ transform: (Element) throws(E) -> T + ) throws(E) -> [T] { // TODO: swift-3-indexing-model - review the following let n = self.count if n == 0 { @@ -1213,6 +1214,17 @@ extension Collection { return Array(result) } + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @usableFromInline + @_silgen_name("$sSlsE3mapySayqd__Gqd__7ElementQzKXEKlF") + func __rethrows_map( + _ transform: (Element) throws -> T + ) throws -> [T] { + try map(transform) + } + /// Returns a subsequence containing all but the given number of initial /// elements. /// diff --git a/stdlib/public/core/ExistentialCollection.swift b/stdlib/public/core/ExistentialCollection.swift index be20e2fdc8ebe..ac2b2e04626bc 100644 --- a/stdlib/public/core/ExistentialCollection.swift +++ b/stdlib/public/core/ExistentialCollection.swift @@ -175,7 +175,7 @@ internal class _AnySequenceBox { @inlinable internal func _map( _ transform: (Element) throws -> T - ) rethrows -> [T] { + ) throws -> [T] { _abstract() } @@ -525,8 +525,8 @@ internal final class _SequenceBox: _AnySequenceBox { @inlinable internal override func _map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _base.map(transform) + ) throws -> [T] { + try _base.map(transform) } @inlinable internal override func _filter( @@ -618,8 +618,8 @@ internal final class _CollectionBox: _AnyCollectionBox @inlinable internal override func _map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _base.map(transform) + ) throws -> [T] { + try _base.map(transform) } @inlinable internal override func _filter( @@ -813,8 +813,8 @@ internal final class _BidirectionalCollectionBox @inlinable internal override func _map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _base.map(transform) + ) throws -> [T] { + try _base.map(transform) } @inlinable internal override func _filter( @@ -1026,8 +1026,8 @@ internal final class _RandomAccessCollectionBox @inlinable internal override func _map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _base.map(transform) + ) throws -> [T] { + try _base.map(transform) } @inlinable internal override func _filter( @@ -1303,10 +1303,26 @@ extension AnySequence { } @inlinable - public func map( + @_alwaysEmitIntoClient + public func map( + _ transform: (Element) throws(E) -> T + ) throws(E) -> [T] { + do { + return try _box._map(transform) + } catch { + throw error as! E + } + } + + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @usableFromInline + @_silgen_name("$ss11AnySequenceV3mapySayqd__Gqd__xKXEKlF") + func __rethrows_map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _box._map(transform) + ) throws -> [T] { + try map(transform) } @inlinable @@ -1390,10 +1406,26 @@ extension AnyCollection { } @inlinable - public func map( + @_alwaysEmitIntoClient + public func map( + _ transform: (Element) throws(E) -> T + ) throws(E) -> [T] { + do { + return try _box._map(transform) + } catch { + throw error as! E + } + } + + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @usableFromInline + @_silgen_name("$ss13AnyCollectionV3mapySayqd__Gqd__xKXEKlF") + func __rethrows_map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _box._map(transform) + ) throws -> [T] { + try map(transform) } @inlinable @@ -1483,10 +1515,26 @@ extension AnyBidirectionalCollection { } @inlinable - public func map( + @_alwaysEmitIntoClient + public func map( + _ transform: (Element) throws(E) -> T + ) throws(E) -> [T] { + do { + return try _box._map(transform) + } catch { + throw error as! E + } + } + + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @usableFromInline + @_silgen_name("$ss26AnyBidirectionalCollectionV3mapySayqd__Gqd__xKXEKlF") + func __rethrows_map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _box._map(transform) + ) throws -> [T] { + try map(transform) } @inlinable @@ -1578,10 +1626,26 @@ extension AnyRandomAccessCollection { } @inlinable - public func map( + @_alwaysEmitIntoClient + public func map( + _ transform: (Element) throws(E) -> T + ) throws(E) -> [T] { + do { + return try _box._map(transform) + } catch { + throw error as! E + } + } + + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @usableFromInline + @_silgen_name("$ss25AnyRandomAccessCollectionV3mapySayqd__Gqd__xKXEKlF") + func __rethrows_map( _ transform: (Element) throws -> T - ) rethrows -> [T] { - return try _box._map(transform) + ) throws -> [T] { + try map(transform) } @inlinable diff --git a/stdlib/public/core/Misc.swift b/stdlib/public/core/Misc.swift index 7bdc22e3ed9d9..efb92d9e8c3f1 100644 --- a/stdlib/public/core/Misc.swift +++ b/stdlib/public/core/Misc.swift @@ -159,6 +159,17 @@ public func _unsafePerformance(_ c: () -> T) -> T { return c() } +// Helper function that exploits a bug in rethrows checking to +// allow us to call rethrows functions from generic typed-throws functions +// and vice-versa. +@usableFromInline +@_alwaysEmitIntoClient +@inline(__always) +func _rethrowsViaClosure(_ fn: () throws -> ()) rethrows { + try fn() +} + + /// This marker protocol represents types that support copying. /// This type is not yet available for use to express explicit /// constraints on generics in your programs. It is currently diff --git a/stdlib/public/core/Sequence.swift b/stdlib/public/core/Sequence.swift index a325dac5aafe5..d1afc0e1c2805 100644 --- a/stdlib/public/core/Sequence.swift +++ b/stdlib/public/core/Sequence.swift @@ -670,9 +670,10 @@ extension Sequence { /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable - public func map( - _ transform: (Element) throws -> T - ) rethrows -> [T] { + @_alwaysEmitIntoClient + public func map( + _ transform: (Element) throws(E) -> T + ) throws(E) -> [T] { let initialCapacity = underestimatedCount var result = ContiguousArray() result.reserveCapacity(initialCapacity) @@ -690,6 +691,17 @@ extension Sequence { return Array(result) } + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @usableFromInline + @_silgen_name("$sSTsE3mapySayqd__Gqd__7ElementQzKXEKlF") + func __rethrows_map( + _ transform: (Element) throws -> T + ) throws -> [T] { + try map(transform) + } + /// Returns an array containing, in order, the elements of the sequence /// that satisfy the given predicate. /// diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 594291a3239db..3cca710ba9565 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -1143,11 +1143,11 @@ struct R_76250381 { // https://github.com/apple/swift/issues/55926 (0..<10).map { x, y in } -// expected-error@-1 {{contextual closure type '(Range.Element) throws -> ()' (aka '(Int) throws -> ()') expects 1 argument, but 2 were used in closure body}} +// expected-error@-1 {{contextual closure type '(Range.Element) -> ()' (aka '(Int) -> ()') expects 1 argument, but 2 were used in closure body}} (0..<10).map { x, y, z in } -// expected-error@-1 {{contextual closure type '(Range.Element) throws -> ()' (aka '(Int) throws -> ()') expects 1 argument, but 3 were used in closure body}} +// expected-error@-1 {{contextual closure type '(Range.Element) -> ()' (aka '(Int) -> ()') expects 1 argument, but 3 were used in closure body}} (0..<10).map { x, y, z, w in } -// expected-error@-1 {{contextual closure type '(Range.Element) throws -> ()' (aka '(Int) throws -> ()') expects 1 argument, but 4 were used in closure body}} +// expected-error@-1 {{contextual closure type '(Range.Element) -> ()' (aka '(Int) -> ()') expects 1 argument, but 4 were used in closure body}} // rdar://77022842 - crash due to a missing argument to a ternary operator func rdar77022842(argA: Bool? = nil, argB: Bool? = nil) { @@ -1171,6 +1171,7 @@ func rdar76058892() { test { // expected-error {{contextual closure type '() -> String' expects 0 arguments, but 1 was used in closure body}} if let arr = arr { arr.map($0.test) // expected-note {{anonymous closure parameter '$0' is used here}} // expected-error {{generic parameter 'T' could not be inferred}} + // expected-error@-1 {{generic parameter 'E' could not be inferred}} } } } diff --git a/test/Constraints/enum_cases.swift b/test/Constraints/enum_cases.swift index 6d925378351a4..6408ed1b65700 100644 --- a/test/Constraints/enum_cases.swift +++ b/test/Constraints/enum_cases.swift @@ -19,14 +19,14 @@ enum G_E { let arr: [String] = [] let _ = arr.map(E.foo) // Ok let _ = arr.map(E.bar) // Ok -let _ = arr.map(E.two) // expected-error {{cannot convert value of type '(Int, Int) -> E' to expected argument type '(String) throws -> E'}} +let _ = arr.map(E.two) // expected-error {{cannot convert value of type '(Int, Int) -> E' to expected argument type '(String) -> E'}} -let _ = arr.map(E.tuple) // expected-error {{cannot convert value of type '((x: Int, y: Int)) -> E' to expected argument type '(String) throws -> E'}} +let _ = arr.map(E.tuple) // expected-error {{cannot convert value of type '((x: Int, y: Int)) -> E' to expected argument type '(String) -> E'}} let _ = arr.map(G_E.foo) // Ok let _ = arr.map(G_E.bar) // Ok -let _ = arr.map(G_E.two) // expected-error {{cannot convert value of type '(String, String) -> G_E' to expected argument type '(String) throws -> G_E'}} -let _ = arr.map(G_E.tuple) // expected-error {{cannot convert value of type '((x: Int, y: Int)) -> G_E' to expected argument type '(String) throws -> G_E'}} +let _ = arr.map(G_E.two) // expected-error {{cannot convert value of type '(String, String) -> G_E' to expected argument type '(String) -> G_E'}} +let _ = arr.map(G_E.tuple) // expected-error {{cannot convert value of type '((x: Int, y: Int)) -> G_E' to expected argument type '(String) -> G_E'}} let _ = E.foo("hello") // expected-error {{missing argument label 'bar:' in call}} let _ = E.bar("hello") // Ok diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift index d36e6f95bed15..5b34df8a9579f 100644 --- a/test/Constraints/tuple_arguments.swift +++ b/test/Constraints/tuple_arguments.swift @@ -1726,7 +1726,7 @@ do { do { func f(_: Int...) {} let _ = [(1, 2, 3)].map(f) // expected-error {{no exact matches in call to instance method 'map'}} - // expected-note@-1 {{found candidate with type '(((Int, Int, Int)) throws -> _) throws -> Array<_>'}} + // expected-note@-1 {{found candidate with type '(((Int, Int, Int)) -> _) -> Array<_>'}} } // rdar://problem/48443263 - cannot convert value of type '() -> Void' to expected argument type '(_) -> Void' diff --git a/test/IDE/complete_from_stdlib.swift b/test/IDE/complete_from_stdlib.swift index de35aa28046d3..bb7f11eea3b36 100644 --- a/test/IDE/complete_from_stdlib.swift +++ b/test/IDE/complete_from_stdlib.swift @@ -20,7 +20,7 @@ func protocolExtCollection1a(_ a: C) { a.#^PRIVATE_NOMINAL_MEMBERS_2A?check=PRIVATE_NOMINAL_MEMBERS_2A;check=NEGATIVE_PRIVATE_NOMINAL_MEMBERS_2A;check=NO_STDLIB_PRIVATE^# } -// PRIVATE_NOMINAL_MEMBERS_2A-DAG: Decl[InstanceMethod]/CurrNominal/IsSystem: map({#(transform): (C.Element) throws -> T##(C.Element) throws -> T#})[' rethrows'][#[T]#]; +// PRIVATE_NOMINAL_MEMBERS_2A-DAG: Decl[InstanceMethod]/CurrNominal/IsSystem: map({#(transform): (C.Element) throws(Error) -> T##(C.Element) throws(Error) -> T#})[' throws'][#[T]#]; // NEGATIVE_PRIVATE_NOMINAL_MEMBERS_2A-NOT: Decl{{.*}}: index({#before: any Comparable#}) func protocolExtCollection1b(_ a: Collection) { @@ -28,14 +28,14 @@ func protocolExtCollection1b(_ a: Collection) { } // FIXME(https://github.com/apple/swift/issues/65696): We should not be showing this because (1) it cannot be accessed on the existential (2) we don't have the syntax and features to represent the projected type sig anyway. -// PRIVATE_NOMINAL_MEMBERS_2B-DAG: map({#(transform): (any Collection.Element) throws -> T##(any Collection.Element) throws -> T#})[' rethrows'][#[T]#]{{; name=.+}} +// PRIVATE_NOMINAL_MEMBERS_2B-DAG: map({#(transform): (any Collection.Element) throws(Error) -> T##(any Collection.Element) throws(Error) -> T#})[' throws'][#[T]#]{{; name=.+}} // NEGATIVE_PRIVATE_NOMINAL_MEMBERS_2B-NOT: Decl{{.*}}: index({#before: any Comparable#}) func protocolExtCollection2(_ a: C) { a.#^PRIVATE_NOMINAL_MEMBERS_3?check=PRIVATE_NOMINAL_MEMBERS_3;check=NEGATIVE_PRIVATE_NOMINAL_MEMBERS_3;check=NO_STDLIB_PRIVATE^# } -// PRIVATE_NOMINAL_MEMBERS_3-DAG: Decl[InstanceMethod]/Super/IsSystem: map({#(transform): (C.Element) throws -> T##(C.Element) throws -> T#})[' rethrows'][#[T]#]{{; name=.+}} +// PRIVATE_NOMINAL_MEMBERS_3-DAG: Decl[InstanceMethod]/Super/IsSystem: map({#(transform): (C.Element) throws(Error) -> T##(C.Element) throws(Error) -> T#})[' throws'][#[T]#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_3-DAG: Decl[InstanceVar]/Super/IsSystem: lazy[#LazySequence#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_3-DAG: firstIndex({#where: (C.Element) throws -> Bool##(C.Element) throws -> Bool#})[' rethrows'][#Comparable?#]{{; name=.+}} // NEGATIVE_PRIVATE_NOMINAL_MEMBERS_3-NOT: Decl{{.*}}: firstIndex({#({{.*}}): Self.Iterator.Element @@ -43,7 +43,7 @@ func protocolExtCollection2(_ func protocolExtArray(_ a: [T]) { a.#^PRIVATE_NOMINAL_MEMBERS_4?check=PRIVATE_NOMINAL_MEMBERS_4;check=NO_STDLIB_PRIVATE^# } -// PRIVATE_NOMINAL_MEMBERS_4-DAG: Decl[InstanceMethod]/Super/IsSystem: map({#(transform): (Equatable) throws -> T##(Equatable) throws -> T#})[' rethrows'][#[T]#]{{; name=.+}} +// PRIVATE_NOMINAL_MEMBERS_4-DAG: Decl[InstanceMethod]/Super/IsSystem: map({#(transform): (Equatable) throws(Error) -> T##(Equatable) throws(Error) -> T#})[' throws'][#[T]#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_4-DAG: Decl[InstanceVar]/Super/IsSystem: last[#Equatable?#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_4-DAG: Decl[InstanceMethod]/Super/IsSystem: firstIndex({#of: Equatable#})[#Int?#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_4-DAG: Decl[InstanceMethod]/Super/IsSystem: firstIndex({#where: (Equatable) throws -> Bool##(Equatable) throws -> Bool#})[' rethrows'][#Int?#]{{; name=.+}} @@ -85,7 +85,7 @@ func testArchetypeReplacement3 (_ a : [Int]) { // PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/CurrNominal/IsSystem: append({#(newElement): Int#})[#Void#] // PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super/IsSystem: removeLast()[#Int#] // PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceVar]/Super/IsSystem: first[#Int?#] -// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super/IsSystem: map({#(transform): (Int) throws -> T##(Int) throws -> T#})[' rethrows'][#[T]#] +// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super/IsSystem: map({#(transform): (Int) throws(Error) -> T##(Int) throws(Error) -> T#})[' throws'][#[T]#] // PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super/IsSystem: dropLast({#(k): Int#})[#ArraySlice#] // PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super/IsSystem: elementsEqual({#(other): Sequence#}, {#by: (Int, Sequence.Element) throws -> Bool##(Int, Sequence.Element) throws -> Bool#})[' rethrows'][#Bool#]; name=elementsEqual(:by:) // PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super/IsSystem: elementsEqual({#(other): Sequence#})[#Bool#]; name=elementsEqual(:) diff --git a/test/IRGen/protocol_synthesized.swift b/test/IRGen/protocol_synthesized.swift index f21979914709e..6fdb1955a7595 100644 --- a/test/IRGen/protocol_synthesized.swift +++ b/test/IRGen/protocol_synthesized.swift @@ -10,6 +10,9 @@ import SynthesizedProtocol +enum Never { } +protocol Error { } + // CHECK: @"$sSo5Flagsas9OptionSetSCMc" = linkonce_odr hidden constant { i32, i32, i32, i32, i16, i16, i32, i32 } { i32 {{(trunc \(i64 )?}}sub ({{i(32|64)}} ptrtoint (ptr @"$ss9OptionSetMp" to {{i(32|64)}}), {{i(32|64)}} ptrtoint (ptr @"$sSo5Flagsas9OptionSetSCMc" to {{i(32|64)}})){{( to i32\))?}}, i32 {{(trunc \(i64 )?}}sub ({{i(32|64)}} ptrtoint (ptr @"$sSo5FlagsaMn" to {{i(32|64)}}), {{i(32|64)}} ptrtoint (ptr getelementptr inbounds ({ i32, i32, i32, i32, i16, i16, i32, i32 }, ptr @"$sSo5Flagsas9OptionSetSCMc", i32 0, i32 1) to {{i(32|64)}})){{( to i32\))?}}, i32 {{(trunc \(i64 )?}}sub ({{i(32|64)}} ptrtoint (ptr @"$sSo5Flagsas9OptionSetSCWP" to {{i(32|64)}}), {{i(32|64)}} ptrtoint (ptr getelementptr inbounds ({ i32, i32, i32, i32, i16, i16, i32, i32 }, ptr @"$sSo5Flagsas9OptionSetSCMc", i32 0, i32 2) to {{i(32|64)}})){{( to i32\))?}}, i32 131200, i16 3, i16 1, i32 {{(trunc \(i64 )?}}sub ({{i(32|64)}} ptrtoint (ptr @"$sSo5Flagsas9OptionSetSCWI" to {{i(32|64)}}), {{i(32|64)}} ptrtoint (ptr getelementptr inbounds ({ i32, i32, i32, i32, i16, i16, i32, i32 }, ptr @"$sSo5Flagsas9OptionSetSCMc", i32 0, i32 6) to {{i(32|64)}})){{( to i32\))?}}, i32 {{(trunc \(i64 )?}}sub ({{i(32|64)}} ptrtoint (ptr @"$sSo5Flagsas9OptionSetSCMcMK" to {{i(32|64)}}), {{i(32|64)}} ptrtoint (ptr getelementptr inbounds ({ i32, i32, i32, i32, i16, i16, i32, i32 }, ptr @"$sSo5Flagsas9OptionSetSCMc", i32 0, i32 7) to {{i(32|64)}})) {{(to i32\) )?}}}, section "{{[^"]*}}"{{(, comdat)?}},{{.*}} align 4 // Triggers the inclusion of the relevant ProtocolConformanceDescriptor diff --git a/test/SIL/OwnershipVerifier/definite_init.sil b/test/SIL/OwnershipVerifier/definite_init.sil index e2a25d56e1836..f557e5e30b68d 100644 --- a/test/SIL/OwnershipVerifier/definite_init.sil +++ b/test/SIL/OwnershipVerifier/definite_init.sil @@ -5,6 +5,9 @@ sil_stage raw import Builtin +enum Never { } +protocol Error { } + enum Optional { case some(T) case none diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift index 0a1ccae288b51..64321fa5dd375 100644 --- a/test/SILGen/function_conversion.swift +++ b/test/SILGen/function_conversion.swift @@ -663,14 +663,14 @@ struct FunctionConversionParameterSubstToOrigReabstractionTest { } } -// CHECK: sil {{.*}} [ossa] @$sS4SIgggoo_S2Ss11AnyHashableVyps5Error_pIegggrrzo_TR +// CHECK: sil {{.*}} [ossa] @$sS4SIgggoo_S2Ss11AnyHashableVypIegggrr_TR // CHECK: [[TUPLE:%.*]] = apply %4(%2, %3) : $@noescape @callee_guaranteed (@guaranteed String, @guaranteed String) -> (@owned String, @owned String) // CHECK: ([[LHS:%.*]], [[RHS:%.*]]) = destructure_tuple [[TUPLE]] // CHECK: [[ADDR:%.*]] = alloc_stack $String // CHECK: store [[LHS]] to [init] [[ADDR]] : $*String // CHECK: [[CVT:%.*]] = function_ref @$ss21_convertToAnyHashableys0cD0VxSHRzlF : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0) -> @out AnyHashable // CHECK: apply [[CVT]](%0, [[ADDR]]) -// CHECK: } // end sil function '$sS4SIgggoo_S2Ss11AnyHashableVyps5Error_pIegggrrzo_TR' +// CHECK: } // end sil function '$sS4SIgggoo_S2Ss11AnyHashableVypIegggrr_TR' func dontCrash() { let userInfo = ["hello": "world"] diff --git a/test/SILGen/opaque_values_silgen.swift b/test/SILGen/opaque_values_silgen.swift index 28c21de9324f6..739ddff7d6328 100644 --- a/test/SILGen/opaque_values_silgen.swift +++ b/test/SILGen/opaque_values_silgen.swift @@ -365,8 +365,16 @@ public struct EnumSeq : Seq { } extension Collection { + func myMap(_ body: (Element) -> T) -> [T] { + var result = [T]() + for element in self { + result.append(body(element)) + } + return result + } + func transformEachElement(_ cl: (Element) -> U) -> [U] { - return map(cl) + return myMap(cl) } } diff --git a/test/SILGen/partial_apply_override.swift b/test/SILGen/partial_apply_override.swift index c84540bb2bb99..915c1b84ede3a 100644 --- a/test/SILGen/partial_apply_override.swift +++ b/test/SILGen/partial_apply_override.swift @@ -26,11 +26,9 @@ public func convert(strings: [String]) -> [Int] { // CHECK-NEXT: // function_ref // CHECK-NEXT: [[CURRY_THUNK:%.*]] = function_ref @$s22partial_apply_override7convert7stringsSaySiGSaySSG_tFSiSScAA18StringIntConverterCcfu_ : $@convention(thin) (@guaranteed StringIntConverter) -> @owned @callee_guaranteed (@guaranteed String) -> Int // CHECK-NEXT: [[CURRY_RESULT:%.*]] = apply [[CURRY_THUNK]]([[CONVERTER]]) -// CHECK: [[CONVERTED:%.*]] = convert_function [[CURRY_RESULT]] -// CHECK: [[NOESCAPE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CONVERTED]] +// CHECK: [[NOESCAPE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CURRY_RESULT]] // CHECK: // function_ref -// CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sSSSis5Error_pIggdzo_SSSisAA_pIegnrzo_TR : $@convention(thin) (@in_guaranteed String, @guaranteed @noescape @callee_guaranteed (@guaranteed String) -> (Int, @error any Error)) -> (@out Int, @error any Error) -// CHECK-NEXT: [[REABSTRACTED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[NOESCAPE]]) +// CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sSSSiIggd_SSSis5NeverOIegnrzr_TR : $@convention(thin) (@in_guaranteed String, @guaranteed @noescape @callee_guaranteed (@guaranteed String) -> Int) -> (@out Int, @error_indirect Never) // CHECK-LABEL: sil private [ossa] @$s22partial_apply_override7convert7stringsSaySiGSaySSG_tFSiSScAA18StringIntConverterCcfu_SiSScfu0_ : $@convention(thin) (@guaranteed String, @guaranteed StringIntConverter) -> Int // CHECK: [[METHOD:%.*]] = class_method %1 : $StringIntConverter, #StringIntConverter.convert : (StringIntConverter) -> (String) -> Int, $@convention(method) (@in_guaranteed String, @guaranteed StringIntConverter) -> @out Int diff --git a/test/SILGen/typed_throws.swift b/test/SILGen/typed_throws.swift index 6170e5112ab5b..78e0f107d0a71 100644 --- a/test/SILGen/typed_throws.swift +++ b/test/SILGen/typed_throws.swift @@ -126,4 +126,24 @@ open class MyClass { // CHECK-NEXT: throw_addr public init(body: () throws(E) -> Void) throws(E) { } + + func f() throws { } +} + +// CHECK-LABEL: sil_vtable MySubclass { +// CHECK-NEXT: #MyClass.init!allocator: (MyClass.Type) -> (() throws(E) -> ()) throws(E) -> MyClass : @$s12typed_throws10MySubclassC4bodyACyyxYKXE_txYKcs5ErrorRzlufC [override] +// CHECK-NEXT: #MyClass.f: (MyClass) -> () throws -> () : @$s12typed_throws10MySubclassC1fyyAA0C5ErrorOYKFAA0C5ClassCADyyKFTV [override] +// CHECK-NEXT: #MySubclass.f: (MySubclass) -> () throws(MyError) -> () : @$s12typed_throws10MySubclassC1fyyAA0C5ErrorOYKF + +class MySubclass: MyClass { + override func f() throws(MyError) { } +} + +// CHECK-LABEL: sil_vtable MySubsubclass +// CHECK-NEXT: #MyClass.init!allocator: (MyClass.Type) -> (() throws(E) -> ()) throws(E) -> MyClass : @$s12typed_throws13MySubsubclassC4bodyACyyxYKXE_txYKcs5ErrorRzlufC [override] +// CHECK-NEXT: #MyClass.f: (MyClass) -> () throws -> () : @$s12typed_throws13MySubsubclassC1fyyF [override] +// CHECK-NEXT: #MySubclass.f: (MySubclass) -> () throws(MyError) -> () : @$s12typed_throws13MySubsubclassC1fyyF [override] +// CHECK-NEXT: #MySubsubclass.f: (MySubsubclass) -> () -> () : @$s12typed_throws13MySubsubclassC1fyyF +class MySubsubclass: MySubclass { + override func f() { } } diff --git a/test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected index 3a93963485761..6402a5ea5b752 100644 --- a/test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected @@ -26,5 +26,17 @@ Func Unicode.UTF32.Parser.parseScalar(from:) has generic signature change from < Func Unicode.UTF32.decode(_:) has generic signature change from to Func Unicode.UTF8.decode(_:) has generic signature change from to Constructor Mirror.init(_:children:displayStyle:ancestorRepresentation:) has generic signature change from to +Func AnyBidirectionalCollection.map(_:) has generic signature change from to +Func AnyBidirectionalCollection.map(_:) is now without @rethrows +Func AnyCollection.map(_:) has generic signature change from to +Func AnyCollection.map(_:) is now without @rethrows +Func AnyRandomAccessCollection.map(_:) has generic signature change from to +Func AnyRandomAccessCollection.map(_:) is now without @rethrows +Func AnySequence.map(_:) has generic signature change from to +Func AnySequence.map(_:) is now without @rethrows +Func Collection.map(_:) has generic signature change from to +Func Collection.map(_:) is now without @rethrows +Func Sequence.map(_:) has generic signature change from to +Func Sequence.map(_:) is now without @rethrows Protocol SIMDScalar has generic signature change from to diff --git a/test/api-digester/stability-stdlib-abi-without-asserts.test b/test/api-digester/stability-stdlib-abi-without-asserts.test index f487f9ce222f9..735506b7dfe88 100644 --- a/test/api-digester/stability-stdlib-abi-without-asserts.test +++ b/test/api-digester/stability-stdlib-abi-without-asserts.test @@ -60,12 +60,18 @@ Func _swift_retainCount(_:) is a new API without @available attribute Func _swift_unownedRetainCount(_:) is a new API without @available attribute Func _swift_weakRetainCount(_:) is a new API without @available attribute +Func Collection.map(_:) has been renamed to Func __rethrows_map(_:) +Func Collection.map(_:) has mangled name changing from '(extension in Swift):Swift.Collection.map((A.Element) throws -> A1) throws -> Swift.Array' to '(extension in Swift):Swift.Collection.__rethrows_map((A.Element) throws -> A1) throws -> Swift.Array' +Func Collection.map(_:) is now without @rethrows Func Collection.removingSubranges(_:) has been removed Func Collection.subranges(of:) has been removed Func Collection.subranges(where:) has been removed Func MutableCollection.moveSubranges(_:to:) has been removed Func MutableCollection.removeSubranges(_:) has been removed Func RangeReplaceableCollection.removeSubranges(_:) has been removed +Func Sequence.map(_:) has been renamed to Func __rethrows_map(_:) +Func Sequence.map(_:) has mangled name changing from '(extension in Swift):Swift.Sequence.map((A.Element) throws -> A1) throws -> Swift.Array' to '(extension in Swift):Swift.Sequence.__rethrows_map((A.Element) throws -> A1) throws -> Swift.Array' +Func Sequence.map(_:) is now without @rethrows Struct AnyHashable has added a conformance to an existing protocol _HasCustomAnyHashableRepresentation Class AnyKeyPath has added a conformance to an existing protocol CustomDebugStringConvertible Class KeyPath has added a conformance to an existing protocol CustomDebugStringConvertible @@ -85,6 +91,18 @@ Constructor _SmallString.init(taggedCocoa:) has return type change from Swift._S Enum Never has added a conformance to an existing protocol Decodable Enum Never has added a conformance to an existing protocol Encodable Enum Never has added a conformance to an existing protocol Identifiable +Func AnyBidirectionalCollection.map(_:) has been renamed to Func __rethrows_map(_:) +Func AnyBidirectionalCollection.map(_:) has mangled name changing from 'Swift.AnyBidirectionalCollection.map((A) throws -> A1) throws -> Swift.Array' to 'Swift.AnyBidirectionalCollection.__rethrows_map((A) throws -> A1) throws -> Swift.Array' +Func AnyBidirectionalCollection.map(_:) is now without @rethrows +Func AnyCollection.map(_:) has been renamed to Func __rethrows_map(_:) +Func AnyCollection.map(_:) has mangled name changing from 'Swift.AnyCollection.map((A) throws -> A1) throws -> Swift.Array' to 'Swift.AnyCollection.__rethrows_map((A) throws -> A1) throws -> Swift.Array' +Func AnyCollection.map(_:) is now without @rethrows +Func AnyRandomAccessCollection.map(_:) has been renamed to Func __rethrows_map(_:) +Func AnyRandomAccessCollection.map(_:) has mangled name changing from 'Swift.AnyRandomAccessCollection.map((A) throws -> A1) throws -> Swift.Array' to 'Swift.AnyRandomAccessCollection.__rethrows_map((A) throws -> A1) throws -> Swift.Array' +Func AnyRandomAccessCollection.map(_:) is now without @rethrows +Func AnySequence.map(_:) has been renamed to Func __rethrows_map(_:) +Func AnySequence.map(_:) has mangled name changing from 'Swift.AnySequence.map((A) throws -> A1) throws -> Swift.Array' to 'Swift.AnySequence.__rethrows_map((A) throws -> A1) throws -> Swift.Array' +Func AnySequence.map(_:) is now without @rethrows // These haven't actually been removed; they are simply marked unavailable. // This seems to be a false positive in the ABI checker. This is not an ABI @@ -110,6 +128,11 @@ Func UnsafeBufferPointer.withMemoryRebound(to:_:) has been removed Func UnsafeMutableBufferPointer.withMemoryRebound(to:_:) has been removed Func UnsafeMutablePointer.withMemoryRebound(to:capacity:_:) has been removed Func UnsafePointer.withMemoryRebound(to:capacity:_:) has been removed +Func _AnySequenceBox._map(_:) is now without @rethrows +Func _BidirectionalCollectionBox._map(_:) is now without @rethrows +Func _CollectionBox._map(_:) is now without @rethrows +Func _RandomAccessCollectionBox._map(_:) is now without @rethrows +Func _SequenceBox._map(_:) is now without @rethrows Func UnsafeMutableRawBufferPointer.storeBytes(of:toByteOffset:as:) has been removed Func UnsafeMutableRawPointer.storeBytes(of:toByteOffset:as:) has been removed Func UnsafeMutableBufferPointer.assign(repeating:) has been removed diff --git a/test/decl/class/typed_throws_override.swift b/test/decl/class/typed_throws_override.swift new file mode 100644 index 0000000000000..68d060c5025d0 --- /dev/null +++ b/test/decl/class/typed_throws_override.swift @@ -0,0 +1,58 @@ +// RUN: %target-typecheck-verify-swift -parse-as-library -enable-experimental-feature TypedThrows + +enum MyError: Error { +case failed +} + +enum HomeworkError: Error { +case dogAteIt +} + +class SuperError: Error { } +class SubError: SuperError { } + +class Super { + func f() throws { } + func g() throws(MyError) { } + func h() throws(HomeworkError) { } // expected-note{{overridden declaration is here}} + func i() throws(SuperError) { } + + var propF: Int { + get throws { 5 } + } + + var propG: Int { + get throws(MyError) { 5 } + } + + var propH: Int { + get throws(HomeworkError) { 5 } // expected-note{{overridden declaration is here}} + } + + var propI: Int { + get throws(SuperError) { 5 } + } +} + +class Sub: Super { + override func f() throws(MyError) { } // okay to make type more specific + override func g() { } // okay to be non-throwing + override func h() throws(MyError) { } // expected-error{{instance method that throws 'MyError' cannot override one that throws 'HomeworkError'}} + override func i() throws(SubError) { } // okay to have a subtype + + override var propF: Int { + get throws(MyError) { 5 } // okay to make type more specific + } + + override var propG: Int { + get { 5 } // okay to be non-throwing + } + + override var propH: Int { + get throws(MyError) { 5 } // expected-error{{getter that throws 'MyError' cannot override one that throws 'HomeworkError'}} + } + + override var propI: Int { + get throws(SubError) { 5 } // okay to make type more specific + } +} diff --git a/test/decl/func/typed_throws.swift b/test/decl/func/typed_throws.swift index d293d7fb85dc4..df45a6eda6357 100644 --- a/test/decl/func/typed_throws.swift +++ b/test/decl/func/typed_throws.swift @@ -179,3 +179,14 @@ func fromRethrows(body: () throws -> Void) rethrows { try notRethrowsLike2(body) // expected-error{{call can throw, but the error is not handled; a function declared 'rethrows' may only throw if its parameter does}} try notRethrowsLike3(body) // expected-error{{call can throw, but the error is not handled; a function declared 'rethrows' may only throw if its parameter does}} } + +// Substitution involving 'any Error' or 'Never' thrown error types should +// use untyped throws or be non-throwing. +enum G_E { + case tuple((x: T, y: T)) +} + +func testArrMap(arr: [String]) { + _ = mapArray(arr, body: G_E.tuple) + // expected-error@-1{{cannot convert value of type '((x: Int, y: Int)) -> G_E' to expected argument type '(String) -> G_E'}} +}