Skip to content

Commit 618378a

Browse files
committed
Ban use of marker protocols in conditional conformances to non-marker protocols
These conditional conformances could not be properly evaluated at runtime, so ban them. We still allow conditional conformances to marker protocols.
1 parent 9df17ff commit 618378a

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5624,6 +5624,10 @@ ERROR(marker_protocol_inherit_nonmarker, none,
56245624
(DeclName, DeclName))
56255625
ERROR(marker_protocol_cast,none,
56265626
"marker protocol %0 cannot be used in a conditional cast", (DeclName))
5627+
ERROR(marker_protocol_conditional_conformance,none,
5628+
"conditional conformance to non-marker protocol %0 cannot depend on "
5629+
"conformance of %1 to non-marker protocol %2",
5630+
(Identifier, Type, Identifier))
56275631

56285632
//------------------------------------------------------------------------------
56295633
// MARK: differentiable programming diagnostics

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,6 +1935,23 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
19351935

19361936
nestedType = nestedType.getNominalParent();
19371937
}
1938+
1939+
// If the protocol to which we are conditionally conforming is not a marker
1940+
// protocol, the conditional requirements must not involve conformance to a
1941+
// marker protocol. We cannot evaluate such a conformance at runtime.
1942+
if (!Proto->isMarkerProtocol()) {
1943+
for (const auto &req : *conditionalReqs) {
1944+
if (req.getKind() == RequirementKind::Conformance &&
1945+
req.getSecondType()->castTo<ProtocolType>()->getDecl()
1946+
->isMarkerProtocol()) {
1947+
C.Diags.diagnose(
1948+
ComplainLoc, diag::marker_protocol_conditional_conformance,
1949+
Proto->getName(), req.getFirstType(),
1950+
req.getSecondType()->castTo<ProtocolType>()->getDecl()->getName());
1951+
conformance->setInvalid();
1952+
}
1953+
}
1954+
}
19381955
}
19391956

19401957
// If the protocol contains missing requirements, it can't be conformed to

test/attr/attr_marker_protocol.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,8 @@ protocol P9: P8 { }
5858
// Implied conditional conformance to P8 is okay because P8 is a marker
5959
// protocol.
6060
extension Array: P9 where Element: P9 { }
61+
62+
protocol P10 { }
63+
64+
extension Array: P10 where Element: P10, Element: P8 { }
65+
// expected-error@-1{{conditional conformance to non-marker protocol 'P10' cannot depend on conformance of 'Element' to non-marker protocol 'P8'}}

0 commit comments

Comments
 (0)