Skip to content

Commit 1e1d4e3

Browse files
authored
Merge pull request #42202 from slavapestov/rqm-even-more-minor-diagnostics-fixes
RequirementMachine: Two more minor diagnostics fixes
2 parents 7e0ef44 + 094130b commit 1e1d4e3

File tree

8 files changed

+59
-35
lines changed

8 files changed

+59
-35
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,14 @@ void swift::rewriting::realizeInheritedRequirements(
649649
Type());
650650
if (!inheritedType) continue;
651651

652+
// Ignore trivially circular protocol refinement (protocol P : P)
653+
// since we diagnose that elsewhere. Adding a rule here would emit
654+
// a useless redundancy warning.
655+
if (auto *protoDecl = dyn_cast<ProtocolDecl>(decl)) {
656+
if (inheritedType->isEqual(protoDecl->getDeclaredInterfaceType()))
657+
continue;
658+
}
659+
652660
auto *typeRepr = inheritedTypes[index].getTypeRepr();
653661
SourceLoc loc = (typeRepr ? typeRepr->getStartLoc() : SourceLoc());
654662
if (shouldInferRequirements) {

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,15 @@ void RewriteSystem::computeRedundantRequirementDiagnostics(
661661
if (!isInMinimizationDomain(rule.getLHS().getRootProtocol()))
662662
continue;
663663

664+
// Concrete conformance rules do not map to requirements in the minimized
665+
// signature; we don't consider them to be 'non-explicit non-redundant',
666+
// so that a conformance rule (T.[P] => T) expressed in terms of a concrete
667+
// conformance (T.[concrete: C : P] => T) is still diagnosed as redundant.
668+
if (auto optSymbol = rule.isPropertyRule()) {
669+
if (optSymbol->getKind() == Symbol::Kind::ConcreteConformance)
670+
continue;
671+
}
672+
664673
auto requirementID = rule.getRequirementID();
665674

666675
if (!requirementID.hasValue()) {
@@ -761,6 +770,9 @@ void RewriteSystem::computeRedundantRequirementDiagnostics(
761770

762771
// If all rules derived from this structural requirement are redundant,
763772
// then the requirement is unnecessary in the source code.
773+
//
774+
// This means the rules derived from this requirement were all
775+
// determined to be redundant by homotopy reduction.
764776
const auto &ruleIDs = pairIt->second;
765777
if (llvm::all_of(ruleIDs, isRedundantRule)) {
766778
auto requirement = WrittenRequirements[requirementID];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on
2+
3+
protocol P1 {}
4+
protocol P2 : P1 {}
5+
6+
protocol P3 {
7+
associatedtype A where A == S
8+
}
9+
10+
struct S : P2 {}
11+
12+
func f1<T : P3>(_: T) where T.A : P1 {}
13+
// expected-warning@-1 {{redundant conformance constraint 'T.A' : 'P1'}}
14+
15+
func f2<T : P3>(_: T) where T.A : P2 {}
16+
// expected-warning@-1 {{redundant conformance constraint 'T.A' : 'P2'}}

test/Generics/superclass_constraint.swift

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
2-
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify > %t.dump 2>&1
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on
2+
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on > %t.dump 2>&1
33
// RUN: %FileCheck %s < %t.dump
44

55
class A {
@@ -12,13 +12,10 @@ class B : A {
1212

1313
class Other { }
1414

15-
func f1<T : A>(_: T) where T : Other {} // expected-error{{type 'T' cannot be a subclass of both 'Other' and 'A'}}
16-
// expected-note@-1{{constraint conflicts with 'T' : 'A'}}
15+
func f1<T : A>(_: T) where T : Other {} // expected-error{{no type for 'T' can satisfy both 'T : Other' and 'T : A'}}
1716

1817
func f2<T : A>(_: T) where T : B {}
1918
// expected-warning@-1{{redundant superclass constraint 'T' : 'A'}}
20-
// expected-note@-2{{superclass constraint 'T' : 'A' implied here}}
21-
2219

2320
class GA<T> {}
2421
class GB<T> : GA<T> {}
@@ -31,19 +28,16 @@ func f5<T, U : GA<T>>(_: T, _: U) {}
3128
func f6<U : GA<T>, T : P>(_: T, _: U) {}
3229
func f7<U, T>(_: T, _: U) where U : GA<T>, T : P {}
3330

34-
func f8<T : GA<A>>(_: T) where T : GA<B> {} // expected-error{{type 'T' cannot be a subclass of both 'GA<B>' and 'GA<A>'}}
35-
// expected-note@-1{{constraint conflicts with 'T' : 'GA<A>'}}
31+
func f8<T : GA<A>>(_: T) where T : GA<B> {} // expected-error{{no type for 'T' can satisfy both 'T : GA<B>' and 'T : GA<A>'}}
3632

3733
func f9<T : GA<A>>(_: T) where T : GB<A> {}
3834
// expected-warning@-1{{redundant superclass constraint 'T' : 'GA<A>'}}
39-
// expected-note@-2{{superclass constraint 'T' : 'GA<A>' implied here}}
4035

4136
func f10<T : GB<A>>(_: T) where T : GA<A> {}
4237
// expected-warning@-1{{redundant superclass constraint 'T' : 'GA<A>'}}
43-
// expected-note@-2{{superclass constraint 'T' : 'GA<A>' implied here}}
4438

45-
func f11<T : GA<T>>(_: T) { } // expected-error{{superclass constraint 'T' : 'GA<T>' is recursive}}
46-
func f12<T : GA<U>, U : GB<T>>(_: T, _: U) { } // expected-error{{superclass constraint 'U' : 'GB<T>' is recursive}} // expected-error{{superclass constraint 'T' : 'GA<U>' is recursive}}
39+
func f11<T : GA<T>>(_: T) { }
40+
func f12<T : GA<U>, U : GB<T>>(_: T, _: U) { }
4741
func f13<T : U, U : GA<T>>(_: T, _: U) { } // expected-error{{type 'T' constrained to non-protocol, non-class type 'U'}}
4842

4943
// rdar://problem/24730536
@@ -68,16 +62,16 @@ class S : P2 {
6862
// CHECK-LABEL: .superclassConformance1(t:)@
6963
// CHECK-NEXT: Generic signature: <T where T : C>
7064
func superclassConformance1<T>(t: T)
71-
where T : C, // expected-note{{conformance constraint 'T' : 'P3' implied here}}
72-
T : P3 {} // expected-warning{{redundant conformance constraint 'T' : 'P3'}}
65+
where T : C,
66+
T : P3 {} // expected-warning{{redundant conformance constraint 'C' : 'P3'}}
7367

7468

7569

7670
// CHECK-LABEL: .superclassConformance2(t:)@
7771
// CHECK-NEXT: Generic signature: <T where T : C>
7872
func superclassConformance2<T>(t: T)
79-
where T : C, // expected-note{{conformance constraint 'T' : 'P3' implied here}}
80-
T : P3 {} // expected-warning{{redundant conformance constraint 'T' : 'P3'}}
73+
where T : C,
74+
T : P3 {} // expected-warning{{redundant conformance constraint 'C' : 'P3'}}
8175

8276
protocol P4 { }
8377

@@ -87,32 +81,28 @@ class C2 : C, P4 { }
8781
// CHECK-NEXT: Generic signature: <T where T : C2>
8882
func superclassConformance3<T>(t: T) where T : C, T : P4, T : C2 {}
8983
// expected-warning@-1{{redundant superclass constraint 'T' : 'C'}}
90-
// expected-note@-2{{superclass constraint 'T' : 'C' implied here}}
91-
// expected-warning@-3{{redundant conformance constraint 'T' : 'P4'}}
92-
// expected-note@-4{{conformance constraint 'T' : 'P4' implied here}}
84+
// expected-warning@-2{{redundant conformance constraint 'T' : 'P4'}}
9385

9486
protocol P5: A { }
9587

96-
protocol P6: A, Other { } // expected-error {{type 'Self' cannot be a subclass of both 'Other' and 'A'}}
88+
protocol P6: A, Other { } // expected-error {{no type for 'Self' can satisfy both 'Self : Other' and 'Self : A'}}
9789
// expected-error@-1{{multiple inheritance from classes 'A' and 'Other'}}
98-
// expected-note@-2 {{constraint conflicts with 'Self' : 'A'}}
9990

10091
func takeA(_: A) { }
10192
func takeP5<T: P5>(_ t: T) {
10293
takeA(t) // okay
10394
}
10495

10596
protocol P7 {
106-
associatedtype Assoc: A, Other
107-
// expected-note@-1{{constraint conflicts with 'Self.Assoc' : 'A'}}
108-
// expected-error@-2{{'Self.Assoc' cannot be a subclass of both 'Other' and 'A'}}
97+
// expected-error@-1{{no type for 'Self.Assoc' can satisfy both 'Self.Assoc : Other' and 'Self.Assoc : A'}}
98+
associatedtype Assoc: A, Other
10999
}
110100

111101
// CHECK-LABEL: .superclassConformance4@
112102
// CHECK-NEXT: Generic signature: <T, U where T : P3, U : P3, T.[P3]T : C, T.[P3]T == U.[P3]T>
113103
func superclassConformance4<T: P3, U: P3>(_: T, _: U)
114-
where T.T: C, // expected-note{{superclass constraint 'U.T' : 'C' implied here}}
115-
U.T: C, // expected-warning{{redundant superclass constraint 'U.T' : 'C'}}
104+
where T.T: C, // expected-warning{{redundant superclass constraint 'T.T' : 'C'}}
105+
U.T: C,
116106
T.T == U.T { }
117107

118108
// Lookup of superclass associated types from inheritance clause
@@ -181,8 +171,7 @@ protocol Rump : Tail {
181171
class Horse<T>: Rump { }
182172

183173
func hasRedundantConformanceConstraint<X : Horse<T>, T>(_: X) where X : Rump {}
184-
// expected-warning@-1 {{redundant conformance constraint 'X' : 'Rump'}}
185-
// expected-note@-2 {{conformance constraint 'X' : 'Rump' implied here}}
174+
// expected-warning@-1 {{redundant conformance constraint 'Horse<T>' : 'Rump'}}
186175

187176
// SR-5862
188177
protocol X {

test/decl/class/circular_inheritance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on
22

33
class Left // expected-error {{'Left' inherits from itself}} expected-note {{through reference here}}
44
: Right.Hand { // expected-note {{through reference here}}

test/decl/protocol/conforms/circular_validation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on
22

33
// With a bit of effort, we could make this work -- but for now, let's just
44
// not crash.

test/decl/protocol/protocols.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -enable-objc-interop -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
1+
// RUN: %target-typecheck-verify-swift -enable-objc-interop -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on
22
protocol EmptyProtocol { }
33

44
protocol DefinitionsInProtocols {

validation-test/compiler_crashers_2_fixed/0145-sr7097.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
2-
// RUN: %target-swift-frontend -typecheck -debug-generic-signatures %s -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify 2>&1 | %FileCheck %s
3-
// RUN: %target-swift-frontend -primary-file %s -emit-ir -o - -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-inferred-signatures=on
2+
// RUN: %target-swift-frontend -typecheck -debug-generic-signatures %s -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s
3+
// RUN: %target-swift-frontend -primary-file %s -emit-ir -o - -requirement-machine-inferred-signatures=on
44

55
protocol P1 { }
66

@@ -13,7 +13,6 @@ protocol P2 {
1313
protocol P3 : P2 { }
1414

1515
struct S0<M: P3> where M.Assoc: P1 { } // expected-warning{{redundant conformance constraint 'M.Assoc' : 'P1'}}
16-
// expected-note@-1{{conformance constraint 'M.Assoc' : 'P1' implied here}}
1716

1817
struct ConformsToP1: P1 { }
1918

0 commit comments

Comments
 (0)