mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
embedded: print an error for class existentials where not all protocols of a composition are class bound
We don't support this, yet. Without the error IRGen would crash. rdar://137517212
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "swift/SIL/InstructionUtils.h"
|
||||
#include "swift/SIL/MemAccessUtils.h"
|
||||
#include "swift/AST/SubstitutionMap.h"
|
||||
#include "swift/AST/ProtocolConformance.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
#include "swift/Basic/Defer.h"
|
||||
#include "swift/Basic/NullablePtr.h"
|
||||
@@ -671,7 +672,20 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
|
||||
RuntimeEffect::MetaData | RuntimeEffect::Existential;
|
||||
|
||||
case SILInstructionKind::InitExistentialRefInst:
|
||||
impactType = inst->getOperand(0)->getType();
|
||||
impactType = cast<InitExistentialRefInst>(inst)->getType();
|
||||
// Make sure to get a diagnostic error in embedded swift for class existentials
|
||||
// where not all protocols of a composition are class bound. For example:
|
||||
// let existential: any ClassBound & NotClassBound = MyClass()
|
||||
// In future we might support this case and then we can remove this check.
|
||||
for (auto protoRef : cast<InitExistentialRefInst>(inst)->getConformances()) {
|
||||
if (protoRef.isConcrete()) {
|
||||
ProtocolConformance *conf = protoRef.getConcrete();
|
||||
if (isa<NormalProtocolConformance>(conf) &&
|
||||
!conf->getProtocol()->requiresClass()) {
|
||||
return RuntimeEffect::MetaData | RuntimeEffect::Existential;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RuntimeEffect::MetaData | RuntimeEffect::ExistentialClassBound;
|
||||
|
||||
case SILInstructionKind::InitExistentialMetatypeInst:
|
||||
|
||||
28
test/embedded/existential-composition.swift
Normal file
28
test/embedded/existential-composition.swift
Normal file
@@ -0,0 +1,28 @@
|
||||
// RUN: %target-swift-emit-ir -parse-as-library -module-name main -verify %s -enable-experimental-feature Embedded -wmo
|
||||
|
||||
// REQUIRES: OS=macosx || OS=linux-gnu
|
||||
|
||||
protocol ClassBound: AnyObject {
|
||||
func foo()
|
||||
}
|
||||
|
||||
protocol OtherProtocol {
|
||||
func bar()
|
||||
}
|
||||
|
||||
class MyClass: ClassBound, OtherProtocol {
|
||||
func foo() { print("MyClass.foo()") }
|
||||
func bar() { print("MyClass.bar()") }
|
||||
}
|
||||
|
||||
// Currently we don't support this
|
||||
func test(existential: any ClassBound & OtherProtocol) {
|
||||
}
|
||||
|
||||
@main
|
||||
struct Main {
|
||||
static func main() {
|
||||
test(existential: MyClass()) // expected-error {{cannot use a value of protocol type 'any ClassBound & OtherProtocol' in embedded Swift}}
|
||||
// expected-note@-4 {{called from here}}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user