Skip to content

Commit 1b99dd2

Browse files
committed
RequirementMachine: Tweak RewriteSystem::recordConflict() heuristic again
1 parent cfa557e commit 1b99dd2

8 files changed

+21
-16
lines changed

lib/AST/RequirementMachine/PropertyUnification.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ void RewriteSystem::recordConflict(unsigned existingRuleID,
156156
// conflicting rules of the same kind, so we rule that out by
157157
// marking the shorter rule as the conflict. Otherwise, we just
158158
// leave both rules in place.
159-
if (existingRule.getRHS().size() > newRule.getRHS().size()) {
159+
if (existingRule.getRHS().size() > newRule.getRHS().size() ||
160+
(existingRule.getRHS().size() == newRule.getRHS().size() &&
161+
existingRuleID < newRuleID)) {
160162
existingRule.markConflicting();
161163
} else {
162164
newRule.markConflicting();
@@ -192,6 +194,12 @@ void PropertyMap::addLayoutProperty(
192194
// If the intersection is invalid, we have a conflict.
193195
if (!mergedLayout->isKnownLayout()) {
194196
System.recordConflict(*props->LayoutRule, ruleID);
197+
198+
// Replace the old layout. Since recordConflict() marks the older rule,
199+
// this ensures that if we process multiple conflicting layout
200+
// requirements, all but the final one will be marked conflicting.
201+
props->Layout = newLayout;
202+
props->LayoutRule = ruleID;
195203
return;
196204
}
197205

test/Constraints/same_types.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,21 @@ func test3<T: Fooable, U: Fooable>(_ t: T, u: U) -> (X, X)
6161
}
6262

6363
// CHECK-LABEL: same_types.(file).fail1(_:u:)@
64-
// CHECK-NEXT: Generic signature: <T, U where T : Fooable, U : Fooable, T.[Fooable]Foo == Y, U.[Fooable]Foo == Y>
64+
// CHECK-NEXT: Generic signature: <T, U where T : Fooable, U : Fooable, T.[Fooable]Foo == X, U.[Fooable]Foo == X>
6565
func fail1< // expected-error{{no type for 'T.Foo' can satisfy both 'T.Foo == X' and 'T.Foo == Y'}}
6666
T: Fooable, U: Fooable
6767
>(_ t: T, u: U) -> (X, Y)
6868
where T.Foo == X, U.Foo == Y, T.Foo == U.Foo {
69-
return (t.foo, u.foo) // expected-error{{cannot convert return expression of type '(Y, Y)' to return type '(X, Y)'}}
69+
return (t.foo, u.foo) // expected-error{{cannot convert return expression of type '(X, X)' to return type '(X, Y)'}}
7070
}
7171

7272
// CHECK-LABEL: same_types.(file).fail2(_:u:)@
73-
// CHECK-NEXT: Generic signature: <T, U where T : Fooable, U : Fooable, T.[Fooable]Foo == X, U.[Fooable]Foo == X>
73+
// CHECK-NEXT: Generic signature: <T, U where T : Fooable, U : Fooable, T.[Fooable]Foo == Y, U.[Fooable]Foo == Y>
7474
func fail2< // expected-error{{no type for 'T.Foo' can satisfy both 'T.Foo == Y' and 'T.Foo == X'}}
7575
T: Fooable, U: Fooable
7676
>(_ t: T, u: U) -> (X, Y)
7777
where T.Foo == U.Foo, T.Foo == X, U.Foo == Y {
78-
return (t.foo, u.foo) // expected-error{{cannot convert return expression of type '(X, X)' to return type '(X, Y)'}}
78+
return (t.foo, u.foo) // expected-error{{cannot convert return expression of type '(Y, Y)' to return type '(X, Y)'}}
7979
}
8080

8181
func test4<T: Barrable>(_ t: T) -> Y where T.Bar == Y {
@@ -122,7 +122,7 @@ func fail5<T: Barrable>(_ t: T) -> (Y, Z)
122122
}
123123

124124
// CHECK-LABEL: same_types.(file).test8@
125-
// CHECK-NEXT: Generic signature: <T where T : Fooable, T.[Fooable]Foo == X>
125+
// CHECK-NEXT: Generic signature: <T where T : Fooable, T.[Fooable]Foo == Y>
126126
func test8<T: Fooable>(_ t: T) // expected-error{{no type for 'T.Foo' can satisfy both 'T.Foo == Y' and 'T.Foo == X'}}
127127
where T.Foo == X,
128128
T.Foo == Y {}
@@ -318,7 +318,7 @@ struct X5a {}
318318
struct X5b { }
319319

320320
// CHECK-LABEL: same_types.(file).test9(_:u:)@
321-
// CHECK-NEXT: Generic signature: <T, U where T : P6, U : P6, T.[P6]Bar == U.[P6]Bar, T.[P6]Bar.[P5]Foo1 == X5b>
321+
// CHECK-NEXT: Generic signature: <T, U where T : P6, U : P6, T.[P6]Bar == U.[P6]Bar, T.[P6]Bar.[P5]Foo1 == X5a>
322322
func test9<T: P6, U: P6>(_ t: T, u: U) // expected-error{{no type for 'T.Bar.Foo1' can satisfy both 'T.Bar.Foo1 == X5a' and 'T.Bar.Foo1 == X5b'}}
323323
where T.Bar.Foo1 == X5a,
324324
U.Bar.Foo2 == X5b,

test/Generics/concrete_conflict.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Class<T> {}
3535

3636
extension Class where T == Bool {
3737
// CHECK-LABEL: .badRequirement()@
38-
// CHECK-NEXT: <T where T == Bool>
38+
// CHECK-NEXT: <T where T == Int>
3939
func badRequirement() where T == Int { }
4040
// expected-error@-1 {{no type for 'T' can satisfy both 'T == Int' and 'T == Bool'}}
4141
}

test/Generics/requirement_machine_diagnostics.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// RUN: %target-typecheck-verify-swift
22
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures 2>&1 | %FileCheck %s
33

4-
// XFAIL: noncopyable_generics
5-
64
func testInvalidConformance() {
75
// expected-error@+1 {{type 'T' constrained to non-protocol, non-class type 'Int'}}
86
func invalidIntConformance<T>(_: T) where T: Int {}
@@ -324,6 +322,7 @@ func sameTypeConflicts() {
324322
// expected-error@+1{{no type for 'T.X' can satisfy both 'T.X == G<U.Foo>' and 'T.X == Int'}}
325323
func fail7<U: Fooable, T: Concrete>(_: U, _: T) where T.X == G<U.Foo> {}
326324

325+
// expected-warning@+2{{same-type requirement makes generic parameter 'T' non-generic; this is an error in Swift 6}}
327326
// expected-error@+1{{no type for 'T' can satisfy both 'T == G<U.Foo>' and 'T == Int'}}
328327
func fail8<T, U: Fooable>(_: U, _: T) where T == G<U.Foo>, T == Int {}
329328

test/Generics/superclass_and_concrete_requirement.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protocol P4 {
4141
class D {}
4242

4343
// CHECK-LABEL: .P5@
44-
// CHECK-NEXT: Requirement signature: <Self where Self.[P5]T : C, Self.[P5]T == D>
44+
// CHECK-NEXT: Requirement signature: <Self where Self.[P5]T == D>
4545
protocol P5 {
4646
// expected-error@-1 {{no type for 'Self.T' can satisfy both 'Self.T : D' and 'Self.T : C'}}
4747
associatedtype T where T : C, T == D

test/attr/attr_specialize.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func funcWithForbiddenSpecializeRequirement<T>(_ t: T) {
167167
}
168168

169169
@_specialize(where T: _Trivial(32), T: _Trivial(64), T: _Trivial, T: _RefCountedObject)
170-
// expected-error@-1{{no type for 'T' can satisfy both 'T : _RefCountedObject' and 'T : _Trivial(32)'}}
170+
// expected-error@-1{{no type for 'T' can satisfy both 'T : _RefCountedObject' and 'T : _Trivial(64)'}}
171171
// expected-error@-2{{no type for 'T' can satisfy both 'T : _Trivial(64)' and 'T : _Trivial(32)'}}
172172
@_specialize(where T: _Trivial, T: _Trivial(64))
173173
@_specialize(where T: _RefCountedObject, T: _NativeRefCountedObject)

test/decl/protocol/req/associated_type_inference_fixed_type.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ protocol P6 where A == Never { // expected-error {{no type for 'Self.A' can sati
4848
struct S6: P6 {} // expected-error {{type 'S6' does not conform to protocol 'P6'}}
4949

5050
protocol P7a where A == Never {
51-
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
51+
associatedtype A
5252
}
5353
// expected-error@+1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Bool'}}
5454
protocol P7b: P7a where A == Bool {}
5555
struct S7: P7b {}
56-
// expected-error@-1 {{type 'S7' does not conform to protocol 'P7a'}}
5756

5857
protocol P8a where A == Never {
5958
associatedtype A

test/decl/protocol/req/associated_type_inference_fixed_type_experimental_inference.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,11 @@ protocol P6 where A == Never { // expected-error {{no type for 'Self.A' can sati
6060
struct S6: P6 {} // expected-error {{type 'S6' does not conform to protocol 'P6'}}
6161

6262
protocol P7a where A == Never {
63-
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
63+
associatedtype A
6464
}
6565
// expected-error@+1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Bool'}}
6666
protocol P7b: P7a where A == Bool {}
6767
struct S7: P7b {}
68-
// expected-error@-1 {{type 'S7' does not conform to protocol 'P7a'}}
6968

7069
protocol P8a where A == Never {
7170
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}

0 commit comments

Comments
 (0)