Skip to content

Commit ba7f301

Browse files
committed
ConformanceChecker: Always diagnose a conformance failure if the requirement check fails in 'ensureRequirementsAreSatisfied'
1 parent 4bbad02 commit ba7f301

12 files changed

+64
-34
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4971,20 +4971,23 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
49714971
break;
49724972

49734973
case CheckGenericArgumentsResult::RequirementFailure:
4974-
TypeChecker::diagnoseRequirementFailure(
4975-
result.getRequirementFailureInfo(), Loc, Loc,
4976-
proto->getDeclaredInterfaceType(), {proto->getSelfInterfaceType()},
4977-
QuerySubstitutionMap{substitutions}, module);
4978-
Conformance->setInvalid();
4979-
return;
49804974
case CheckGenericArgumentsResult::SubstitutionFailure:
49814975
// Diagnose the failure generically.
49824976
// FIXME: Would be nice to give some more context here!
49834977
if (!Conformance->isInvalid()) {
49844978
diags.diagnose(Loc, diag::type_does_not_conform,
49854979
Adoptee,
49864980
Proto->getDeclaredInterfaceType());
4981+
4982+
if (result == CheckGenericArgumentsResult::RequirementFailure) {
4983+
TypeChecker::diagnoseRequirementFailure(
4984+
result.getRequirementFailureInfo(), Loc, Loc,
4985+
proto->getDeclaredInterfaceType(), {proto->getSelfInterfaceType()},
4986+
QuerySubstitutionMap{substitutions}, module);
4987+
}
4988+
49874989
Conformance->setInvalid();
4990+
AlreadyComplained = true;
49884991
}
49894992
return;
49904993
}

test/AutoDiff/Sema/DerivedConformances/class_differentiable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ final class TangentVectorWB: DummyAdditiveArithmetic, Differentiable {
434434
}
435435
// expected-error @+3 {{'Differentiable' requires the types 'VectorSpaceTypeAlias.TangentVector' (aka 'TangentVectorWB') and 'TangentVectorWB.TangentVector' be equivalent}}
436436
// expected-note @+2 {{requirement specified as 'Self.TangentVector' == 'Self.TangentVector.TangentVector' [with Self = VectorSpaceTypeAlias]}}
437-
// expected-error @+1 {{type 'VectorSpaceTypeAlias' does not conform to protocol 'Differentiable'}}
437+
// expected-error @+1 2 {{type 'VectorSpaceTypeAlias' does not conform to protocol 'Differentiable'}} FIXME: Duplicate error
438438
final class VectorSpaceTypeAlias: DummyAdditiveArithmetic, Differentiable {
439439
var w: Float
440440
var b: Float

test/Distributed/actor_protocols.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ distributed actor DA: DistributedActor {
4343
typealias ActorSystem = FakeActorSystem
4444
}
4545

46+
// FIXME: Ideally, we should only emit the tailored conformance error.
47+
// expected-error@+1 {{type 'A2' does not conform to protocol 'DistributedActor'}}
4648
actor A2: DistributedActor {
4749
// expected-error@-1{{non-distributed actor type 'A2' cannot conform to the 'DistributedActor' protocol}} {{1-1=distributed }}
4850
// expected-error@-2{{'DistributedActor' requires the types 'ObjectIdentifier' and 'FakeActorSystem.ActorID' (aka 'ActorAddress') be equivalent}}
@@ -63,6 +65,8 @@ actor A2: DistributedActor {
6365
}
6466
}
6567

68+
// FIXME: Ideally, we should only emit the tailored conformance error.
69+
// expected-error@+1 {{type 'C2' does not conform to protocol 'DistributedActor'}}
6670
final class C2: DistributedActor {
6771
// expected-error@-1{{non-actor type 'C2' cannot conform to the 'Actor' protocol}}
6872
// expected-error@-2{{'DistributedActor' requires the types 'ObjectIdentifier' and 'FakeActorSystem.ActorID' (aka 'ActorAddress') be equivalent}}

test/Generics/associated_type_where_clause.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ struct ConcreteNestedConformsInfer: NestedConforms {
3939
func foo(_: ConcreteConforms) {}
4040
}
4141
struct BadConcreteNestedConforms: NestedConforms {
42-
// expected-error@-1 {{type 'ConcreteConformsNonFoo2.T' (aka 'Float') does not conform to protocol 'Foo2'}}
42+
// expected-error@-1 {{type 'BadConcreteNestedConforms' does not conform to protocol 'NestedConforms'}}
43+
// expected-error@-2 {{type 'ConcreteConformsNonFoo2.T' (aka 'Float') does not conform to protocol 'Foo2'}}
4344
typealias U = ConcreteConformsNonFoo2
4445
}
4546
struct BadConcreteNestedConformsInfer: NestedConforms {
@@ -71,8 +72,10 @@ func needsNestedSameType<X: NestedSameType>(_: X.Type) {
7172
needsSameType(X.U.T.self, Int.self)
7273
}
7374
struct BadConcreteNestedSameType: NestedSameType {
74-
// expected-error@-1 {{'NestedSameType' requires the types 'ConcreteConformsNonFoo2.T' (aka 'Float') and 'Int' be equivalent}}
75-
// expected-note@-2 {{requirement specified as 'Self.U.T' == 'Int' [with Self = BadConcreteNestedSameType]}}
75+
// expected-error@-1 {{type 'BadConcreteNestedSameType' does not conform to protocol 'NestedSameType'}}
76+
// expected-error@-2 {{'NestedSameType' requires the types 'ConcreteConformsNonFoo2.T' (aka 'Float') and 'Int' be equivalent}}
77+
// expected-note@-3 {{requirement specified as 'Self.U.T' == 'Int' [with Self = BadConcreteNestedSameType]}}
78+
7679
typealias U = ConcreteConformsNonFoo2
7780
}
7881
struct BadConcreteNestedSameTypeInfer: NestedSameType {

test/Generics/conditional_conformances.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,12 @@ func inheritequal_bad<U>(_: U) {
229229

230230
struct InheritLess<T> {}
231231
extension InheritLess: P2 where T: P1 {}
232-
extension InheritLess: P5 {} // expected-error{{type 'T' does not conform to protocol 'P1'}}
233-
// expected-error@-1{{'P5' requires that 'T' conform to 'P1'}}
234-
// expected-note@-2{{requirement specified as 'T' : 'P1'}}
235-
// expected-note@-3{{requirement from conditional conformance of 'InheritLess<T>' to 'P2'}}
232+
extension InheritLess: P5 {}
233+
// expected-error@-1 {{type 'InheritLess<T>' does not conform to protocol 'P5'}}
234+
// expected-error@-2 {{type 'T' does not conform to protocol 'P1'}}
235+
// expected-error@-3 {{'P5' requires that 'T' conform to 'P1'}}
236+
// expected-note@-4 {{requirement specified as 'T' : 'P1'}}
237+
// expected-note@-5 {{requirement from conditional conformance of 'InheritLess<T>' to 'P2'}}
236238

237239

238240
struct InheritMore<T> {}

test/Generics/protocol_where_clause.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ struct ConcreteConforms: Conforms {
3535
typealias T = Int
3636
}
3737
struct BadConcreteConforms: Conforms {
38-
// expected-error@-1 {{type 'BadConcreteConforms.T' (aka 'String') does not conform to protocol 'Foo'}}
38+
// expected-error@-1 {{type 'BadConcreteConforms' does not conform to protocol 'Conforms}}
39+
// expected-error@-2 {{type 'BadConcreteConforms.T' (aka 'String') does not conform to protocol 'Foo'}}
3940
typealias T = String
4041
}
4142

@@ -47,8 +48,10 @@ struct ConcreteSameType: SameType {
4748
typealias T = Int
4849
typealias U = Int
4950
}
50-
struct BadConcreteSameType: SameType { // expected-error{{'SameType' requires the types 'BadConcreteSameType.T' (aka 'Int') and 'BadConcreteSameType.U' (aka 'Float') be equivalent}}
51-
// expected-note@-1{{requirement specified as 'Self.T' == 'Self.U' [with Self = BadConcreteSameType]}}
51+
struct BadConcreteSameType: SameType {
52+
// expected-error@-1 {{type 'BadConcreteSameType' does not conform to protocol 'SameType'}}
53+
// expected-error@-2 {{'SameType' requires the types 'BadConcreteSameType.T' (aka 'Int') and 'BadConcreteSameType.U' (aka 'Float') be equivalent}}
54+
// expected-note@-3 {{requirement specified as 'Self.T' == 'Self.U' [with Self = BadConcreteSameType]}}
5255
typealias T = Int
5356
typealias U = Float
5457
}
@@ -63,7 +66,8 @@ struct ConcreteNestedConforms: NestedConforms {
6366
typealias U = ConcreteParent
6467
}
6568
struct BadConcreteNestedConforms: NestedConforms {
66-
// expected-error@-1 {{type 'ConcreteParentNonFoo2.T' (aka 'Float') does not conform to protocol 'Foo2'}}
69+
// expected-error@-1 {{type 'BadConcreteNestedConforms' does not conform to protocol 'NestedConforms'}}
70+
// expected-error@-2 {{type 'ConcreteParentNonFoo2.T' (aka 'Float') does not conform to protocol 'Foo2'}}
6771
typealias U = ConcreteParentNonFoo2
6872
}
6973

test/decl/protocol/conforms/failure.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,10 @@ protocol P13a {
254254
}
255255
protocol P13b: P13a where A: Class13 {}
256256
do {
257-
// FIXME: No conformance failure.
258257
struct Conformer: P13b {
259-
// expected-error@-1 {{'P13b' requires that 'Conformer.A' (aka 'Array<Bool>') inherit from 'Class13'}}
260-
// expected-note@-2 {{requirement specified as 'Self.A' : 'Class13' [with Self = Conformer]}}
258+
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P13b'}}
259+
// expected-error@-2 {{'P13b' requires that 'Conformer.A' (aka 'Array<Bool>') inherit from 'Class13'}}
260+
// expected-note@-3 {{requirement specified as 'Self.A' : 'Class13' [with Self = Conformer]}}
261261
typealias A = Array<Bool>
262262
}
263263
}

test/decl/protocol/protocol_with_superclass.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ func usesProtoRefinesClass2<T : ProtoRefinesClass>(_ t: T) {
9595
}
9696

9797
class BadConformingClass1 : ProtoRefinesClass {
98-
// expected-error@-1 {{'ProtoRefinesClass' requires that 'BadConformingClass1' inherit from 'Generic<Int>'}}
99-
// expected-note@-2 {{requirement specified as 'Self' : 'Generic<Int>' [with Self = BadConformingClass1]}}
98+
// expected-error@-1 {{type 'BadConformingClass1' does not conform to protocol 'ProtoRefinesClass'}}
99+
// expected-error@-2 {{'ProtoRefinesClass' requires that 'BadConformingClass1' inherit from 'Generic<Int>'}}
100+
// expected-note@-3 {{requirement specified as 'Self' : 'Generic<Int>' [with Self = BadConformingClass1]}}
100101
func requirementUsesClassTypes(_: ConcreteAlias, _: GenericAlias) {
101102
// expected-error@-1 {{cannot find type 'ConcreteAlias' in scope}}
102103
// expected-error@-2 {{cannot find type 'GenericAlias' in scope}}
@@ -112,8 +113,9 @@ class BadConformingClass2 : Generic<String>, ProtoRefinesClass {
112113
// expected-error@-1 {{'ProtoRefinesClass' requires that 'BadConformingClass2' inherit from 'Generic<Int>'}}
113114
// expected-note@-2 {{requirement specified as 'Self' : 'Generic<Int>' [with Self = BadConformingClass2]}}
114115
// expected-error@-3 {{type 'BadConformingClass2' does not conform to protocol 'ProtoRefinesClass'}}
116+
117+
// expected-note@+1 {{candidate has non-matching type '(BadConformingClass2.ConcreteAlias, BadConformingClass2.GenericAlias) -> ()' (aka '(String, (String, String)) -> ()')}}
115118
func requirementUsesClassTypes(_: ConcreteAlias, _: GenericAlias) {
116-
// expected-note@-1 {{candidate has non-matching type '(BadConformingClass2.ConcreteAlias, BadConformingClass2.GenericAlias) -> ()' (aka '(String, (String, String)) -> ()')}}
117119
_ = ConcreteAlias.self
118120
_ = GenericAlias.self
119121
}
@@ -315,8 +317,9 @@ class SecondClass : FirstClass {}
315317
protocol SecondProtocol : SecondClass, FirstProtocol {}
316318

317319
class FirstConformer : FirstClass, SecondProtocol {}
318-
// expected-error@-1 {{'SecondProtocol' requires that 'FirstConformer' inherit from 'SecondClass'}}
319-
// expected-note@-2 {{requirement specified as 'Self' : 'SecondClass' [with Self = FirstConformer]}}
320+
// expected-error@-1 {{type 'FirstConformer' does not conform to protocol 'SecondProtocol'}}
321+
// expected-error@-2 {{'SecondProtocol' requires that 'FirstConformer' inherit from 'SecondClass'}}
322+
// expected-note@-3 {{requirement specified as 'Self' : 'SecondClass' [with Self = FirstConformer]}}
320323

321324
class SecondConformer : SecondClass, SecondProtocol {}
322325

test/decl/protocol/protocol_with_superclass_where_clause.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ func usesProtoRefinesClass2<T : ProtoRefinesClass>(_ t: T) {
9696
}
9797

9898
class BadConformingClass1 : ProtoRefinesClass {
99-
// expected-error@-1 {{'ProtoRefinesClass' requires that 'BadConformingClass1' inherit from 'Generic<Int>'}}
100-
// expected-note@-2 {{requirement specified as 'Self' : 'Generic<Int>' [with Self = BadConformingClass1]}}
99+
// expected-error@-1 {{type 'BadConformingClass1' does not conform to protocol 'ProtoRefinesClass'}}
100+
// expected-error@-2 {{'ProtoRefinesClass' requires that 'BadConformingClass1' inherit from 'Generic<Int>'}}
101+
// expected-note@-3 {{requirement specified as 'Self' : 'Generic<Int>' [with Self = BadConformingClass1]}}
101102
func requirementUsesClassTypes(_: ConcreteAlias, _: GenericAlias) {
102103
// expected-error@-1 {{cannot find type 'ConcreteAlias' in scope}}
103104
// expected-error@-2 {{cannot find type 'GenericAlias' in scope}}
@@ -113,8 +114,9 @@ class BadConformingClass2 : Generic<String>, ProtoRefinesClass {
113114
// expected-error@-1 {{'ProtoRefinesClass' requires that 'BadConformingClass2' inherit from 'Generic<Int>'}}
114115
// expected-note@-2 {{requirement specified as 'Self' : 'Generic<Int>' [with Self = BadConformingClass2]}}
115116
// expected-error@-3 {{type 'BadConformingClass2' does not conform to protocol 'ProtoRefinesClass'}}
117+
118+
// expected-note@+1 {{candidate has non-matching type '(BadConformingClass2.ConcreteAlias, BadConformingClass2.GenericAlias) -> ()' (aka '(String, (String, String)) -> ()')}}
116119
func requirementUsesClassTypes(_: ConcreteAlias, _: GenericAlias) {
117-
// expected-note@-1 {{candidate has non-matching type '(BadConformingClass2.ConcreteAlias, BadConformingClass2.GenericAlias) -> ()' (aka '(String, (String, String)) -> ()')}}
118120
_ = ConcreteAlias.self
119121
_ = GenericAlias.self
120122
}
@@ -316,8 +318,9 @@ class SecondClass : FirstClass {}
316318
protocol SecondProtocol where Self : SecondClass, Self : FirstProtocol {}
317319

318320
class FirstConformer : FirstClass, SecondProtocol {}
319-
// expected-error@-1 {{'SecondProtocol' requires that 'FirstConformer' inherit from 'SecondClass'}}
320-
// expected-note@-2 {{requirement specified as 'Self' : 'SecondClass' [with Self = FirstConformer]}}
321+
// expected-error@-1 {{type 'FirstConformer' does not conform to protocol 'SecondProtocol'}}
322+
// expected-error@-2 {{'SecondProtocol' requires that 'FirstConformer' inherit from 'SecondClass'}}
323+
// expected-note@-3 {{requirement specified as 'Self' : 'SecondClass' [with Self = FirstConformer]}}
321324

322325
class SecondConformer : SecondClass, SecondProtocol {}
323326

test/decl/protocol/req/associated_type_inference_fixed_type.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ do {
6666
struct Conformer: P8a, P8b {}
6767
// expected-error@-1 {{'P8b' requires the types 'Conformer.A' (aka 'Never') and 'Bool' be equivalent}}
6868
// expected-note@-2 {{requirement specified as 'Self.A' == 'Bool' [with Self = Conformer]}}
69+
// expected-error@-3 {{type 'Conformer' does not conform to protocol 'P8b'}}
6970
}
7071

7172
protocol P9a where A == Never {
@@ -75,6 +76,7 @@ protocol P9b: P9a {
7576
associatedtype A
7677
}
7778
struct S9a: P9b {}
79+
// expected-error@+3 {{type 'S9b' does not conform to protocol 'P9a'}}
7880
// expected-error@+2 {{'P9a' requires the types 'S9b.A' (aka 'Bool') and 'Never' be equivalent}}
7981
// expected-note@+1 {{requirement specified as 'Self.A' == 'Never' [with Self = S9b]}}
8082
struct S9b: P9b {
@@ -94,6 +96,7 @@ extension P10b {
9496
}
9597
// FIXME: 'P10 extension.A' should not be considered a viable type witness;
9698
// instead, the compiler should infer A := Never and synthesize S10.A.
99+
// expected-error@+3 {{type 'S10' does not conform to protocol 'P10a'}}
97100
// expected-error@+2 {{'P10a' requires the types 'S10.A' (aka 'Bool') and 'Never' be equivalent}}
98101
// expected-note@+1 {{requirement specified as 'Self.A' == 'Never' [with Self = S10]}}
99102
struct S10: P10b, P10a {}
@@ -323,13 +326,15 @@ do {
323326
struct Conformer1: Q28a {}
324327
// expected-error@-1 {{'P28b' requires the types 'Conformer1.A' (aka 'Int') and 'Bool' be equivalent}}
325328
// expected-note@-2 {{requirement specified as 'Self.A' == 'Bool' [with Self = Conformer1]}}
329+
// expected-error@-3 {{type 'Conformer1' does not conform to protocol 'P28b'}}
326330

327331
struct Conformer2: Q28b {}
328332
// expected-error@-1 {{'P28c' requires the types 'Conformer2.A' (aka 'Int') and 'Never' be equivalent}}
329333
// expected-error@-2 {{'P28b' requires the types 'Conformer2.A' (aka 'Int') and 'Bool' be equivalent}}
330334
// expected-note@-3 {{requirement specified as 'Self.A' == 'Never' [with Self = Conformer2]}}
331335
// expected-note@-4 {{requirement specified as 'Self.A' == 'Bool' [with Self = Conformer2]}}
332-
336+
// expected-error@-5 {{type 'Conformer2' does not conform to protocol 'P28b'}}
337+
// expected-error@-6 {{type 'Conformer2' does not conform to protocol 'P28c'}}
333338
}
334339

335340
protocol P29a where A == Int {
@@ -353,6 +358,7 @@ do {
353358
struct Conformer1: Q29a {}
354359
// expected-error@-1 {{'P29b' requires the types 'Conformer1.B' (aka 'Int') and 'Never' be equivalent}}
355360
// expected-note@-2 {{requirement specified as 'Self.B' == 'Never' [with Self = Conformer1]}}
361+
// expected-error@-3 {{type 'Conformer1' does not conform to protocol 'P29b'}}
356362

357363

358364
struct Conformer2: Q29b {}

test/decl/protocol/req/associated_type_inference_fixed_type_experimental_inference.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ protocol P9b: P9a {
106106
// CHECK-NEXT: A => Never,
107107
// CHECK-NEXT: }
108108
struct S9a: P9b {}
109+
// expected-error@+3 {{type 'S9b' does not conform to protocol 'P9a'}}
109110
// expected-error@+2 {{'P9a' requires the types 'S9b.A' (aka 'Bool') and 'Never' be equivalent}}
110111
// expected-note@+1 {{requirement specified as 'Self.A' == 'Never' [with Self = S9b]}}
111112
struct S9b: P9b {
@@ -125,6 +126,7 @@ extension P10b {
125126
}
126127
// FIXME: 'P10 extension.A' should not be considered a viable type witness;
127128
// instead, the compiler should infer A := Never and synthesize S10.A.
129+
// expected-error@+3 {{type 'S10' does not conform to protocol 'P10a'}}
128130
// expected-error@+2 {{'P10a' requires the types 'S10.A' (aka 'Bool') and 'Never' be equivalent}}
129131
// expected-note@+1 {{requirement specified as 'Self.A' == 'Never' [with Self = S10]}}
130132
struct S10: P10b, P10a {}

test/decl/protocol/special/DistributedActor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ distributed actor D4 {
4343
// expected-error@-6{{type 'D4' does not conform to protocol 'Encodable'}}
4444

4545
let actorSystem: String
46-
// expected-error@-1{{invalid redeclaration of synthesized property 'actorSystem'}}
47-
// expected-error@-2{{property 'actorSystem' cannot be defined explicitly, as it conflicts with distributed actor synthesized stored property}}
46+
// expected-error@-1{{property 'actorSystem' cannot be defined explicitly, as it conflicts with distributed actor synthesized stored property}}
47+
// expected-error@-2 {{invalid redeclaration of synthesized property 'actorSystem'}}
4848
// expected-note@-3{{stored property 'actorSystem' without initial value prevents synthesized initializers}}
4949
let id: OtherActorIdentity
5050
// expected-error@-1{{property 'id' cannot be defined explicitly, as it conflicts with distributed actor synthesized stored property}}

0 commit comments

Comments
 (0)