From f8a3c3b1ff6c6095354d060dadd396bc47ab72fa Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Thu, 29 May 2025 13:49:12 -0700 Subject: [PATCH] [TypeCheckEffects] Fix `AbstractFunction::getType` to look through all levels of optional A member and a parameter could be wrapped in an arbitrary number of `Optional`, we need to look through all of them to get to the underlying function type. Resolves: rdar://151943924 (cherry picked from commit 86390ab91f3fabfbfbe490a363ab5ca206324c5d) --- lib/Sema/TypeCheckEffects.cpp | 5 ++--- .../rdar151943924.swift | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 validation-test/Sema/type_checker_crashers_fixed/rdar151943924.swift diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp index 6ae2b8c46a916..03278fceb32fd 100644 --- a/lib/Sema/TypeCheckEffects.cpp +++ b/lib/Sema/TypeCheckEffects.cpp @@ -386,7 +386,7 @@ class AbstractFunction { Type getType() const { switch (getKind()) { case Kind::Opaque: - return getOpaqueFunction()->getType()->lookThroughSingleOptionalType(); + return getOpaqueFunction()->getType()->lookThroughAllOptionalTypes(); case Kind::Function: { auto *AFD = getFunction(); if (AFD->hasImplicitSelfDecl() && AppliedSelf) @@ -395,8 +395,7 @@ class AbstractFunction { } case Kind::Closure: return getClosure()->getType(); case Kind::Parameter: - return getParameter()->getInterfaceType() - ->lookThroughSingleOptionalType(); + return getParameter()->getInterfaceType()->lookThroughAllOptionalTypes(); } llvm_unreachable("bad kind"); } diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar151943924.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar151943924.swift new file mode 100644 index 0000000000000..6b0cde035d736 --- /dev/null +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar151943924.swift @@ -0,0 +1,18 @@ +// RUN: %target-typecheck-verify-swift + +@propertyWrapper +struct Weak { + var wrappedValue: Value? { fatalError() } +} + +struct WeakStorage { + @Weak var action: ((Set) -> Void)?? +} + +final class Test { + var storage: WeakStorage = .init() + + func test(items: Set) { + storage.action??(items) + } +}