Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions lib/Sema/TypeCheckDeclPrimary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1864,17 +1864,16 @@ static void diagnoseRetroactiveConformances(
continue;
}

bool isMarkedRetroactive = entry.isRetroactive();
SmallVector<ProtocolDecl *, 2> protos;
if (auto *protoTy = inheritedTy->getAs<ProtocolType>()) {
auto *proto = protoTy->getDecl();

// 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>()) {
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 10 additions & 2 deletions test/Sema/extension_retroactive_conformances.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

Expand Down Expand Up @@ -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 {}

Expand Down