Skip to content

Commit

Permalink
Add rule to prefer opaque generic parameter syntax (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
calda committed Oct 17, 2022
1 parent f7f2ff9 commit f600ed0
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ let package = Package(

.binaryTarget(
name: "SwiftFormat",
url: "https://github.com/calda/SwiftFormat/releases/download/0.50-beta-4/SwiftFormat.artifactbundle.zip",
checksum: "b7dfc4e623c1a6686d51904f74f7898194b950cd1db65f831bd3c0e0e6e70749"),
url: "https://github.com/calda/SwiftFormat/releases/download/0.51-beta-2/SwiftFormat.artifactbundle.zip",
checksum: "77066735bb56a2f2f37d8bfbd7606612b206d99c15ec3250e712c6a842c823a2"),

.binaryTarget(
name: "SwiftLintBinary",
Expand Down
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2221,6 +2221,72 @@ _You can enable the following settings in Xcode by running [this script](resourc

</details>

* <a id='prefer-opaque-generic-parameters'></a>(<a href='#prefer-opaque-generic-parameters'>link</a>) **Prefer using opaque generic parameters (with `some`) over verbose named generic parameter syntax where possible.** [![SwiftFormat: opaqueGenericParameters](https://img.shields.io/badge/SwiftFormat-opaqueGenericParameters-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#opaqueGenericParameters)

<details>

#### Why?

Opaque generic parameter syntax is significantly less verbose and thus more legible than the full named generic parameter syntax.

```swift
// WRONG
func spaceshipDashboard<WarpDriveView: View, CaptainsLogView: View>(
warpDrive: WarpDriveView,
captainsLog: CaptainsLogView)
-> some View
{ }

func generate<Planets>(_ planets: Planets) where Planets: Collection, Planets.Element == Planet {
}

// RIGHT
func spaceshipDashboard(
warpDrive: some View,
captainsLog: some View)
-> some View
{ }

func generate(_ planets: some Collection<Planet>) {
}

// Also fine, since there isn't an equivalent opaque parameter syntax for expressing
// that two parameters in the type signature are of the same type:
func terraform<Body: PlanetaryBody>(_ planetaryBody: Body, into terraformedBody: Body) {
}

// Also fine, since the generic patameter name is referenced in the function body so can't be removed:
func terraform<Body: PlanetaryBody>(_ planetaryBody: Body) {
plataryBody.generateAtmosphere(Body.idealAtmosphere)
}
```

#### `some Any`

Fully-unconstrained generic parameters are somewhat uncommon, but are equivalent to `some Any`. For example:

```swift
func assertFailure<Value>(_ result: Result<Value, Error>) {
if case .failure(let error) = result {
XCTFail(error.localizedDescription)
}
}

// is equivalent to:
func assertFailure(_ result: Result<some Any, Error>) {
if case .failure(let error) = result {
XCTFail(error.localizedDescription)
}
}
```

`some Any` is somewhat unintuitive, and the named generic parameter is useful in this situation to compensate for the weak type information. Because of this, prefer using named generic parameters instead of `some Any`.

</details>

**[⬆ back to top](#table-of-contents)**

## File Organization
Expand Down
2 changes: 2 additions & 0 deletions Sources/AirbnbSwiftFormatTool/airbnb.swiftformat
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
--redundanttype inferred # redundantType
--typeblanklines preserve # blankLinesAtStartOfScope, blankLinesAtEndOfScope
--emptybraces spaced # emptyBraces
--someAny disabled # opaqueGenericParameters

# We recommend a max width of 100 but _strictly enforce_ a max width of 130
--maxwidth 130 # wrap
Expand Down Expand Up @@ -76,5 +77,6 @@
--rules blankLinesAtEndOfScope
--rules emptyBraces
--rules andOperator
--rules opaqueGenericParameters
--rules genericExtensions
--rules trailingClosures

0 comments on commit f600ed0

Please sign in to comment.