Skip to content

Commit cc5e64d

Browse files
authored
Merge pull request #4459 from DougGregor/fix-crashes-rdar27940842
[Type checker] Improve recovery from erroneous operators in types.
2 parents 55aa909 + e939de4 commit cc5e64d

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,6 +4335,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
43354335
dc->getDeclaredInterfaceType())
43364336
.fixItInsert(FD->getAttributeInsertionLoc(/*forModifier=*/true),
43374337
"static ");
4338+
4339+
FD->setStatic();
43384340
} else {
43394341
TC.diagnose(FD->getLoc(), diag::nonfinal_operator_in_class,
43404342
operatorName, dc->getDeclaredInterfaceType())
@@ -4350,6 +4352,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
43504352
dc->getDeclaredInterfaceType())
43514353
.fixItInsert(FD->getAttributeInsertionLoc(/*forModifier=*/true),
43524354
"static ");
4355+
FD->setStatic();
43534356
}
43544357
} else if (!dc->isModuleScopeContext()) {
43554358
TC.diagnose(FD, diag::operator_in_local_scope);

lib/Sema/TypeCheckError.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ class ApplyClassifier {
406406
SmallVector<Expr*, 4> args;
407407
auto fnRef = AbstractFunction::decomposeApply(E, args);
408408

409+
// If any of the arguments didn't type check, fail.
410+
for (auto arg : args) {
411+
if (!arg->getType() || arg->getType()->is<ErrorType>())
412+
return Classification::forInvalidCode();
413+
}
414+
409415
// If we're applying more arguments than the natural argument
410416
// count, then this is a call to the opaque value returned from
411417
// the function.

test/decl/func/operator.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,20 @@ extension P3 {
336336
// Okay: refers to P3
337337
static func %%%%(lhs: P3, rhs: Unrelated) -> Unrelated { }
338338
}
339+
340+
// rdar://problem/27940842 - recovery with a non-static '=='.
341+
class C5 {
342+
func == (lhs: C5, rhs: C5) -> Bool { return false } // expected-error{{operator '==' declared in type 'C5' must be 'static'}}
343+
344+
func test1(x: C5) {
345+
_ = x == x
346+
}
347+
}
348+
349+
class C6 {
350+
static func == (lhs: C6, rhs: C6) -> Bool { return false }
351+
352+
func test1(x: C6) {
353+
if x == x && x = x { } // expected-error{{cannot assign to value: '&&' returns immutable value}}
354+
}
355+
}

0 commit comments

Comments
 (0)