@@ -366,10 +366,21 @@ class AbstractFunction {
366
366
}
367
367
368
368
static AbstractFunction decomposeApply (ApplyExpr *apply,
369
- SmallVectorImpl<Expr*> &args ) {
369
+ SmallVectorImpl<SmallVector< Expr *, 2 >> &argLists ) {
370
370
Expr *fn;
371
371
do {
372
- args.push_back (apply->getArg ());
372
+ auto *argExpr = apply->getArg ();
373
+ if (auto *tupleExpr = dyn_cast<TupleExpr>(argExpr)) {
374
+ auto args = tupleExpr->getElements ();
375
+ argLists.emplace_back (args.begin (), args.end ());
376
+ } else if (auto *parenExpr = dyn_cast<ParenExpr>(argExpr)) {
377
+ argLists.emplace_back ();
378
+ argLists.back ().push_back (parenExpr->getSubExpr ());
379
+ } else {
380
+ argLists.emplace_back ();
381
+ argLists.back ().push_back (argExpr);
382
+ }
383
+
373
384
fn = apply->getFn ()->getValueProvidingExpr ();
374
385
} while ((apply = dyn_cast<ApplyExpr>(fn)));
375
386
@@ -733,13 +744,15 @@ class ApplyClassifier {
733
744
734
745
bool isAsync = fnType->isAsync () || E->implicitlyAsync ();
735
746
// Decompose the application.
736
- SmallVector<Expr*, 4 > args ;
737
- auto fnRef = AbstractFunction::decomposeApply (E, args );
747
+ SmallVector<SmallVector< Expr *, 2 >, 2 > argLists ;
748
+ auto fnRef = AbstractFunction::decomposeApply (E, argLists );
738
749
739
750
// If any of the arguments didn't type check, fail.
740
- for (auto arg : args) {
741
- if (!arg->getType () || arg->getType ()->hasError ())
742
- return Classification::forInvalidCode ();
751
+ for (auto argList : argLists) {
752
+ for (auto *arg : argList) {
753
+ if (!arg->getType () || arg->getType ()->hasError ())
754
+ return Classification::forInvalidCode ();
755
+ }
743
756
}
744
757
745
758
if (fnRef.getRethrowingKind () == FunctionRethrowingKind::ByConformance) {
@@ -780,12 +793,12 @@ class ApplyClassifier {
780
793
// If we're applying more arguments than the natural argument
781
794
// count, then this is a call to the opaque value returned from
782
795
// the function.
783
- if (args .size () != fnRef.getNumArgumentsForFullApply ()) {
796
+ if (argLists .size () != fnRef.getNumArgumentsForFullApply ()) {
784
797
// Special case: a reference to an operator within a type might be
785
798
// missing 'self'.
786
799
// FIXME: The issue here is that this is an ill-formed expression, but
787
800
// we don't know it from the structure of the expression.
788
- if (args .size () == 1 && fnRef.getKind () == AbstractFunction::Function &&
801
+ if (argLists .size () == 1 && fnRef.getKind () == AbstractFunction::Function &&
789
802
isa<FuncDecl>(fnRef.getFunction ()) &&
790
803
cast<FuncDecl>(fnRef.getFunction ())->isOperator () &&
791
804
fnRef.getNumArgumentsForFullApply () == 2 &&
@@ -795,7 +808,7 @@ class ApplyClassifier {
795
808
return Classification::forInvalidCode ();
796
809
}
797
810
798
- assert (args .size () > fnRef.getNumArgumentsForFullApply () &&
811
+ assert (argLists .size () > fnRef.getNumArgumentsForFullApply () &&
799
812
" partial application was throwing?" );
800
813
return Classification::forThrow (PotentialThrowReason::forThrowingApply (),
801
814
isAsync);
@@ -813,13 +826,20 @@ class ApplyClassifier {
813
826
// Use the most significant result from the arguments.
814
827
Classification result = isAsync ? Classification::forAsync ()
815
828
: Classification ();
816
- for (auto arg : llvm::reverse (args )) {
829
+ for (auto argList : llvm::reverse (argLists )) {
817
830
auto fnType = type->getAs <AnyFunctionType>();
818
- if (!fnType) return Classification::forInvalidCode ();
831
+ if (!fnType)
832
+ return Classification::forInvalidCode ();
833
+
834
+ auto params = fnType->getParams ();
835
+ if (params.size () != argList.size ())
836
+ return Classification::forInvalidCode ();
837
+
838
+ for (unsigned i = 0 , e = params.size (); i < e; ++i) {
839
+ result.merge (classifyRethrowsArgument (argList[i],
840
+ params[i].getParameterType ()));
841
+ }
819
842
820
- auto paramType = FunctionType::composeInput (fnType->getASTContext (),
821
- fnType->getParams (), false );
822
- result.merge (classifyRethrowsArgument (arg, paramType));
823
843
type = fnType->getResult ();
824
844
}
825
845
return result;
0 commit comments