mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Fix a regression in retroactive conformance diagnostic suppression.
Module qualifying a protocol name in an inheritance clause should suppress retroactive conformance diagnostics for the protocol and any protocols it inherits from, just like adding the `@retroactive` attribute. Fixes a regression in Swift 6.2 introduced by https://github.com/swiftlang/swift/pull/81576. Resolves rdar://162295268 and https://github.com/swiftlang/swift/issues/85153.
This commit is contained in:
@@ -1864,6 +1864,7 @@ static void diagnoseRetroactiveConformances(
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isMarkedRetroactive = entry.isRetroactive();
|
||||
SmallVector<ProtocolDecl *, 2> protos;
|
||||
if (auto *protoTy = inheritedTy->getAs<ProtocolType>()) {
|
||||
auto *proto = protoTy->getDecl();
|
||||
@@ -1871,10 +1872,8 @@ static void diagnoseRetroactiveConformances(
|
||||
// As a fallback, to support previous language versions, also allow
|
||||
// this through if the protocol has been explicitly module-qualified.
|
||||
TypeRepr *repr = unwrapAttributedRepr(entry.getTypeRepr());
|
||||
if (isModuleQualified(repr, proto->getParentModule())) {
|
||||
protocolsWithRetroactiveAttr.insert(proto);
|
||||
continue;
|
||||
}
|
||||
if (isModuleQualified(repr, proto->getParentModule()))
|
||||
isMarkedRetroactive = true;
|
||||
|
||||
protos.push_back(proto);
|
||||
} else if (auto *compositionTy = inheritedTy->getAs<ProtocolCompositionType>()) {
|
||||
@@ -1920,7 +1919,7 @@ static void diagnoseRetroactiveConformances(
|
||||
}
|
||||
|
||||
// If it's marked @retroactive, no need to warn.
|
||||
if (entry.isRetroactive()) {
|
||||
if (isMarkedRetroactive) {
|
||||
// Note that we encountered this protocol through a conformance marked
|
||||
// @retroactive in case multiple clauses cause the protocol to be
|
||||
// inherited.
|
||||
|
||||
@@ -20,8 +20,12 @@ public struct Sample3 {}
|
||||
public struct Sample4 {}
|
||||
public struct Sample5 {}
|
||||
public struct Sample6 {}
|
||||
public struct Sample6a {}
|
||||
public struct Sample6b {}
|
||||
public struct Sample6c {}
|
||||
public struct Sample7 {}
|
||||
public struct Sample8 {}
|
||||
public struct Sample8a {}
|
||||
|
||||
public struct SampleAlreadyConforms: SampleProtocol1 {}
|
||||
|
||||
@@ -76,9 +80,13 @@ typealias MySample6 = Sample6
|
||||
extension MySample6: SampleProtocol1 {} // expected-warning {{extension declares a conformance of imported type 'Sample6' to imported protocol 'SampleProtocol1'}}
|
||||
// expected-note @-1 {{add '@retroactive' to silence this warning}} {{22-37=@retroactive SampleProtocol1}}
|
||||
|
||||
// Ensure module-qualifying both types still silences the warning
|
||||
// Ensure module-qualifying the protocol silences the warning
|
||||
|
||||
extension Library.Sample6: Library.SampleProtocol2 {} // ok, module-qualified.
|
||||
extension Library.Sample6: Library.SampleProtocol2 {} // ok, both types are module-qualified.
|
||||
extension Sample6a: Library.SampleProtocol2 {} // ok, protocol is module qualified.
|
||||
extension Library.Sample6b: SampleProtocol2 {} // expected-warning {{extension declares a conformance of imported type 'Sample6b' to imported protocol 'SampleProtocol2'; this will not behave correctly if the owners of 'Library' introduce this conformance in the future}}
|
||||
// expected-note @-1 {{add '@retroactive' to silence this warning}}
|
||||
extension Sample6c: Library.SampleProtocol1a {} // ok, protocol is module qualified.
|
||||
|
||||
protocol ClientProtocol {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user