Skip to content

Commit 74b29ca

Browse files
committed
GSB: Fix bug with concrete same-type requirements to self-conforming protocols
If a type parameter both conformed to Error and was required to equal Error, we didn't record a concrete source for the Error conformance. This still produced the right minimized signature because the code in enumerateRequirements() happens to skip all other requirements if an equivalence class was concrete, but we shouldn't rely on that. The bug also meant that we didn't diagnose the redundant conformance requirement.
1 parent 389a082 commit 74b29ca

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,21 +2607,22 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
26072607
concreteSource = concreteSource->viaConcrete(*this, concrete);
26082608
} else {
26092609
concreteSource = concreteSource->viaConcrete(*this, conformance);
2610-
equivClass->recordConformanceConstraint(*this, type, proto, concreteSource);
2611-
2612-
// Only infer conditional requirements from explicit sources.
2613-
bool hasExplicitSource = llvm::any_of(
2614-
equivClass->concreteTypeConstraints,
2615-
[](const ConcreteConstraint &constraint) {
2616-
return (!constraint.source->isDerivedRequirement() &&
2617-
constraint.source->getLoc().isValid());
2618-
});
2610+
}
26192611

2620-
if (hasExplicitSource) {
2621-
if (addConditionalRequirements(conformance, /*inferForModule=*/nullptr,
2622-
concreteSource->getLoc()))
2623-
return nullptr;
2624-
}
2612+
equivClass->recordConformanceConstraint(*this, type, proto, concreteSource);
2613+
2614+
// Only infer conditional requirements from explicit sources.
2615+
bool hasExplicitSource = llvm::any_of(
2616+
equivClass->concreteTypeConstraints,
2617+
[](const ConcreteConstraint &constraint) {
2618+
return (!constraint.source->isDerivedRequirement() &&
2619+
constraint.source->getLoc().isValid());
2620+
});
2621+
2622+
if (hasExplicitSource) {
2623+
if (addConditionalRequirements(conformance, /*inferForModule=*/nullptr,
2624+
concreteSource->getLoc()))
2625+
return nullptr;
26252626
}
26262627

26272628
return concreteSource;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// RUN: %target-swift-frontend -typecheck -debug-generic-signatures %s 2>&1 | %FileCheck %s
3+
4+
struct G<T> {}
5+
6+
// CHECK-LABEL: Generic signature: <T where T == Error>
7+
extension G where T : Error, T == Error {}
8+
// expected-warning@-1 {{redundant conformance constraint 'T': 'Error'}}
9+
// expected-note@-2 {{conformance constraint 'T': 'Error' implied here}}

0 commit comments

Comments
 (0)