@@ -500,49 +500,47 @@ namespace {
500500 return false ;
501501 }
502502
503- // / Determine whether the given parameter and argument type should be
503+ // / Determine whether the given parameter type and argument should be
504504 // / "favored" because they match exactly.
505505 bool isFavoredParamAndArg (ConstraintSystem &CS,
506506 Type paramTy,
507+ Expr *arg,
507508 Type argTy,
508- Type otherArgTy) {
509- if (argTy->getAs <LValueType>())
510- argTy = argTy->getLValueOrInOutObjectType ();
511-
512- if (!otherArgTy.isNull () &&
513- otherArgTy->getAs <LValueType>())
514- otherArgTy = otherArgTy->getLValueOrInOutObjectType ();
515-
509+ Expr *otherArg = nullptr ,
510+ Type otherArgTy = Type()) {
511+ // Determine the argument type.
512+ argTy = argTy->getLValueOrInOutObjectType ();
513+
516514 // Do the types match exactly?
517515 if (paramTy->isEqual (argTy))
518516 return true ;
519-
520- // If the argument is a type variable created for a literal that has a
521- // default type, this is a favored param/arg pair if the parameter is of
522- // that default type.
523- // Is the argument a type variable...
524- if (auto argTypeVar = argTy->getAs <TypeVariableType>()) {
525- if (auto proto = argTypeVar->getImpl ().literalConformanceProto ) {
526- // If it's a struct type associated with the literal conformance,
527- // test against it directly. This helps to avoid 'widening' the
528- // favored type to the default type for the literal.
529- if (!otherArgTy.isNull () &&
530- otherArgTy->getAs <StructType>()) {
531-
532- if (CS.TC .conformsToProtocol (otherArgTy,
533- proto,
534- CS.DC ,
535- ConformanceCheckFlags::InExpression)) {
536- return otherArgTy->isEqual (paramTy);
537- }
538- } else if (auto defaultTy = CS.TC .getDefaultType (proto, CS.DC )) {
539- if (paramTy->isEqual (defaultTy)) {
540- return true ;
541- }
542- }
543- }
517+
518+ // If the argument is a literal, this is a favored param/arg pair if
519+ // the parameter is of that default type.
520+ auto &tc = CS.getTypeChecker ();
521+ auto literalProto = tc.getLiteralProtocol (arg->getSemanticsProvidingExpr ());
522+ if (!literalProto) return false ;
523+
524+ // Dig out the second argument type.
525+ if (otherArgTy)
526+ otherArgTy = otherArgTy->getLValueOrInOutObjectType ();
527+
528+ // If there is another, concrete argument, check whether it's type
529+ // conforms to the literal protocol and test against it directly.
530+ // This helps to avoid 'widening' the favored type to the default type for
531+ // the literal.
532+ if (otherArgTy && otherArgTy->getAnyNominal ()) {
533+ return otherArgTy->isEqual (paramTy) &&
534+ tc.conformsToProtocol (otherArgTy, literalProto, CS.DC ,
535+ ConformanceCheckFlags::InExpression);
544536 }
545-
537+
538+ // If there is a default type for the literal protocol, check whether
539+ // it is the same as the parameter type.
540+ // Check whether there is a default type to compare against.
541+ if (Type defaultType = tc.getDefaultType (literalProto, CS.DC ))
542+ return paramTy->isEqual (defaultType);
543+
546544 return false ;
547545 }
548546
@@ -750,9 +748,6 @@ namespace {
750748 // / for the operand and contextual type.
751749 void favorMatchingUnaryOperators (ApplyExpr *expr,
752750 ConstraintSystem &CS) {
753- // Find the argument type.
754- auto argTy = getInnerParenType (expr->getArg ()->getType ());
755-
756751 // Determine whether the given declaration is favored.
757752 auto isFavoredDecl = [&](ValueDecl *value) -> bool {
758753 auto valueTy = value->getType ();
@@ -770,7 +765,8 @@ namespace {
770765 auto resultTy = fnTy->getResult ();
771766 auto contextualTy = CS.getContextualType (expr);
772767
773- return isFavoredParamAndArg (CS, paramTy, argTy, Type ()) &&
768+ return isFavoredParamAndArg (CS, paramTy, expr->getArg (),
769+ expr->getArg ()->getType ()) &&
774770 (!contextualTy || contextualTy->isEqual (resultTy));
775771 };
776772
@@ -889,8 +885,10 @@ namespace {
889885 if (!fnTy)
890886 return false ;
891887
892- auto firstFavoredTy = CS.getFavoredType (argTupleExpr->getElement (0 ));
893- auto secondFavoredTy = CS.getFavoredType (argTupleExpr->getElement (1 ));
888+ Expr *firstArg = argTupleExpr->getElement (0 );
889+ auto firstFavoredTy = CS.getFavoredType (firstArg);
890+ Expr *secondArg = argTupleExpr->getElement (1 );
891+ auto secondFavoredTy = CS.getFavoredType (secondArg);
894892
895893 auto favoredExprTy = CS.getFavoredType (expr);
896894
@@ -934,8 +932,10 @@ namespace {
934932 auto contextualTy = CS.getContextualType (expr);
935933
936934 return
937- (isFavoredParamAndArg (CS, firstParamTy, firstArgTy, secondArgTy) ||
938- isFavoredParamAndArg (CS, secondParamTy, secondArgTy, firstArgTy)) &&
935+ (isFavoredParamAndArg (CS, firstParamTy, firstArg, firstArgTy,
936+ secondArg, secondArgTy) ||
937+ isFavoredParamAndArg (CS, secondParamTy, secondArg, secondArgTy,
938+ firstArg, firstArgTy)) &&
939939 firstParamTy->isEqual (secondParamTy) &&
940940 (!contextualTy || contextualTy->isEqual (resultTy));
941941 };
@@ -1091,7 +1091,7 @@ namespace {
10911091 auto keyTy = dictTy->first ;
10921092 auto valueTy = dictTy->second ;
10931093
1094- if (isFavoredParamAndArg (CS, keyTy, index->getType (), Type ())) {
1094+ if (isFavoredParamAndArg (CS, keyTy, index, index ->getType ())) {
10951095 outputTy = OptionalType::get (valueTy);
10961096
10971097 if (isLValueBase)
@@ -1172,10 +1172,7 @@ namespace {
11721172
11731173 auto tv = CS.createTypeVariable (CS.getConstraintLocator (expr),
11741174 TVO_PrefersSubtypeBinding);
1175-
1176- tv->getImpl ().literalConformanceProto = protocol;
1177-
1178- CS.addConstraint (ConstraintKind::ConformsTo, tv,
1175+ CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
11791176 protocol->getDeclaredType (),
11801177 CS.getConstraintLocator (expr));
11811178 return tv;
@@ -1198,8 +1195,7 @@ namespace {
11981195 // ExpressibleByStringInterpolation protocol.
11991196 auto locator = CS.getConstraintLocator (expr);
12001197 auto tv = CS.createTypeVariable (locator, TVO_PrefersSubtypeBinding);
1201- tv->getImpl ().literalConformanceProto = interpolationProto;
1202- CS.addConstraint (ConstraintKind::ConformsTo, tv,
1198+ CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
12031199 interpolationProto->getDeclaredType (),
12041200 locator);
12051201
@@ -1272,9 +1268,7 @@ namespace {
12721268 auto tv = CS.createTypeVariable (CS.getConstraintLocator (expr),
12731269 TVO_PrefersSubtypeBinding);
12741270
1275- tv->getImpl ().literalConformanceProto = protocol;
1276-
1277- CS.addConstraint (ConstraintKind::ConformsTo, tv,
1271+ CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
12781272 protocol->getDeclaredType (),
12791273 CS.getConstraintLocator (expr));
12801274
@@ -1691,7 +1685,7 @@ namespace {
16911685 contextualArrayElementType =
16921686 CS.getBaseTypeForArrayType (contextualType.getPointer ());
16931687
1694- CS.addConstraint (ConstraintKind::ConformsTo , contextualType,
1688+ CS.addConstraint (ConstraintKind::LiteralConformsTo , contextualType,
16951689 arrayProto->getDeclaredType (),
16961690 locator);
16971691
@@ -1711,7 +1705,7 @@ namespace {
17111705 auto arrayTy = CS.createTypeVariable (locator, TVO_PrefersSubtypeBinding);
17121706
17131707 // The array must be an array literal type.
1714- CS.addConstraint (ConstraintKind::ConformsTo , arrayTy,
1708+ CS.addConstraint (ConstraintKind::LiteralConformsTo , arrayTy,
17151709 arrayProto->getDeclaredType (),
17161710 locator);
17171711
@@ -1777,8 +1771,8 @@ namespace {
17771771 auto dictionaryTy = CS.createTypeVariable (locator,
17781772 TVO_PrefersSubtypeBinding);
17791773
1780- // The array must be a dictionary literal type.
1781- CS.addConstraint (ConstraintKind::ConformsTo , dictionaryTy,
1774+ // The dictionary must be a dictionary literal type.
1775+ CS.addConstraint (ConstraintKind::LiteralConformsTo , dictionaryTy,
17821776 dictionaryProto->getDeclaredType (),
17831777 locator);
17841778
0 commit comments