From d16a213c1d52370845337e5c62eb6e60dd709b77 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Thu, 5 Dec 2024 07:20:46 +0100 Subject: [PATCH] SILVerifier: fix a wrong check for witness_method instructions Consider that the lookup-type can be an opaque return type. Also fixing the SILPrinter. Fixes a verifier crash https://github.com/swiftlang/swift/issues/77955 140939536 --- lib/SIL/IR/SILPrinter.cpp | 5 +-- lib/SIL/Verifier/SILVerifier.cpp | 2 +- .../propagate_opaque_return_type.swift | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/SILOptimizer/propagate_opaque_return_type.swift diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 7112ac3fd3a16..5d7b5b8924d01 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -2520,10 +2520,11 @@ class SILPrinter : public SILInstructionVisitor { PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType(); QualifiedSILTypeOptions.CurrentModule = WMI->getModule().getSwiftModule(); - *this << "$" << WMI->getLookupType() << ", " << WMI->getMember() << " : "; + auto lookupType = WMI->getLookupType(); + *this << "$" << lookupType << ", " << WMI->getMember() << " : "; WMI->getMember().getDecl()->getInterfaceType().print( PrintState.OS, QualifiedSILTypeOptions); - if (!WMI->getTypeDependentOperands().empty()) { + if ((getLocalArchetypeOf(lookupType) || lookupType->hasDynamicSelfType()) && !WMI->getTypeDependentOperands().empty()) { *this << ", "; *this << getIDAndForcedPrintedType(WMI->getTypeDependentOperands()[0].get()); } diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index ed59536c73137..eba86e73bd6d2 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -4177,7 +4177,7 @@ class SILVerifier : public SILVerifierBase { "Must have a type dependent operand for the opened archetype"); verifyLocalArchetype(AMI, lookupType); } else { - require(AMI->getTypeDependentOperands().empty(), + require(AMI->getTypeDependentOperands().empty() || lookupType->hasLocalArchetype(), "Should not have an operand for the opened existential"); } if (!isa(lookupType) && !isa(lookupType)) { diff --git a/test/SILOptimizer/propagate_opaque_return_type.swift b/test/SILOptimizer/propagate_opaque_return_type.swift new file mode 100644 index 0000000000000..75ba610f8f228 --- /dev/null +++ b/test/SILOptimizer/propagate_opaque_return_type.swift @@ -0,0 +1,33 @@ +// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all) | %FileCheck %s + +protocol P {} +extension P { + func foo() -> some Sequence { + [1, 2, 3] + } +} + +struct B { + let p: P + + @inline(never) + func bar() { + for x in p.foo() { + print(x) + } + } +} + + +struct S : P { + var x = 0 +} + + +let b = B(p: S()) + +// CHECK: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +b.bar() +