@@ -500,49 +500,47 @@ namespace {
500
500
return false ;
501
501
}
502
502
503
- // / Determine whether the given parameter and argument type should be
503
+ // / Determine whether the given parameter type and argument should be
504
504
// / "favored" because they match exactly.
505
505
bool isFavoredParamAndArg (ConstraintSystem &CS,
506
506
Type paramTy,
507
+ Expr *arg,
507
508
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
+
516
514
// Do the types match exactly?
517
515
if (paramTy->isEqual (argTy))
518
516
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);
544
536
}
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
+
546
544
return false ;
547
545
}
548
546
@@ -750,9 +748,6 @@ namespace {
750
748
// / for the operand and contextual type.
751
749
void favorMatchingUnaryOperators (ApplyExpr *expr,
752
750
ConstraintSystem &CS) {
753
- // Find the argument type.
754
- auto argTy = getInnerParenType (expr->getArg ()->getType ());
755
-
756
751
// Determine whether the given declaration is favored.
757
752
auto isFavoredDecl = [&](ValueDecl *value) -> bool {
758
753
auto valueTy = value->getType ();
@@ -770,7 +765,8 @@ namespace {
770
765
auto resultTy = fnTy->getResult ();
771
766
auto contextualTy = CS.getContextualType (expr);
772
767
773
- return isFavoredParamAndArg (CS, paramTy, argTy, Type ()) &&
768
+ return isFavoredParamAndArg (CS, paramTy, expr->getArg (),
769
+ expr->getArg ()->getType ()) &&
774
770
(!contextualTy || contextualTy->isEqual (resultTy));
775
771
};
776
772
@@ -889,8 +885,10 @@ namespace {
889
885
if (!fnTy)
890
886
return false ;
891
887
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);
894
892
895
893
auto favoredExprTy = CS.getFavoredType (expr);
896
894
@@ -934,8 +932,10 @@ namespace {
934
932
auto contextualTy = CS.getContextualType (expr);
935
933
936
934
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)) &&
939
939
firstParamTy->isEqual (secondParamTy) &&
940
940
(!contextualTy || contextualTy->isEqual (resultTy));
941
941
};
@@ -1091,7 +1091,7 @@ namespace {
1091
1091
auto keyTy = dictTy->first ;
1092
1092
auto valueTy = dictTy->second ;
1093
1093
1094
- if (isFavoredParamAndArg (CS, keyTy, index->getType (), Type ())) {
1094
+ if (isFavoredParamAndArg (CS, keyTy, index, index ->getType ())) {
1095
1095
outputTy = OptionalType::get (valueTy);
1096
1096
1097
1097
if (isLValueBase)
@@ -1172,10 +1172,7 @@ namespace {
1172
1172
1173
1173
auto tv = CS.createTypeVariable (CS.getConstraintLocator (expr),
1174
1174
TVO_PrefersSubtypeBinding);
1175
-
1176
- tv->getImpl ().literalConformanceProto = protocol;
1177
-
1178
- CS.addConstraint (ConstraintKind::ConformsTo, tv,
1175
+ CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
1179
1176
protocol->getDeclaredType (),
1180
1177
CS.getConstraintLocator (expr));
1181
1178
return tv;
@@ -1198,8 +1195,7 @@ namespace {
1198
1195
// ExpressibleByStringInterpolation protocol.
1199
1196
auto locator = CS.getConstraintLocator (expr);
1200
1197
auto tv = CS.createTypeVariable (locator, TVO_PrefersSubtypeBinding);
1201
- tv->getImpl ().literalConformanceProto = interpolationProto;
1202
- CS.addConstraint (ConstraintKind::ConformsTo, tv,
1198
+ CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
1203
1199
interpolationProto->getDeclaredType (),
1204
1200
locator);
1205
1201
@@ -1272,9 +1268,7 @@ namespace {
1272
1268
auto tv = CS.createTypeVariable (CS.getConstraintLocator (expr),
1273
1269
TVO_PrefersSubtypeBinding);
1274
1270
1275
- tv->getImpl ().literalConformanceProto = protocol;
1276
-
1277
- CS.addConstraint (ConstraintKind::ConformsTo, tv,
1271
+ CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
1278
1272
protocol->getDeclaredType (),
1279
1273
CS.getConstraintLocator (expr));
1280
1274
@@ -1691,7 +1685,7 @@ namespace {
1691
1685
contextualArrayElementType =
1692
1686
CS.getBaseTypeForArrayType (contextualType.getPointer ());
1693
1687
1694
- CS.addConstraint (ConstraintKind::ConformsTo , contextualType,
1688
+ CS.addConstraint (ConstraintKind::LiteralConformsTo , contextualType,
1695
1689
arrayProto->getDeclaredType (),
1696
1690
locator);
1697
1691
@@ -1711,7 +1705,7 @@ namespace {
1711
1705
auto arrayTy = CS.createTypeVariable (locator, TVO_PrefersSubtypeBinding);
1712
1706
1713
1707
// The array must be an array literal type.
1714
- CS.addConstraint (ConstraintKind::ConformsTo , arrayTy,
1708
+ CS.addConstraint (ConstraintKind::LiteralConformsTo , arrayTy,
1715
1709
arrayProto->getDeclaredType (),
1716
1710
locator);
1717
1711
@@ -1777,8 +1771,8 @@ namespace {
1777
1771
auto dictionaryTy = CS.createTypeVariable (locator,
1778
1772
TVO_PrefersSubtypeBinding);
1779
1773
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,
1782
1776
dictionaryProto->getDeclaredType (),
1783
1777
locator);
1784
1778
0 commit comments