Skip to content

Commit 16e84e3

Browse files
committed
[Diagnostics] Add edu note explaining limitations of protocols with associated type requirements
1 parent dddcfb8 commit 16e84e3

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

include/swift/AST/EducationalNotes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
// EDUCATIONAL_NOTES(DIAG_ID, EDUCATIONAL_NOTE_FILENAMES...)
2323

24+
EDUCATIONAL_NOTES(unsupported_existential_type,
25+
"associated-type-requirements.md")
26+
2427
EDUCATIONAL_NOTES(non_nominal_no_initializers, "nominal-types.md")
2528
EDUCATIONAL_NOTES(non_nominal_extension, "nominal-types.md")
2629
EDUCATIONAL_NOTES(associated_type_witness_conform_impossible,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Using Protocols with `Self` or Associated Type Requirements
2+
---
3+
Protocols in Swift may be used as types, as part of a generic constraint, or as part of an opaque result type.
4+
```
5+
// CustomStringConvertible can be used as a type.
6+
func foo(bar: CustomStringConvertible) { /* ... */ }
7+
8+
// ...or as a generic constraint on 'T'.
9+
func bar<T: CustomStringConvertible>(baz: T) { /* ... */ }
10+
11+
// ...or as part of an opaque result type.
12+
func baz() -> some CustomStringConvertible { /* ... */ }
13+
```
14+
15+
While all Swift protocols can be used as generic constraints and as part of opaque result types, not all protocols can be used as types in general. Specifically, if a protocol has a requirement which references `Self` or an associated type, it cannot be used as a type. One such protocol is `Identifiable`, which has the requirement `var id: ID { get }`, where `ID` is an associated type. As a result, the following code is not allowed:
16+
```
17+
func foo(bar: Identifiable) { /* ... */ }
18+
// error: protocol 'Identifiable' can only be used as a generic constraint because it has Self or associated type requirements
19+
```
20+
21+
Protocols like `Identifiable` which have `Self` or associated type requirements cannot be used as types because such types would rarely be useful in practice. They would be unable to allow use of `Self` or associated type requirements like `var id: ID { get }` because the associated type is not specified.
22+
23+
When working with protocols having `Self` or associated type requirements constrained generics, opaque result types, or manual type erasure is sufficient to support most use cases. To learn more, see the [Protocols](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html), [Generics](https://docs.swift.org/swift-book/LanguageGuide/Generics.html), and [Opaque Types](https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html) sections of _The Swift Programming Language_.

0 commit comments

Comments
 (0)