Skip to content

Commit d10dfb3

Browse files
Merge pull request #82020 from AnthonyLatsis/camellia-sinensis
Sema: Never record argument label mismatches for unlabeled trailing closures
2 parents d38b961 + f2e1420 commit d10dfb3

File tree

5 files changed

+52
-15
lines changed

5 files changed

+52
-15
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6665,12 +6665,6 @@ bool isSIMDOperator(ValueDecl *value);
66656665

66666666
std::string describeGenericType(ValueDecl *GP, bool includeName = false);
66676667

6668-
/// Whether the given parameter requires an argument.
6669-
bool parameterRequiresArgument(
6670-
ArrayRef<AnyFunctionType::Param> params,
6671-
const ParameterListInfo &paramInfo,
6672-
unsigned paramIdx);
6673-
66746668
} // end namespace swift
66756669

66766670
namespace llvm {

lib/Sema/CSSimplify.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,9 @@ static ConstraintSystem::TypeMatchOptions getDefaultDecompositionOptions(
279279
}
280280

281281
/// Whether the given parameter requires an argument.
282-
bool swift::parameterRequiresArgument(
283-
ArrayRef<AnyFunctionType::Param> params,
284-
const ParameterListInfo &paramInfo,
285-
unsigned paramIdx) {
282+
static bool parameterRequiresArgument(ArrayRef<AnyFunctionType::Param> params,
283+
const ParameterListInfo &paramInfo,
284+
unsigned paramIdx) {
286285
return !paramInfo.hasDefaultArgument(paramIdx)
287286
&& !params[paramIdx].isVariadic();
288287
}
@@ -374,8 +373,15 @@ static bool matchCallArgumentsImpl(
374373
auto claim = [&](Identifier expectedName, unsigned argIdx,
375374
bool ignoreNameClash = false) -> unsigned {
376375
// Make sure we can claim this argument.
377-
assert(argIdx != numArgs && "Must have a valid index to claim");
378-
assert(!claimedArgs[argIdx] && "Argument already claimed");
376+
ASSERT(argIdx != numArgs && "Must have a valid index to claim");
377+
ASSERT(!claimedArgs[argIdx] && "Argument already claimed");
378+
379+
// Prevent recording of an argument label mismatche for an unlabeled
380+
// trailing closure. An unlabeled trailing closure is necessarily the first
381+
// one and vice versa, per language syntax.
382+
if (unlabeledTrailingClosureArgIndex == argIdx) {
383+
expectedName = Identifier();
384+
}
379385

380386
if (!actualArgNames.empty()) {
381387
// We're recording argument names; record this one.

lib/Sema/MiscDiagnostics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2701,8 +2701,10 @@ bool swift::diagnoseArgumentLabelError(ASTContext &ctx,
27012701
}
27022702
}
27032703

2704+
ASSERT((numMissing + numExtra + numWrong > 0) &&
2705+
"Should not call this function with nothing to diagnose");
2706+
27042707
// Emit the diagnostic.
2705-
assert(numMissing > 0 || numExtra > 0 || numWrong > 0);
27062708
llvm::SmallString<16> haveBuffer; // note: diagOpt has references to this
27072709
llvm::SmallString<16> expectedBuffer; // note: diagOpt has references to this
27082710

test/expr/closure/trailing.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,39 @@ func rdar92521618() {
488488
if let _ = { foo {} }() {}
489489
guard let _ = { foo {} }() else { return }
490490
}
491+
492+
// Argument matching never binds trailing closure arguments to
493+
// defaulted/variadic parameters of non-function type.
494+
do {
495+
// Trailing closure not considered fulfilled by 'arg'.
496+
// Note: Used to crash.
497+
do {
498+
func variadic(arg: Int...) {} // expected-note@:10 {{'variadic(arg:)' declared here}}{{none}}
499+
func defaulted(arg: Int = 0) {}
500+
501+
let _ = variadic { return () }
502+
// expected-error@-1:22 {{trailing closure passed to parameter of type 'Int' that does not accept a closure}}{{none}}
503+
let _ = defaulted { return () }
504+
// expected-error@-1:23 {{extra trailing closure passed in call}}{{none}}
505+
}
506+
// Trailing closure considered fulfilled by 'x' instead of 'arg'.
507+
do {
508+
func variadic(arg: Int..., x: String) {} // expected-note@:10 {{'variadic(arg:x:)' declared here}}{{none}}
509+
func defaulted(arg: Int = 0, x: String) {} // expected-note@:10 {{'defaulted(arg:x:)' declared here}}{{none}}
510+
511+
let _ = variadic { return () }
512+
// expected-error@-1:22 {{trailing closure passed to parameter of type 'String' that does not accept a closure}}{{none}}
513+
let _ = defaulted { return () }
514+
// expected-error@-1:23 {{trailing closure passed to parameter of type 'String' that does not accept a closure}}{{none}}
515+
}
516+
// Trailing closure considered fulfilled by 'arg'; has function type.
517+
do {
518+
func variadic(arg: ((Int) -> Void)...) {}
519+
func defaulted(arg: ((Int) -> Void) = { _ in }) {}
520+
521+
let _ = variadic { return () }
522+
// expected-error@-1:22 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}}{{23-23= _ in}}
523+
let _ = defaulted { return () }
524+
// expected-error@-1:23 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}}{{24-24= _ in}}
525+
}
526+
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
// {"signature":"(anonymous namespace)::OpaqueUnderlyingTypeChecker::check()"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
3-
// REQUIRES: asserts
2+
// RUN: not %target-swift-frontend -typecheck %s
43
Array {

0 commit comments

Comments
 (0)