@@ -500,47 +500,49 @@ namespace {
500
500
return false ;
501
501
}
502
502
503
- // / Determine whether the given parameter type and argument should be
503
+ // / Determine whether the given parameter and argument type should be
504
504
// / "favored" because they match exactly.
505
505
bool isFavoredParamAndArg (ConstraintSystem &CS,
506
506
Type paramTy,
507
- Expr *arg,
508
507
Type argTy,
509
- Expr *otherArg = nullptr ,
510
- Type otherArgTy = Type()) {
511
- // Determine the argument type.
512
- argTy = argTy->getLValueOrInOutObjectType ();
513
-
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
+
514
516
// Do the types match exactly?
515
517
if (paramTy->isEqual (argTy))
516
518
return true ;
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);
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
+ }
536
544
}
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
-
545
+
544
546
return false ;
545
547
}
546
548
@@ -740,6 +742,9 @@ namespace {
740
742
// / for the operand and contextual type.
741
743
void favorMatchingUnaryOperators (ApplyExpr *expr,
742
744
ConstraintSystem &CS) {
745
+ // Find the argument type.
746
+ auto argTy = expr->getArg ()->getType ()->getWithoutParens ();
747
+
743
748
// Determine whether the given declaration is favored.
744
749
auto isFavoredDecl = [&](ValueDecl *value) -> bool {
745
750
auto valueTy = value->getType ();
@@ -757,8 +762,7 @@ namespace {
757
762
auto resultTy = fnTy->getResult ();
758
763
auto contextualTy = CS.getContextualType (expr);
759
764
760
- return isFavoredParamAndArg (CS, paramTy, expr->getArg (),
761
- expr->getArg ()->getType ()) &&
765
+ return isFavoredParamAndArg (CS, paramTy, argTy, Type ()) &&
762
766
(!contextualTy || contextualTy->isEqual (resultTy));
763
767
};
764
768
@@ -877,10 +881,8 @@ namespace {
877
881
if (!fnTy)
878
882
return false ;
879
883
880
- Expr *firstArg = argTupleExpr->getElement (0 );
881
- auto firstFavoredTy = CS.getFavoredType (firstArg);
882
- Expr *secondArg = argTupleExpr->getElement (1 );
883
- auto secondFavoredTy = CS.getFavoredType (secondArg);
884
+ auto firstFavoredTy = CS.getFavoredType (argTupleExpr->getElement (0 ));
885
+ auto secondFavoredTy = CS.getFavoredType (argTupleExpr->getElement (1 ));
884
886
885
887
auto favoredExprTy = CS.getFavoredType (expr);
886
888
@@ -924,10 +926,8 @@ namespace {
924
926
auto contextualTy = CS.getContextualType (expr);
925
927
926
928
return
927
- (isFavoredParamAndArg (CS, firstParamTy, firstArg, firstArgTy,
928
- secondArg, secondArgTy) ||
929
- isFavoredParamAndArg (CS, secondParamTy, secondArg, secondArgTy,
930
- firstArg, firstArgTy)) &&
929
+ (isFavoredParamAndArg (CS, firstParamTy, firstArgTy, secondArgTy) ||
930
+ isFavoredParamAndArg (CS, secondParamTy, secondArgTy, firstArgTy)) &&
931
931
firstParamTy->isEqual (secondParamTy) &&
932
932
(!contextualTy || contextualTy->isEqual (resultTy));
933
933
};
@@ -1083,7 +1083,7 @@ namespace {
1083
1083
auto keyTy = dictTy->first ;
1084
1084
auto valueTy = dictTy->second ;
1085
1085
1086
- if (isFavoredParamAndArg (CS, keyTy, index, index ->getType ())) {
1086
+ if (isFavoredParamAndArg (CS, keyTy, index->getType (), Type ())) {
1087
1087
outputTy = OptionalType::get (valueTy);
1088
1088
1089
1089
if (isLValueBase)
@@ -1164,7 +1164,10 @@ namespace {
1164
1164
1165
1165
auto tv = CS.createTypeVariable (CS.getConstraintLocator (expr),
1166
1166
TVO_PrefersSubtypeBinding);
1167
- CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
1167
+
1168
+ tv->getImpl ().literalConformanceProto = protocol;
1169
+
1170
+ CS.addConstraint (ConstraintKind::ConformsTo, tv,
1168
1171
protocol->getDeclaredType (),
1169
1172
CS.getConstraintLocator (expr));
1170
1173
return tv;
@@ -1187,7 +1190,8 @@ namespace {
1187
1190
// ExpressibleByStringInterpolation protocol.
1188
1191
auto locator = CS.getConstraintLocator (expr);
1189
1192
auto tv = CS.createTypeVariable (locator, TVO_PrefersSubtypeBinding);
1190
- CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
1193
+ tv->getImpl ().literalConformanceProto = interpolationProto;
1194
+ CS.addConstraint (ConstraintKind::ConformsTo, tv,
1191
1195
interpolationProto->getDeclaredType (),
1192
1196
locator);
1193
1197
@@ -1260,7 +1264,9 @@ namespace {
1260
1264
auto tv = CS.createTypeVariable (CS.getConstraintLocator (expr),
1261
1265
TVO_PrefersSubtypeBinding);
1262
1266
1263
- CS.addConstraint (ConstraintKind::LiteralConformsTo, tv,
1267
+ tv->getImpl ().literalConformanceProto = protocol;
1268
+
1269
+ CS.addConstraint (ConstraintKind::ConformsTo, tv,
1264
1270
protocol->getDeclaredType (),
1265
1271
CS.getConstraintLocator (expr));
1266
1272
@@ -1677,7 +1683,7 @@ namespace {
1677
1683
contextualArrayElementType =
1678
1684
CS.getBaseTypeForArrayType (contextualType.getPointer ());
1679
1685
1680
- CS.addConstraint (ConstraintKind::LiteralConformsTo , contextualType,
1686
+ CS.addConstraint (ConstraintKind::ConformsTo , contextualType,
1681
1687
arrayProto->getDeclaredType (),
1682
1688
locator);
1683
1689
@@ -1697,7 +1703,7 @@ namespace {
1697
1703
auto arrayTy = CS.createTypeVariable (locator, TVO_PrefersSubtypeBinding);
1698
1704
1699
1705
// The array must be an array literal type.
1700
- CS.addConstraint (ConstraintKind::LiteralConformsTo , arrayTy,
1706
+ CS.addConstraint (ConstraintKind::ConformsTo , arrayTy,
1701
1707
arrayProto->getDeclaredType (),
1702
1708
locator);
1703
1709
@@ -1763,8 +1769,8 @@ namespace {
1763
1769
auto dictionaryTy = CS.createTypeVariable (locator,
1764
1770
TVO_PrefersSubtypeBinding);
1765
1771
1766
- // The dictionary must be a dictionary literal type.
1767
- CS.addConstraint (ConstraintKind::LiteralConformsTo , dictionaryTy,
1772
+ // The array must be a dictionary literal type.
1773
+ CS.addConstraint (ConstraintKind::ConformsTo , dictionaryTy,
1768
1774
dictionaryProto->getDeclaredType (),
1769
1775
locator);
1770
1776
0 commit comments