Skip to content

Commit 54005af

Browse files
author
Harlan Haskins
authored
Merge pull request #26258 from mcichecki/SR-10979
[SR-10979] Add fix-it for missing operator
2 parents 4fcac39 + b4ae75b commit 54005af

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3771,8 +3771,36 @@ void bindFuncDeclToOperator(TypeChecker &TC, FuncDecl *FD) {
37713771
}
37723772

37733773
if (!op) {
3774-
// FIXME: Add Fix-It introducing an operator declaration?
3775-
TC.diagnose(FD, diag::declared_operator_without_operator_decl);
3774+
SourceLoc insertionLoc;
3775+
if (isa<SourceFile>(FD->getParent())) {
3776+
// Parent context is SourceFile, insertion location is start of func declaration
3777+
// or unary operator
3778+
insertionLoc = FD->isUnaryOperator() ? FD->getAttrs().getStartLoc() : FD->getStartLoc();
3779+
} else {
3780+
// Finding top-level decl context before SourceFile and inserting before it
3781+
for (DeclContext *CurContext = FD->getLocalContext();
3782+
!isa<SourceFile>(CurContext);
3783+
CurContext = CurContext->getParent()) {
3784+
insertionLoc = CurContext->getAsDecl()->getStartLoc();
3785+
}
3786+
}
3787+
3788+
SmallString<128> insertion;
3789+
auto numOfParams = FD->getParameters()->size();
3790+
if (numOfParams == 1) {
3791+
if (FD->getAttrs().hasAttribute<PrefixAttr>())
3792+
insertion += "prefix operator ";
3793+
else
3794+
insertion += "postfix operator ";
3795+
} else if (numOfParams == 2) {
3796+
insertion += "infix operator ";
3797+
}
3798+
3799+
insertion += operatorName.str();
3800+
insertion += " : <# Precedence Group #>\n";
3801+
InFlightDiagnostic opDiagnostic = TC.diagnose(FD, diag::declared_operator_without_operator_decl);
3802+
if (insertionLoc.isValid())
3803+
opDiagnostic.fixItInsert(insertionLoc, insertion);
37763804
return;
37773805
}
37783806

test/decl/func/operator.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,27 @@ struct Y {}
1111

1212
func +(lhs: X, rhs: X) -> X {} // okay
1313

14-
func +++(lhs: X, rhs: X) -> X {} // expected-error {{operator implementation without matching operator declaration}}
14+
func <=>(lhs: X, rhs: X) -> X {} // expected-error {{operator implementation without matching operator declaration}}{{1-1=infix operator <=> : <# Precedence Group #>\n}}
15+
16+
extension X {
17+
static func <=>(lhs: X, rhs: X) -> X {} // expected-error {{operator implementation without matching operator declaration}}{{1-1=infix operator <=> : <# Precedence Group #>\n}}
18+
}
19+
20+
extension X {
21+
struct Z {
22+
static func <=> (lhs: Z, rhs: Z) -> Z {} // expected-error {{operator implementation without matching operator declaration}}{{1-1=infix operator <=> : <# Precedence Group #>\n}}
23+
}
24+
}
25+
26+
extension X {
27+
static prefix func <=>(lhs: X) -> X {} // expected-error {{operator implementation without matching operator declaration}}{{1-1=prefix operator <=> : <# Precedence Group #>\n}}
28+
}
29+
30+
extension X {
31+
struct ZZ {
32+
static prefix func <=>(lhs: ZZ) -> ZZ {} // expected-error {{operator implementation without matching operator declaration}}{{1-1=prefix operator <=> : <# Precedence Group #>\n}}
33+
}
34+
}
1535

1636
infix operator ++++ : ReallyHighPrecedence
1737
precedencegroup ReallyHighPrecedence {

0 commit comments

Comments
 (0)