@@ -1620,6 +1620,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
16201620 }
16211621 }
16221622
1623+ auto hasLabelMismatch = false ;
16231624 for (unsigned i = 0 , n = tuple1->getNumElements (); i != n; ++i) {
16241625 const auto &elt1 = tuple1->getElement (i);
16251626 const auto &elt2 = tuple2->getElement (i);
@@ -1641,6 +1642,11 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
16411642 // used at some other position.
16421643 if (elt2.hasName () && tuple1->getNamedElementId (elt2.getName ()) != -1 )
16431644 return getTypeMatchFailure (locator);
1645+
1646+ // If both elements have names and they mismatch, make a note of it
1647+ // so we can emit a warning.
1648+ if (elt1.hasName () && elt2.hasName ())
1649+ hasLabelMismatch = true ;
16441650 }
16451651 }
16461652
@@ -1656,6 +1662,13 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
16561662 return result;
16571663 }
16581664
1665+ if (hasLabelMismatch) {
1666+ // If we had a label mismatch, emit a warning. This is something we
1667+ // shouldn't permit, as it's more permissive than what a conversion would
1668+ // allow. Ideally we'd turn this into an error in Swift 6 mode.
1669+ recordFix (AllowTupleLabelMismatch::create (
1670+ *this , tuple1, tuple2, getConstraintLocator (locator)));
1671+ }
16591672 return getTypeMatchSuccess ();
16601673 }
16611674
@@ -1700,6 +1713,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
17001713 case ConstraintKind::UnresolvedMemberChainBase:
17011714 case ConstraintKind::PropertyWrapper:
17021715 case ConstraintKind::ClosureBodyElement:
1716+ case ConstraintKind::BindTupleOfFunctionParams:
17031717 llvm_unreachable (" Not a conversion" );
17041718 }
17051719
@@ -1839,6 +1853,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
18391853 case ConstraintKind::UnresolvedMemberChainBase:
18401854 case ConstraintKind::PropertyWrapper:
18411855 case ConstraintKind::ClosureBodyElement:
1856+ case ConstraintKind::BindTupleOfFunctionParams:
18421857 return true ;
18431858 }
18441859
@@ -2250,6 +2265,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
22502265 case ConstraintKind::UnresolvedMemberChainBase:
22512266 case ConstraintKind::PropertyWrapper:
22522267 case ConstraintKind::ClosureBodyElement:
2268+ case ConstraintKind::BindTupleOfFunctionParams:
22532269 llvm_unreachable (" Not a relational constraint" );
22542270 }
22552271
@@ -5337,6 +5353,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
53375353 case ConstraintKind::UnresolvedMemberChainBase:
53385354 case ConstraintKind::PropertyWrapper:
53395355 case ConstraintKind::ClosureBodyElement:
5356+ case ConstraintKind::BindTupleOfFunctionParams:
53405357 llvm_unreachable (" Not a relational constraint" );
53415358 }
53425359 }
@@ -6310,6 +6327,19 @@ ConstraintSystem::simplifyConstructionConstraint(
63106327 fnLocator,
63116328 ConstraintLocator::ConstructorMember));
63126329
6330+ // HACK: Bind the function's parameter list as a tuple to a type variable.
6331+ // This only exists to preserve compatibility with rdar://85263844, as it can
6332+ // affect the prioritization of bindings, which can affect behavior for tuple
6333+ // matching as tuple subtyping is currently a *weaker* constraint than tuple
6334+ // conversion.
6335+ if (!getASTContext ().isSwiftVersionAtLeast (6 )) {
6336+ auto paramTypeVar = createTypeVariable (
6337+ getConstraintLocator (locator, ConstraintLocator::ApplyArgument),
6338+ TVO_CanBindToLValue | TVO_CanBindToInOut | TVO_CanBindToNoEscape);
6339+ addConstraint (ConstraintKind::BindTupleOfFunctionParams, memberType,
6340+ paramTypeVar, locator);
6341+ }
6342+
63136343 addConstraint (ConstraintKind::ApplicableFunction, fnType, memberType,
63146344 fnLocator);
63156345
@@ -7133,6 +7163,59 @@ ConstraintSystem::simplifyOptionalObjectConstraint(
71337163 return SolutionKind::Solved;
71347164}
71357165
7166+ ConstraintSystem::SolutionKind
7167+ ConstraintSystem::simplifyBindTupleOfFunctionParamsConstraint (
7168+ Type first, Type second, TypeMatchOptions flags,
7169+ ConstraintLocatorBuilder locator) {
7170+ auto simplified = simplifyType (first);
7171+ auto simplifiedCopy = simplified;
7172+
7173+ unsigned unwrapCount = 0 ;
7174+ if (shouldAttemptFixes ()) {
7175+ while (auto objectTy = simplified->getOptionalObjectType ()) {
7176+ simplified = objectTy;
7177+
7178+ // Track how many times we do this so that we can record a fix for each.
7179+ ++unwrapCount;
7180+ }
7181+
7182+ if (simplified->isPlaceholder ()) {
7183+ if (auto *typeVar = second->getAs <TypeVariableType>())
7184+ recordPotentialHole (typeVar);
7185+ return SolutionKind::Solved;
7186+ }
7187+ }
7188+
7189+ if (simplified->isTypeVariableOrMember ()) {
7190+ if (!flags.contains (TMF_GenerateConstraints))
7191+ return SolutionKind::Unsolved;
7192+
7193+ addUnsolvedConstraint (
7194+ Constraint::create (*this , ConstraintKind::BindTupleOfFunctionParams,
7195+ simplified, second, getConstraintLocator (locator)));
7196+ return SolutionKind::Solved;
7197+ }
7198+
7199+ auto *funcTy = simplified->getAs <FunctionType>();
7200+ if (!funcTy)
7201+ return SolutionKind::Error;
7202+
7203+ auto tupleTy =
7204+ AnyFunctionType::composeTuple (getASTContext (), funcTy->getParams (),
7205+ /* wantParamFlags*/ false );
7206+
7207+ addConstraint (ConstraintKind::Bind, tupleTy, second,
7208+ locator.withPathElement (ConstraintLocator::FunctionArgument));
7209+
7210+ if (unwrapCount > 0 ) {
7211+ auto *fix = ForceOptional::create (*this , simplifiedCopy, second,
7212+ getConstraintLocator (locator));
7213+ if (recordFix (fix, /* impact=*/ unwrapCount))
7214+ return SolutionKind::Error;
7215+ }
7216+ return SolutionKind::Solved;
7217+ }
7218+
71367219static bool isForKeyPathSubscript (ConstraintSystem &cs,
71377220 ConstraintLocator *locator) {
71387221 if (!locator || !locator->getAnchor ())
@@ -11963,6 +12046,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1196312046 case FixKind::DropThrowsAttribute:
1196412047 case FixKind::DropAsyncAttribute:
1196512048 case FixKind::AllowSwiftToCPointerConversion:
12049+ case FixKind::AllowTupleLabelMismatch:
1196612050 llvm_unreachable (" handled elsewhere" );
1196712051 }
1196812052
@@ -12048,6 +12132,10 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1204812132 return simplifyUnresolvedMemberChainBaseConstraint (first, second, subflags,
1204912133 locator);
1205012134
12135+ case ConstraintKind::BindTupleOfFunctionParams:
12136+ return simplifyBindTupleOfFunctionParamsConstraint (first, second, subflags,
12137+ locator);
12138+
1205112139 case ConstraintKind::ValueMember:
1205212140 case ConstraintKind::UnresolvedValueMember:
1205312141 case ConstraintKind::ValueWitness:
@@ -12591,6 +12679,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1259112679 constraint.getClosureElement (), constraint.getElementContext (),
1259212680 constraint.isDiscardedElement (),
1259312681 /* flags=*/ None, constraint.getLocator ());
12682+
12683+ case ConstraintKind::BindTupleOfFunctionParams:
12684+ return simplifyBindTupleOfFunctionParamsConstraint (
12685+ constraint.getFirstType (), constraint.getSecondType (), /* flags*/ None,
12686+ constraint.getLocator ());
1259412687 }
1259512688
1259612689 llvm_unreachable (" Unhandled ConstraintKind in switch." );
0 commit comments