Skip to content

Commit 4d42f13

Browse files
authored
Address warnings about retroactively conforming types from other modules to protocols (#957)
* Add @retroactive annotations with explanatory comments to address warnings * Fix false-positive warning about inner function not throwing * Use backwards compatible syntax for retroactive protocol conformance * Update comments about retroactive protocol conformances
1 parent a8ad29e commit 4d42f13

File tree

7 files changed

+53
-14
lines changed

7 files changed

+53
-14
lines changed

Sources/SwiftDocC/DocumentationService/Convert/Symbol Link Resolution/DocCSymbolRepresentable.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -164,6 +164,15 @@ public extension Collection where Element: DocCSymbolRepresentable {
164164
}
165165
}
166166

167+
#if compiler(>=6)
168+
// DocCSymbolRepresentable inherits from Equatable. If SymbolKit added Equatable conformance in the future, this could behave differently.
169+
// It's reasonable to expect that symbols with the same unique ID would be equal but it's possible that SymbolKit's implementation would consider more symbol properties.
170+
//
171+
// In the long term we should try to phase out DocCSymbolRepresentable since it doesn't reflect how DocC resolves links or disambiguated symbols in links.
172+
extension SymbolGraph.Symbol: @retroactive Equatable {}
173+
extension UnifiedSymbolGraph.Symbol: @retroactive Equatable {}
174+
#endif
175+
167176
extension SymbolGraph.Symbol: DocCSymbolRepresentable {
168177
public var preciseIdentifier: String? {
169178
self.identifier.precise

Sources/SwiftDocC/Infrastructure/Symbol Graph/AccessControl+Comparable.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -10,7 +10,12 @@
1010

1111
import SymbolKit
1212

13-
extension SymbolGraph.Symbol.AccessControl: Comparable {
13+
// Use fully-qualified types to silence a warning about retroactively conforming a type from another module to a new protocol (SE-0364).
14+
// The `@retroactive` attribute is new in the Swift 6 compiler. The backwards compatible syntax for a retroactive conformance is fully-qualified types.
15+
//
16+
// SymbolKit doesn't define any access control values ("open", "public", "internal", "filePrivate", and "private", are defined in SwiftDocC).
17+
// Because AccessControl only has a string raw value, it's unlikely that SymbolKit would add a Comparable conformance and default implementation.
18+
extension SymbolKit.SymbolGraph.Symbol.AccessControl: Swift.Comparable {
1419
private var level: Int? {
1520
switch self {
1621
case .private : return 1

Sources/SwiftDocC/Utility/SemanticVersion+Comparable.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -11,7 +11,14 @@
1111
import Foundation
1212
import SymbolKit
1313

14-
extension SymbolGraph.SemanticVersion: Comparable {
14+
// Use fully-qualified types to silence a warning about retroactively conforming a type from another module to a new protocol (SE-0364).
15+
// The `@retroactive` attribute is new in the Swift 6 compiler. The backwards compatible syntax for a retroactive conformance is fully-qualified types.
16+
//
17+
// If SymbolKit adds Comparable conformance it's reasonable to expect that its behavior would be compatible.
18+
//
19+
// As long as a hypothetical future SymbolKit implementation considers "major", "minor", and "patch" before comparing the "prerelease" and "buildMetadata"
20+
// components, the behavior will remain compatible with what SwiftDocC expects.
21+
extension SymbolKit.SymbolGraph.SemanticVersion: Swift.Comparable {
1522
/// Compares two semantic versions.
1623
public static func < (lhs: SymbolGraph.SemanticVersion, rhs: SymbolGraph.SemanticVersion) -> Bool {
1724
return (lhs.major, lhs.minor, lhs.patch) < (rhs.major, rhs.minor, rhs.patch)

Sources/SwiftDocCUtilities/ArgumentParsing/Options/DocumentationCoverageOptionsArgument.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -85,9 +85,15 @@ public struct DocumentationCoverageOptionsArgument: ParsableArguments {
8585
}
8686
}
8787

88-
// SwiftDocCUtilities imports SwiftDocC. SwiftDocC does not link against ArgumentParser (because it isn't about CLI). We conform here because this is the first place that we can. We implement in DocC.
89-
extension DocumentationCoverageLevel: ExpressibleByArgument {}
90-
extension DocumentationCoverageOptions.KindFilterOptions.BitFlagRepresentation: ExpressibleByArgument {}
88+
// Use fully-qualified types to silence a warning about retroactively conforming a type from another module to a new protocol (SE-0364).
89+
// The `@retroactive` attribute is new in the Swift 6 compiler. The backwards compatible syntax for a retroactive conformance is fully-qualified types.
90+
//
91+
// It is safe to add a retroactively conformance here because the other module (SwiftDocC) is in the same package.
92+
//
93+
// These conforming types are defined in SwiftDocC and extended in SwiftDocCUtilities, because SwiftDocC doesn't link against ArgumentParse (since it isn't about CLI).
94+
// We conform here because this is the first place that we can add the conformance. The implementation is in SwiftDocC.
95+
extension SwiftDocC.DocumentationCoverageLevel: ArgumentParser.ExpressibleByArgument {}
96+
extension SwiftDocC.DocumentationCoverageOptions.KindFilterOptions.BitFlagRepresentation: ArgumentParser.ExpressibleByArgument {}
9197

9298
extension DocumentationCoverageOptions {
9399
public init(from arguments: DocumentationCoverageOptionsArgument) {

Sources/generate-symbol-graph/main.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -57,7 +57,11 @@ func directiveUSR(_ directiveName: String) -> String {
5757
"__docc_universal_symbol_reference_$\(directiveName)"
5858
}
5959

60-
extension SymbolGraph.Symbol.DeclarationFragments.Fragment: ExpressibleByStringInterpolation {
60+
// Use fully-qualified types to silence a warning about retroactively conforming a type from another module to a new protocol (SE-0364).
61+
// The `@retroactive` attribute is new in the Swift 6 compiler. The backwards compatible syntax for a retroactive conformance is fully-qualified types.
62+
//
63+
// This conformance it only relevant to the `generate-symbol-graph` script.
64+
extension SymbolKit.SymbolGraph.Symbol.DeclarationFragments.Fragment: Swift.ExpressibleByStringInterpolation {
6165
public init(stringLiteral value: String) {
6266
self.init(kind: .text, spelling: value, preciseIdentifier: nil)
6367
}
@@ -71,7 +75,11 @@ extension SymbolGraph.Symbol.DeclarationFragments.Fragment: ExpressibleByStringI
7175
}
7276
}
7377

74-
extension SymbolGraph.LineList.Line: ExpressibleByStringInterpolation {
78+
// Use fully-qualified types to silence a warning about retroactively conforming a type from another module to a new protocol (SE-0364).
79+
// The `@retroactive` attribute is new in the Swift 6 compiler. The backwards compatible syntax for a retroactive conformance is fully-qualified types.
80+
//
81+
// This conformance it only relevant to the `generate-symbol-graph` script.
82+
extension SymbolKit.SymbolGraph.LineList.Line: Swift.ExpressibleByStringInterpolation {
7583
public init(stringLiteral value: String) {
7684
self.init(text: value, range: nil)
7785
}

Tests/SwiftDocCTests/Model/RenderNodeSerializationTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ class RenderNodeSerializationTests: XCTestCase {
225225
let kind: RenderNode.Kind
226226
}
227227
func decodeKind(jsonString: String) throws -> RenderNode.Kind {
228-
return try JSONDecoder().decode(Wrapper.self, from: "{ \"kind\" : \(jsonString) }".data(using: .utf8)!).kind
228+
return try JSONDecoder().decode(RenderNode.Kind.self, from: Data(jsonString.utf8))
229229
}
230230

231231
// Both values can be decoded

Tests/SwiftDocCTests/Semantics/Reference/RowTests.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,11 @@ class RowTests: XCTestCase {
283283

284284
}
285285

286-
extension RenderBlockContent: ExpressibleByStringLiteral {
286+
// Use fully-qualified types to silence a warning about retroactively conforming a type from another module to a new protocol (SE-0364).
287+
// The `@retroactive` attribute is new in the Swift 6 compiler. The backwards compatible syntax for a retroactive conformance is fully-qualified types.
288+
//
289+
// It is safe to add a retroactively conformance here because the other module (SwiftDocC) is in the same package.
290+
extension SwiftDocC.RenderBlockContent: Swift.ExpressibleByStringLiteral {
287291
public init(stringLiteral value: String) {
288292
self = RenderBlockContent.paragraph(Paragraph(inlineContent: [.text(value)]))
289293
}

0 commit comments

Comments
 (0)