Skip to content

Commit 71b7c92

Browse files
committed
Handle more cycles with ConcurrentValue inference
1 parent 9d333ee commit 71b7c92

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

lib/AST/Module.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -970,18 +970,18 @@ ProtocolConformanceRef ModuleDecl::lookupConformance(Type type,
970970
// If we are recursively checking for implicit conformance of a nominal
971971
// type to ConcurrentValue, fail without evaluating this request. This
972972
// squashes cycles.
973+
LookupConformanceInModuleRequest request{{this, type, protocol}};
973974
if (protocol->isSpecificProtocol(KnownProtocolKind::ConcurrentValue)) {
974975
if (auto nominal = type->getAnyNominal()) {
975-
GetImplicitConcurrentValueRequest request{nominal};
976-
if (getASTContext().evaluator.hasActiveRequest(request))
976+
GetImplicitConcurrentValueRequest icvRequest{nominal};
977+
if (getASTContext().evaluator.hasActiveRequest(icvRequest) ||
978+
getASTContext().evaluator.hasActiveRequest(request))
977979
return ProtocolConformanceRef::forInvalid();
978980
}
979981
}
980982

981983
return evaluateOrDefault(
982-
getASTContext().evaluator,
983-
LookupConformanceInModuleRequest{{this, type, protocol}},
984-
ProtocolConformanceRef::forInvalid());
984+
getASTContext().evaluator, request, ProtocolConformanceRef::forInvalid());
985985
}
986986

987987
ProtocolConformanceRef

test/Concurrency/concurrent_value_inference.swift

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,46 @@ struct GS2<T> {
2626
}
2727

2828
func acceptCV<T: ConcurrentValue>(_: T) { }
29-
// expected-note@-1 3{{where 'T' =}}
29+
// expected-note@-1 4{{where 'T' =}}
30+
31+
// Example that was triggering circular dependencies.
32+
struct Signature { }
33+
struct Data { }
34+
struct BlockInfo { }
35+
36+
struct Bitcode {
37+
let signature: Signature
38+
let elements: [BitcodeElement]
39+
let blockInfo: [UInt64: BlockInfo]
40+
}
41+
42+
enum BitcodeElement {
43+
struct Block {
44+
var id: UInt64
45+
var elements: [BitcodeElement]
46+
}
47+
48+
struct Record {
49+
enum Payload {
50+
case none
51+
case array([UInt64])
52+
case char6String(String)
53+
case blob(Data)
54+
}
55+
56+
var id: UInt64
57+
var fields: [UInt64]
58+
var payload: Payload
59+
}
60+
61+
case block(Block)
62+
case record(Record)
63+
}
64+
3065

3166
func testCV(
32-
c1: C1, c2: C2, s1: S1, e1: E1, e2: E2, gs1: GS1<Int>, gs2: GS2<Int>
67+
c1: C1, c2: C2, s1: S1, e1: E1, e2: E2, gs1: GS1<Int>, gs2: GS2<Int>,
68+
bc: Bitcode
3369
) {
3470
acceptCV(c1) // expected-error{{'C1' conform to 'ConcurrentValue'}}
3571
acceptCV(c2)
@@ -38,4 +74,7 @@ func testCV(
3874
acceptCV(e2)
3975
acceptCV(gs1)
4076
acceptCV(gs2) // expected-error{{'GS2<Int>' conform to 'ConcurrentValue'}}
77+
78+
// Note available due to recursive conformance dependencies.
79+
acceptCV(bc) // expected-error{{global function 'acceptCV' requires that 'Bitcode' conform to 'ConcurrentValue'}}
4180
}

0 commit comments

Comments
 (0)