Skip to content

Commit 81284f5

Browse files
authored
Merge pull request #4777 from jrose-apple/fix-it-trailing-closure-ambiguity
Offer fix-its to disambiguate based on a trailing closure's label.
2 parents d224450 + e6d6e0e commit 81284f5

File tree

11 files changed

+218
-30
lines changed

11 files changed

+218
-30
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,6 +2235,10 @@ ERROR(ambiguous_decl_ref,none,
22352235
"ambiguous use of %0", (DeclName))
22362236
ERROR(ambiguous_operator_ref,none,
22372237
"ambiguous use of operator %0", (DeclName))
2238+
NOTE(ambiguous_because_of_trailing_closure,none,
2239+
"%select{use an explicit argument label instead of a trailing closure|"
2240+
"avoid using a trailing closure}0 to call %1",
2241+
(bool, DeclName))
22382242

22392243
// Cannot capture inout-ness of a parameter
22402244
// Partial application of foreign functions not supported

include/swift/Basic/DiagnosticOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ class DiagnosticOptions {
2424
/// Indicates whether the diagnostics produced during compilation should be
2525
/// checked against expected diagnostics, indicated by markers in the
2626
/// input source file.
27-
bool VerifyDiagnostics = false;
27+
enum {
28+
NoVerify,
29+
Verify,
30+
VerifyAndApplyFixes
31+
} VerifyMode = NoVerify;
2832

2933
/// Indicates whether diagnostic passes should be skipped.
3034
bool SkipDiagnosticPasses = false;

include/swift/Frontend/DiagnosticVerifier.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@
2323
namespace swift {
2424
class SourceManager;
2525

26-
/// enableDiagnosticVerifier - Set up the specified source manager so that
27-
/// diagnostics are captured instead of being printed.
26+
/// Set up the specified source manager so that diagnostics are captured
27+
/// instead of being printed.
2828
void enableDiagnosticVerifier(SourceManager &SM);
2929

30-
/// verifyDiagnostics - Verify that captured diagnostics meet with the
31-
/// expectations of the source files corresponding to the specified BufferIDs
32-
/// and tear down our support for capturing and verifying diagnostics.
30+
/// Verify that captured diagnostics meet with the expectations of the source
31+
/// files corresponding to the specified \p BufferIDs and tear down our
32+
/// support for capturing and verifying diagnostics.
3333
///
3434
/// This returns true if there are any mismatches found.
35-
///
36-
bool verifyDiagnostics(SourceManager &SM, ArrayRef<unsigned> BufferIDs);
35+
bool verifyDiagnostics(SourceManager &SM, ArrayRef<unsigned> BufferIDs,
36+
bool autoApplyFixes);
3737
}
3838

3939
#endif

include/swift/Option/FrontendOptions.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ def emit_fixits_path
6161
def verify : Flag<["-"], "verify">,
6262
HelpText<"Verify diagnostics against expected-{error|warning|note} "
6363
"annotations">;
64+
def verify_apply_fixes : Flag<["-"], "verify-apply-fixes">,
65+
HelpText<"Like -verify, but updates the original source file">;
6466

6567
def show_diagnostics_after_fatal : Flag<["-"], "show-diagnostics-after-fatal">,
6668
HelpText<"Keep emitting subsequent diagnostics after a fatal error">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,10 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
981981
DiagnosticEngine &Diags) {
982982
using namespace options;
983983

984-
Opts.VerifyDiagnostics |= Args.hasArg(OPT_verify);
984+
if (Args.hasArg(OPT_verify))
985+
Opts.VerifyMode = DiagnosticOptions::Verify;
986+
if (Args.hasArg(OPT_verify_apply_fixes))
987+
Opts.VerifyMode = DiagnosticOptions::VerifyAndApplyFixes;
985988
Opts.SkipDiagnosticPasses |= Args.hasArg(OPT_disable_diagnostic_passes);
986989
Opts.ShowDiagnosticsAfterFatalError |=
987990
Args.hasArg(OPT_show_diagnostics_after_fatal);

lib/Frontend/DiagnosticVerifier.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -677,30 +677,24 @@ void DiagnosticVerifier::autoApplyFixes(unsigned BufferID,
677677
// Main entrypoints
678678
//===----------------------------------------------------------------------===//
679679

680-
/// VerifyModeDiagnosticHook - Every time a diagnostic is generated in -verify
681-
/// mode, this function is called with the diagnostic. We just buffer them up
682-
/// until the end of the file.
680+
/// Every time a diagnostic is generated in -verify mode, this function is
681+
/// called with the diagnostic. We just buffer them up until the end of the
682+
/// file.
683683
static void VerifyModeDiagnosticHook(const llvm::SMDiagnostic &Diag,
684684
void *Context) {
685685
((DiagnosticVerifier*)Context)->addDiagnostic(Diag);
686686
}
687687

688688

689-
/// enableDiagnosticVerifier - Set up the specified source manager so that
690-
/// diagnostics are captured instead of being printed.
691689
void swift::enableDiagnosticVerifier(SourceManager &SM) {
692690
SM.getLLVMSourceMgr().setDiagHandler(VerifyModeDiagnosticHook,
693691
new DiagnosticVerifier(SM));
694692
}
695693

696-
/// verifyDiagnostics - Verify that captured diagnostics meet with the
697-
/// expectations of the source files corresponding to the specified BufferIDs
698-
/// and tear down our support for capturing and verifying diagnostics.
699-
bool swift::verifyDiagnostics(SourceManager &SM, ArrayRef<unsigned> BufferIDs) {
694+
bool swift::verifyDiagnostics(SourceManager &SM, ArrayRef<unsigned> BufferIDs,
695+
bool autoApplyFixes) {
700696
auto *Verifier = (DiagnosticVerifier*)SM.getLLVMSourceMgr().getDiagContext();
701697
SM.getLLVMSourceMgr().setDiagHandler(nullptr, nullptr);
702-
703-
bool autoApplyFixes = false;
704698

705699
bool HadError = false;
706700

lib/FrontendTool/FrontendTool.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,8 @@ int swift::performFrontend(ArrayRef<const char *> Args,
12691269
llvm::EnableStatistics();
12701270
}
12711271

1272-
if (Invocation.getDiagnosticOptions().VerifyDiagnostics) {
1272+
const DiagnosticOptions &diagOpts = Invocation.getDiagnosticOptions();
1273+
if (diagOpts.VerifyMode != DiagnosticOptions::NoVerify) {
12731274
enableDiagnosticVerifier(Instance.getSourceMgr());
12741275
}
12751276

@@ -1298,9 +1299,12 @@ int swift::performFrontend(ArrayRef<const char *> Args,
12981299
Invocation.getFrontendOptions().DumpAPIPath);
12991300
}
13001301

1301-
if (Invocation.getDiagnosticOptions().VerifyDiagnostics) {
1302-
HadError = verifyDiagnostics(Instance.getSourceMgr(),
1303-
Instance.getInputBufferIDs());
1302+
if (diagOpts.VerifyMode != DiagnosticOptions::NoVerify) {
1303+
HadError = verifyDiagnostics(
1304+
Instance.getSourceMgr(),
1305+
Instance.getInputBufferIDs(),
1306+
diagOpts.VerifyMode == DiagnosticOptions::VerifyAndApplyFixes);
1307+
13041308
DiagnosticEngine &diags = Instance.getDiags();
13051309
if (diags.hasFatalErrorOccurred() &&
13061310
!Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {

lib/Sema/CSDiag.cpp

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,113 @@ static unsigned countDistinctOverloads(ArrayRef<OverloadChoice> choices) {
312312

313313
/// \brief Determine the name of the overload in a set of overload choices.
314314
static DeclName getOverloadChoiceName(ArrayRef<OverloadChoice> choices) {
315+
DeclName name;
315316
for (auto choice : choices) {
316-
if (choice.isDecl())
317-
return choice.getDecl()->getFullName();
317+
if (!choice.isDecl())
318+
continue;
319+
320+
DeclName nextName = choice.getDecl()->getFullName();
321+
if (!name) {
322+
name = nextName;
323+
continue;
324+
}
325+
326+
if (name != nextName) {
327+
// Assume all choices have the same base name and only differ in
328+
// argument labels. This may not be a great assumption, but we don't
329+
// really have a way to recover for diagnostics otherwise.
330+
return name.getBaseName();
331+
}
318332
}
319333

320-
return DeclName();
334+
return name;
335+
}
336+
337+
/// Returns true if any diagnostics were emitted.
338+
static bool
339+
tryDiagnoseTrailingClosureAmbiguity(TypeChecker &tc, const Expr *expr,
340+
ArrayRef<OverloadChoice> choices) {
341+
auto *callExpr = dyn_cast<CallExpr>(expr);
342+
if (!callExpr)
343+
return false;
344+
if (!callExpr->hasTrailingClosure())
345+
return false;
346+
347+
llvm::SmallMapVector<Identifier, const ValueDecl *, 8> choicesByLabel;
348+
for (const OverloadChoice &choice : choices) {
349+
auto *callee = dyn_cast<AbstractFunctionDecl>(choice.getDecl());
350+
if (!callee)
351+
return false;
352+
353+
const ParameterList *paramList = callee->getParameterLists().back();
354+
const ParamDecl *param = paramList->getArray().back();
355+
356+
// Sanity-check that the trailing closure corresponds to this parameter.
357+
if (!param->getType()->is<AnyFunctionType>())
358+
return false;
359+
360+
Identifier trailingClosureLabel = param->getArgumentName();
361+
auto &choiceForLabel = choicesByLabel[trailingClosureLabel];
362+
363+
// FIXME: Cargo-culted from diagnoseAmbiguity: apparently the same decl can
364+
// appear more than once?
365+
if (choiceForLabel == callee)
366+
continue;
367+
368+
// If just providing the trailing closure label won't solve the ambiguity,
369+
// don't bother offering the fix-it.
370+
if (choiceForLabel != nullptr)
371+
return false;
372+
373+
choiceForLabel = callee;
374+
}
375+
376+
// If we got here, then all of the choices have unique labels. Offer them in
377+
// order.
378+
SourceManager &sourceMgr = tc.Context.SourceMgr;
379+
SourceLoc replaceStartLoc;
380+
SourceLoc closureStartLoc;
381+
bool hasOtherArgs, needsParens;
382+
if (auto tupleArgs = dyn_cast<TupleExpr>(callExpr->getArg())) {
383+
assert(tupleArgs->getNumElements() >= 2);
384+
const Expr *lastBeforeClosure = tupleArgs->getElements().drop_back().back();
385+
replaceStartLoc =
386+
Lexer::getLocForEndOfToken(sourceMgr, lastBeforeClosure->getEndLoc());
387+
closureStartLoc = tupleArgs->getElements().back()->getStartLoc();
388+
hasOtherArgs = true;
389+
needsParens = false;
390+
} else {
391+
auto parenArgs = cast<ParenExpr>(callExpr->getArg());
392+
replaceStartLoc = parenArgs->getRParenLoc();
393+
closureStartLoc = parenArgs->getSubExpr()->getStartLoc();
394+
hasOtherArgs = false;
395+
needsParens = parenArgs->getRParenLoc().isInvalid();
396+
}
397+
if (!replaceStartLoc.isValid()) {
398+
assert(callExpr->getFn()->getEndLoc().isValid());
399+
replaceStartLoc =
400+
Lexer::getLocForEndOfToken(sourceMgr, callExpr->getFn()->getEndLoc());
401+
}
402+
403+
for (const auto &choicePair : choicesByLabel) {
404+
SmallString<64> insertionString;
405+
if (needsParens)
406+
insertionString += "(";
407+
else if (hasOtherArgs)
408+
insertionString += ", ";
409+
410+
if (!choicePair.first.empty()) {
411+
insertionString += choicePair.first.str();
412+
insertionString += ": ";
413+
}
414+
415+
tc.diagnose(expr->getLoc(), diag::ambiguous_because_of_trailing_closure,
416+
choicePair.first.empty(), choicePair.second->getFullName())
417+
.fixItReplaceChars(replaceStartLoc, closureStartLoc, insertionString)
418+
.fixItInsertAfter(callExpr->getEndLoc(), ")");
419+
}
420+
421+
return true;
321422
}
322423

323424
static bool diagnoseAmbiguity(ConstraintSystem &cs,
@@ -410,9 +511,12 @@ static bool diagnoseAmbiguity(ConstraintSystem &cs,
410511
: diag::ambiguous_decl_ref,
411512
name);
412513

514+
if (tryDiagnoseTrailingClosureAmbiguity(tc, expr, overload.choices))
515+
return true;
516+
413517
// Emit candidates. Use a SmallPtrSet to make sure only emit a particular
414518
// candidate once. FIXME: Why is one candidate getting into the overload
415-
// set multiple times?
519+
// set multiple times? (See also tryDiagnoseTrailingClosureAmbiguity.)
416520
SmallPtrSet<Decl*, 8> EmittedDecls;
417521
for (auto choice : overload.choices) {
418522
switch (choice.getKind()) {

test/expr/closure/trailing.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,71 @@ func r23036383(foo: Foo23036383?, obj: Foo23036383) {
180180
// expected-error@-1 {{trailing closure requires parentheses for disambiguation in this context}} {{22-23=(}} {{28-28=)}}
181181
// expected-error@-2 {{trailing closure requires parentheses for disambiguation in this context}} {{37-38=(x: }} {{43-43=)}}
182182
}
183+
184+
func overloadOnLabel(a: () -> Void) {}
185+
func overloadOnLabel(b: () -> Void) {}
186+
func overloadOnLabel(c: () -> Void) {}
187+
188+
func overloadOnLabel2(a: () -> Void) {}
189+
func overloadOnLabel2(_: () -> Void) {}
190+
191+
func overloadOnLabelArgs(_: Int, a: () -> Void) {}
192+
func overloadOnLabelArgs(_: Int, b: () -> Void) {}
193+
194+
func overloadOnLabelArgs2(_: Int, a: () -> Void) {}
195+
func overloadOnLabelArgs2(_: Int, _: () -> Void) {}
196+
197+
func overloadOnLabelDefaultArgs(x: Int = 0, a: () -> Void) {}
198+
func overloadOnLabelDefaultArgs(x: Int = 1, b: () -> Void) {}
199+
200+
func overloadOnLabelSomeDefaultArgs(_: Int, x: Int = 0, a: () -> Void) {}
201+
func overloadOnLabelSomeDefaultArgs(_: Int, x: Int = 1, b: () -> Void) {}
202+
203+
func overloadOnDefaultArgsOnly(x: Int = 0, a: () -> Void) {} // expected-note 2 {{found this candidate}}
204+
func overloadOnDefaultArgsOnly(y: Int = 1, a: () -> Void) {} // expected-note 2 {{found this candidate}}
205+
206+
func overloadOnDefaultArgsOnly2(x: Int = 0, a: () -> Void) {} // expected-note 2 {{found this candidate}}
207+
func overloadOnDefaultArgsOnly2(y: Bool = true, a: () -> Void) {} // expected-note 2 {{found this candidate}}
208+
209+
func overloadOnDefaultArgsOnly3(x: Int = 0, a: () -> Void) {} // expected-note 2 {{found this candidate}}
210+
func overloadOnDefaultArgsOnly3(x: Bool = true, a: () -> Void) {} // expected-note 2 {{found this candidate}}
211+
212+
func overloadOnSomeDefaultArgsOnly(_: Int, x: Int = 0, a: () -> Void) {} // expected-note {{found this candidate}}
213+
func overloadOnSomeDefaultArgsOnly(_: Int, y: Int = 1, a: () -> Void) {} // expected-note {{found this candidate}}
214+
215+
func overloadOnSomeDefaultArgsOnly2(_: Int, x: Int = 0, a: () -> Void) {} // expected-note {{found this candidate}}
216+
func overloadOnSomeDefaultArgsOnly2(_: Int, y: Bool = true, a: () -> Void) {} // expected-note {{found this candidate}}
217+
218+
func overloadOnSomeDefaultArgsOnly3(_: Int, x: Int = 0, a: () -> Void) {} // expected-note {{found this candidate}}
219+
func overloadOnSomeDefaultArgsOnly3(_: Int, x: Bool = true, a: () -> Void) {} // expected-note {{found this candidate}}
220+
221+
func testOverloadAmbiguity() {
222+
overloadOnLabel {} // expected-error {{ambiguous use of 'overloadOnLabel'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel(a:)'}} {{18-19=(a: }} {{21-21=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel(b:)'}} {{18-19=(b: }} {{21-21=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel(c:)'}} {{18-19=(c: }} {{21-21=)}}
223+
overloadOnLabel() {} // expected-error {{ambiguous use of 'overloadOnLabel'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel(a:)'}} {{19-21=a: }} {{23-23=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel(b:)'}} {{19-21=b: }} {{23-23=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel(c:)'}} {{19-21=c: }} {{23-23=)}}
224+
overloadOnLabel2 {} // expected-error {{ambiguous use of 'overloadOnLabel2'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel2(a:)'}} {{19-20=(a: }} {{22-22=)}} expected-note {{avoid using a trailing closure to call 'overloadOnLabel2'}} {{19-20=(}} {{22-22=)}}
225+
overloadOnLabel2() {} // expected-error {{ambiguous use of 'overloadOnLabel2'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabel2(a:)'}} {{20-22=a: }} {{24-24=)}} expected-note {{avoid using a trailing closure to call 'overloadOnLabel2'}} {{20-22=}} {{24-24=)}}
226+
overloadOnLabelArgs(1) {} // expected-error {{ambiguous use of 'overloadOnLabelArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelArgs(_:a:)'}} {{24-26=, a: }} {{28-28=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelArgs(_:b:)'}} {{24-26=, b: }} {{28-28=)}}
227+
overloadOnLabelArgs2(1) {} // expected-error {{ambiguous use of 'overloadOnLabelArgs2'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelArgs2(_:a:)'}} {{25-27=, a: }} {{29-29=)}} expected-note {{avoid using a trailing closure to call 'overloadOnLabelArgs2'}} {{25-27=, }} {{29-29=)}}
228+
overloadOnLabelDefaultArgs {} // expected-error {{ambiguous use of 'overloadOnLabelDefaultArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelDefaultArgs(x:a:)'}} {{29-30=(a: }} {{32-32=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelDefaultArgs(x:b:)'}} {{29-30=(b: }} {{32-32=)}}
229+
overloadOnLabelDefaultArgs() {} // expected-error {{ambiguous use of 'overloadOnLabelDefaultArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelDefaultArgs(x:a:)'}} {{30-32=a: }} {{34-34=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelDefaultArgs(x:b:)'}} {{30-32=b: }} {{34-34=)}}
230+
overloadOnLabelDefaultArgs(x: 2) {} // expected-error {{ambiguous use of 'overloadOnLabelDefaultArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelDefaultArgs(x:a:)'}} {{34-36=, a: }} {{38-38=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelDefaultArgs(x:b:)'}} {{34-36=, b: }} {{38-38=)}}
231+
overloadOnLabelSomeDefaultArgs(1) {} // expected-error {{ambiguous use of 'overloadOnLabelSomeDefaultArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelSomeDefaultArgs(_:x:a:)'}} {{35-37=, a: }} {{39-39=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelSomeDefaultArgs(_:x:b:)'}} {{35-37=, b: }} {{39-39=)}}
232+
overloadOnLabelSomeDefaultArgs(1, x: 2) {} // expected-error {{ambiguous use of 'overloadOnLabelSomeDefaultArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelSomeDefaultArgs(_:x:a:)'}} {{41-43=, a: }} {{45-45=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelSomeDefaultArgs(_:x:b:)'}} {{41-43=, b: }} {{45-45=)}}
233+
234+
overloadOnLabelSomeDefaultArgs( // expected-error {{ambiguous use of 'overloadOnLabelSomeDefaultArgs'}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelSomeDefaultArgs(_:x:a:)'}} {{12-5=, a: }} {{4-4=)}} expected-note {{use an explicit argument label instead of a trailing closure to call 'overloadOnLabelSomeDefaultArgs(_:x:b:)'}} {{12-5=, b: }} {{4-4=)}}
235+
1, x: 2
236+
) {
237+
// some
238+
}
239+
240+
overloadOnDefaultArgsOnly {} // expected-error {{ambiguous use of 'overloadOnDefaultArgsOnly'}}
241+
overloadOnDefaultArgsOnly() {} // expected-error {{ambiguous use of 'overloadOnDefaultArgsOnly'}}
242+
overloadOnDefaultArgsOnly2 {} // expected-error {{ambiguous use of 'overloadOnDefaultArgsOnly2'}}
243+
overloadOnDefaultArgsOnly2() {} // expected-error {{ambiguous use of 'overloadOnDefaultArgsOnly2'}}
244+
overloadOnDefaultArgsOnly3 {} // expected-error {{ambiguous use of 'overloadOnDefaultArgsOnly3(x:a:)'}}
245+
overloadOnDefaultArgsOnly3() {} // expected-error {{ambiguous use of 'overloadOnDefaultArgsOnly3(x:a:)'}}
246+
247+
overloadOnSomeDefaultArgsOnly(1) {} // expected-error {{ambiguous use of 'overloadOnSomeDefaultArgsOnly'}}
248+
overloadOnSomeDefaultArgsOnly2(1) {} // expected-error {{ambiguous use of 'overloadOnSomeDefaultArgsOnly2'}}
249+
overloadOnSomeDefaultArgsOnly3(1) {} // expected-error {{ambiguous use of 'overloadOnSomeDefaultArgsOnly3(_:x:a:)'}}
250+
}

test/expr/unary/selector/selector.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class C1 {
1515
@objc class func method3(_ a: A, b: B) { } // expected-note{{found this candidate}}
1616
@objc class func method3(a: A, b: B) { } // expected-note{{found this candidate}}
1717

18+
@objc(ambiguous1:b:) class func ambiguous(a: A, b: A) { } // expected-note{{found this candidate}}
19+
@objc(ambiguous2:b:) class func ambiguous(a: A, b: B) { } // expected-note{{found this candidate}}
20+
1821
@objc func getC1() -> AnyObject { return self }
1922

2023
@objc func testUnqualifiedSelector(_ a: A, b: B) {
@@ -83,7 +86,8 @@ func testSelector(_ c1: C1, p1: P1, obj: AnyObject) {
8386
}
8487

8588
func testAmbiguity() {
86-
_ = #selector(C1.method3) // expected-error{{ambiguous use of 'method3(_:b:)'}}
89+
_ = #selector(C1.method3) // expected-error{{ambiguous use of 'method3'}}
90+
_ = #selector(C1.ambiguous) // expected-error{{ambiguous use of 'ambiguous(a:b:)'}}
8791
}
8892

8993
func testUnusedSelector() {

tools/sil-opt/SILOpt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ int main(int argc, char **argv) {
354354
// If we're in -verify mode, we've buffered up all of the generated
355355
// diagnostics. Check now to ensure that they meet our expectations.
356356
if (VerifyMode) {
357-
HadError = verifyDiagnostics(CI.getSourceMgr(), CI.getInputBufferIDs());
357+
HadError = verifyDiagnostics(CI.getSourceMgr(), CI.getInputBufferIDs(),
358+
/*autoApplyFixes*/false);
358359
DiagnosticEngine &diags = CI.getDiags();
359360
if (diags.hasFatalErrorOccurred() &&
360361
!Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {

0 commit comments

Comments
 (0)