@@ -483,6 +483,10 @@ namespace {
483
483
484
484
// Handle operator requirements found in protocols.
485
485
if (auto proto = dyn_cast<ProtocolDecl>(decl->getDeclContext ())) {
486
+ bool isCurried = shouldBuildCurryThunk (choice,
487
+ /* baseIsInstance=*/ false ,
488
+ /* extraUncurryLevel=*/ false );
489
+
486
490
// If we have a concrete conformance, build a call to the witness.
487
491
//
488
492
// FIXME: This is awful. We should be able to handle this as a call to
@@ -494,49 +498,53 @@ namespace {
494
498
ConformanceCheckFlags::InExpression);
495
499
if (conformance.isConcrete ()) {
496
500
if (auto witness = conformance.getConcrete ()->getWitnessDecl (decl)) {
497
- // The fullType was computed by substituting the protocol
498
- // requirement so it always has a (Self) -> ... curried
499
- // application. Strip it off if the witness was a top-level
500
- // function.
501
- Type refType;
502
- if (witness->getDeclContext ()->isTypeContext ())
503
- refType = fullType;
504
- else
505
- refType = fullType->castTo <AnyFunctionType>()->getResult ();
506
-
507
- // Build the AST for the call to the witness.
508
- auto subMap = getOperatorSubstitutions (witness, refType);
509
- if (subMap) {
510
- ConcreteDeclRef witnessRef (witness, *subMap);
511
- auto declRefExpr = new (ctx) DeclRefExpr (witnessRef, loc,
512
- /* Implicit=*/ false );
513
- declRefExpr->setFunctionRefKind (choice.getFunctionRefKind ());
514
- cs.setType (declRefExpr, refType);
515
-
516
- Expr *refExpr;
517
- if (witness->getDeclContext ()->isTypeContext ()) {
518
- // If the operator is a type member, add the implicit
519
- // (Self) -> ... call.
520
- Expr *base =
521
- TypeExpr::createImplicitHack (loc.getBaseNameLoc (), baseTy,
522
- ctx);
523
- cs.setType (base, MetatypeType::get (baseTy));
524
-
525
- refExpr = new (ctx) DotSyntaxCallExpr (declRefExpr,
526
- SourceLoc (), base);
527
- auto refType = fullType->castTo <FunctionType>()->getResult ();
528
- cs.setType (refExpr, refType);
529
- } else {
530
- refExpr = declRefExpr;
501
+ bool isMemberOperator = witness->getDeclContext ()->isTypeContext ();
502
+
503
+ if (!isMemberOperator || !isCurried) {
504
+ // The fullType was computed by substituting the protocol
505
+ // requirement so it always has a (Self) -> ... curried
506
+ // application. Strip it off if the witness was a top-level
507
+ // function.
508
+ Type refType;
509
+ if (isMemberOperator)
510
+ refType = fullType;
511
+ else
512
+ refType = fullType->castTo <AnyFunctionType>()->getResult ();
513
+
514
+ // Build the AST for the call to the witness.
515
+ auto subMap = getOperatorSubstitutions (witness, refType);
516
+ if (subMap) {
517
+ ConcreteDeclRef witnessRef (witness, *subMap);
518
+ auto declRefExpr = new (ctx) DeclRefExpr (witnessRef, loc,
519
+ /* Implicit=*/ false );
520
+ declRefExpr->setFunctionRefKind (choice.getFunctionRefKind ());
521
+ cs.setType (declRefExpr, refType);
522
+
523
+ Expr *refExpr;
524
+ if (isMemberOperator) {
525
+ // If the operator is a type member, add the implicit
526
+ // (Self) -> ... call.
527
+ Expr *base =
528
+ TypeExpr::createImplicitHack (loc.getBaseNameLoc (), baseTy,
529
+ ctx);
530
+ cs.setType (base, MetatypeType::get (baseTy));
531
+
532
+ refExpr = new (ctx) DotSyntaxCallExpr (declRefExpr,
533
+ SourceLoc (), base);
534
+ auto refType = fullType->castTo <FunctionType>()->getResult ();
535
+ cs.setType (refExpr, refType);
536
+ } else {
537
+ refExpr = declRefExpr;
538
+ }
539
+
540
+ return forceUnwrapIfExpected (refExpr, choice, locator);
531
541
}
532
-
533
- return forceUnwrapIfExpected (refExpr, choice, locator);
534
542
}
535
543
}
536
544
}
537
545
}
538
546
539
- // Build a reference to the protocol requirement .
547
+ // Build a reference to the member .
540
548
Expr *base =
541
549
TypeExpr::createImplicitHack (loc.getBaseNameLoc (), baseTy, ctx);
542
550
cs.cacheExprTypes (base);
0 commit comments