Skip to content

Commit 30da30e

Browse files
committed
RequirementMachine: Rule::isProtocolRefinementRule() allows transitive refinement
Without this, we only considered a protocol refinement rule redundant if it was derived by directly-stated protocol refinements. But this broke when completion introduced a 'transitive' refinement [P].[R] => [P] from two directly-stated refinements [P].[Q] => [P] and [Q].[R] => [Q]. Fixes rdar://problem/90402503.
1 parent c5cef95 commit 30da30e

File tree

4 files changed

+16
-9
lines changed

4 files changed

+16
-9
lines changed

lib/AST/RequirementMachine/MinimalConformances.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ void MinimalConformances::collectConformanceRules() {
396396
continue;
397397

398398
// Save protocol refinement relations in a side table.
399-
if (rule.isProtocolRefinementRule())
399+
if (rule.isProtocolRefinementRule(Context))
400400
ProtocolRefinements.insert(ruleID);
401401

402402
if (!System.isInMinimizationDomain(rule.getLHS().getRootProtocol()))

lib/AST/RequirementMachine/Rule.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ bool Rule::isIdentityConformanceRule() const {
9393

9494
/// If this is a rule of the form [P].[Q] => [P] where [P] and [Q] are
9595
/// protocol symbols, return true, otherwise return false.
96-
bool Rule::isProtocolRefinementRule() const {
96+
bool Rule::isProtocolRefinementRule(RewriteContext &ctx) const {
9797
if (LHS.size() == 2 &&
9898
RHS.size() == 1 &&
9999
LHS[0] == RHS[0] &&
@@ -111,7 +111,7 @@ bool Rule::isProtocolRefinementRule() const {
111111
auto *proto = LHS[0].getProtocol();
112112
auto *otherProto = LHS[1].getProtocol();
113113

114-
auto inherited = proto->getInheritedProtocols();
114+
auto inherited = ctx.getInheritedProtocols(proto);
115115
return (std::find(inherited.begin(), inherited.end(), otherProto)
116116
!= inherited.end());
117117
}

lib/AST/RequirementMachine/Rule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class Rule final {
108108

109109
bool isIdentityConformanceRule() const;
110110

111-
bool isProtocolRefinementRule() const;
111+
bool isProtocolRefinementRule(RewriteContext &ctx) const;
112112

113113
bool isCircularConformanceRule() const;
114114

test/Generics/redundant_protocol_refinement.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
// RUN: %target-typecheck-verify-swift
22
// RUN: %target-swift-frontend -typecheck -debug-generic-signatures -requirement-machine-protocol-signatures=verify %s 2>&1 | %FileCheck %s
33

4-
protocol Base {}
5-
64
// CHECK-LABEL: redundant_protocol_refinement.(file).Base@
75
// CHECK-LABEL: Requirement signature: <Self>
8-
9-
protocol Middle : Base {}
6+
protocol Base {}
107

118
// CHECK-LABEL: redundant_protocol_refinement.(file).Middle@
129
// CHECK-LABEL: Requirement signature: <Self where Self : Base>
10+
protocol Middle : Base {}
1311

12+
// CHECK-LABEL: redundant_protocol_refinement.(file).Derived@
13+
// CHECK-LABEL: Requirement signature: <Self where Self : Middle>
1414
protocol Derived : Middle, Base {}
1515
// expected-note@-1 {{conformance constraint 'Self' : 'Base' implied here}}
1616
// expected-warning@-2 {{redundant conformance constraint 'Self' : 'Base'}}
1717

18-
// CHECK-LABEL: redundant_protocol_refinement.(file).Derived@
18+
// CHECK-LABEL: redundant_protocol_refinement.(file).Derived2@
1919
// CHECK-LABEL: Requirement signature: <Self where Self : Middle>
20+
protocol Derived2 : Middle {}
21+
22+
// CHECK-LABEL: redundant_protocol_refinement.(file).MoreDerived@
23+
// CHECK-LABEL: Requirement signature: <Self where Self : Derived2>
24+
protocol MoreDerived : Derived2, Base {}
25+
// expected-note@-1 {{conformance constraint 'Self' : 'Base' implied here}}
26+
// expected-warning@-2 {{redundant conformance constraint 'Self' : 'Base'}}
2027

2128
protocol P1 {}
2229

0 commit comments

Comments
 (0)