diff --git a/lib/Sema/CSOptimizer.cpp b/lib/Sema/CSOptimizer.cpp index aab3431df14bb..c822f51f5457a 100644 --- a/lib/Sema/CSOptimizer.cpp +++ b/lib/Sema/CSOptimizer.cpp @@ -1429,11 +1429,22 @@ static void determineBestChoicesInContext( } } - // If the parameter is `Any` we assume that all candidates are - // convertible to it, which makes it a perfect match. The solver - // would then decide whether erasing to an existential is preferable. - if (paramType->isAny()) - return 1; + if (paramType->isAnyExistentialType()) { + // If the parameter is `Any` we assume that all candidates are + // convertible to it, which makes it a perfect match. The solver + // would then decide whether erasing to an existential is preferable. + if (paramType->isAny()) + return 1; + + // If the parameter is `Any.Type` we assume that all metatype + // candidates are convertible to it. + if (auto *EMT = paramType->getAs()) { + if (EMT->getExistentialInstanceType()->isAny() && + (candidateType->is() || + candidateType->is())) + return 1; + } + } // Check if a candidate could be matched to a parameter by // an existential opening. diff --git a/test/Interpreter/issue-85020.swift b/test/Interpreter/issue-85020.swift new file mode 100644 index 0000000000000..f4bd32ce931fe --- /dev/null +++ b/test/Interpreter/issue-85020.swift @@ -0,0 +1,33 @@ +// RUN: %target-run-simple-swift | %FileCheck %s + +// https://github.com/swiftlang/swift/issues/85020 + +struct Store { + let theType: Any.Type + + init(of theType: Any.Type) { + print("init from TYPE: \(theType)") + self.theType = theType + } + + init(of instance: Any) { + print("init from VALUE: \(instance)") + self.init(of: type(of: instance)) + } +} + +let a: (any Numeric)? = 42 +print("a: \(type(of: a))") +// CHECK: a: Optional + +let storeA = Store(of: a!) +// CHECK-NEXT: init from VALUE: 42 +// CHECK-NEXT: init from TYPE: Int + +let b: (any Numeric.Type)? = type(of: 42) +print("b: \(type(of: b))") +// CHECK-NEXT: b: Optional + +let storeB = Store(of: b!) +// CHECK-NEXT: init from TYPE: Int +