Skip to content

Commit cb60f52

Browse files
authored
Merge pull request #1281 from ahoppen/ahoppen/missing-requirement-diagnostic
Improve diagnostic if where clause is missing a requirement
2 parents c17f6b0 + 84429cb commit cb60f52

File tree

4 files changed

+21
-4
lines changed

4 files changed

+21
-4
lines changed

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,20 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
776776
return .visitChildren
777777
}
778778

779+
public override func visit(_ node: SameTypeRequirementSyntax) -> SyntaxVisitorContinueKind {
780+
if shouldSkip(node) {
781+
return .skipChildren
782+
}
783+
if node.equalityToken.presence == .missing && node.rightTypeIdentifier.isMissingAllTokens {
784+
addDiagnostic(
785+
node.equalityToken,
786+
.missingConformanceRequirement,
787+
handledNodes: [node.equalityToken.id, node.rightTypeIdentifier.id]
788+
)
789+
}
790+
return .visitChildren
791+
}
792+
779793
public override func visit(_ node: SourceFileSyntax) -> SyntaxVisitorContinueKind {
780794
if shouldSkip(node) {
781795
return .skipChildren

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ extension DiagnosticMessage where Self == StaticParserError {
149149
public static var missingColonInTernaryExpr: Self {
150150
.init("expected ':' after '? ...' in ternary expression")
151151
}
152+
public static var missingConformanceRequirement: Self {
153+
.init("expected ':' or '==' to indicate a conformance or same-type requirement")
154+
}
152155
public static var misspelledAsync: Self {
153156
.init("expected async specifier; did you mean 'async'?")
154157
}

Tests/SwiftParserTest/AttributeTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ final class AttributeTests: XCTestCase {
4343
""",
4444
diagnostics: [
4545
DiagnosticSpec(locationMarker: "1️⃣", message: "expected ':' and parameters in '@differentiable' argument", fixIts: ["insert ':' and parameters"]),
46-
DiagnosticSpec(locationMarker: "2️⃣", message: "expected '=' and right-hand type in same type requirement", fixIts: ["insert '=' and right-hand type"]),
46+
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ':' or '==' to indicate a conformance or same-type requirement"),
4747
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ')' to end attribute", fixIts: ["insert ')'"]),
4848
],
4949
fixedSource: """
50-
@differentiable(reverse wrt: <#identifier#>,where T = <#type#>)
50+
@differentiable(reverse wrt: <#identifier#>,where T)
5151
func podcastPlaybackSpeed() {
5252
}
5353
"""

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ final class DeclarationTests: XCTestCase {
123123
AssertParse(
124124
"class T where t1️⃣",
125125
diagnostics: [
126-
DiagnosticSpec(message: "expected '=' and right-hand type in same type requirement"),
126+
DiagnosticSpec(message: "expected ':' or '==' to indicate a conformance or same-type requirement"),
127127
DiagnosticSpec(message: "expected member block in class"),
128128
]
129129
)
130130
AssertParse(
131131
"class B<where g1️⃣",
132132
diagnostics: [
133-
DiagnosticSpec(message: "expected '=' and right-hand type in same type requirement"),
133+
DiagnosticSpec(message: "expected ':' or '==' to indicate a conformance or same-type requirement"),
134134
DiagnosticSpec(message: "expected '>' to end generic parameter clause"),
135135
DiagnosticSpec(message: "expected member block in class"),
136136
]

0 commit comments

Comments
 (0)