Skip to content

Commit 53b4ce0

Browse files
fix confusing protocol diagnostic
- update the diagnostic error message - add educational notes
1 parent af52886 commit 53b4ce0

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,8 +1803,8 @@ ERROR(use_of_equal_instead_of_equality,none,
18031803
"use of '=' in a boolean context, did you mean '=='?", ())
18041804

18051805
ERROR(type_cannot_conform, none,
1806-
"%select{|value of protocol }0type %1 cannot conform to %2; "
1807-
"only struct/enum/class types can conform to protocols",
1806+
"%select{|A value of protocol }0type %1 does not conform to the protocol itself (exception: 'Error'); "
1807+
"only concrete types such as structs, enums and classes can conform to protocols",
18081808
(bool, Type, Type))
18091809
NOTE(required_by_opaque_return,none,
18101810
"required by opaque return type of %0 %1", (DescriptiveDeclKind, DeclName))

include/swift/AST/EducationalNotes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,6 @@ EDUCATIONAL_NOTES(append_interpolation_static,
6565
"string-interpolation-conformance.md")
6666
EDUCATIONAL_NOTES(append_interpolation_void_or_discardable,
6767
"string-interpolation-conformance.md")
68+
EDUCATIONAL_NOTES(type_cannot_conform, "protocol-type-non-conformance.md")
6869

6970
#undef EDUCATIONAL_NOTES
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Protocol type not conforming to itself
2+
Swift disallows us from using a protocol as a type that conforms to itself as illustrated in the examples below
3+
4+
```swift
5+
protocol SomeProtocol {
6+
init()
7+
}
8+
9+
struct SomeStruct: SomeProtocol {}
10+
struct AnotherStruct: SomeProtocol {}
11+
12+
var arr: [SomeProtocol] = [SomeStruct(), AnotherStruct()]
13+
arr.appendNewItem()
14+
15+
extension Array where Element: SomeProtocol {
16+
mutating func appendNewItem() {
17+
append(Element())
18+
}
19+
}
20+
```
21+
22+
The code snippet above would not compile because we are using `SomeProtocol` as a type that conforms to itself. There is no concrete implementation for the protocol.
23+
24+
Consider also the case of using protocol as a type in a generic type -
25+
26+
```swift
27+
protocol AnotherProtocol {
28+
static func foo()
29+
}
30+
31+
struct GenericStruct<T: AnotherProtocol> {
32+
func faz() {
33+
T.foo()
34+
}
35+
}
36+
37+
GenericStruct<AnotherProtocol>().faz()
38+
```
39+
Constructing the instance of the struct `GenericStruct` with type `AnotherProtocol` will not compile because there is no concrete implementation for the static requirement of the protocol.
40+
There is no implementation for for() used above.
41+

0 commit comments

Comments
 (0)