Skip to content

Commit fc055f9

Browse files
committed
---
yaml --- r: 347011 b: refs/heads/master c: bdabe9b h: refs/heads/master i: 347009: 544dca1 347007: 0c85520
1 parent deee2a0 commit fc055f9

File tree

5 files changed

+423
-41
lines changed

5 files changed

+423
-41
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 1444fb62219fe8e6ca571757e50c6f51619b52c0
2+
refs/heads/master: bdabe9b2208b887c0d7c75ecabbf3d07ea1a3ecc
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/lib/Sema/CSGen.cpp

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,6 @@ namespace {
540540
/// "favored" because they match exactly.
541541
bool isFavoredParamAndArg(ConstraintSystem &CS,
542542
Type paramTy,
543-
Expr *arg,
544543
Type argTy,
545544
Type otherArgTy = Type()) {
546545
// Determine the argument type.
@@ -550,32 +549,45 @@ namespace {
550549
if (paramTy->isEqual(argTy))
551550
return true;
552551

553-
// If the argument is a literal, this is a favored param/arg pair if
554-
// the parameter is of that default type.
555-
auto &tc = CS.getTypeChecker();
556-
auto literalProto = tc.getLiteralProtocol(arg->getSemanticsProvidingExpr());
557-
if (!literalProto) return false;
552+
llvm::SmallSetVector<ProtocolDecl *, 2> literalProtos;
553+
if (auto argTypeVar = argTy->getAs<TypeVariableType>()) {
554+
llvm::SetVector<Constraint *> constraints;
555+
CS.getConstraintGraph().gatherConstraints(
556+
argTypeVar, constraints,
557+
ConstraintGraph::GatheringKind::EquivalenceClass,
558+
[](Constraint *constraint) {
559+
return constraint->getKind() == ConstraintKind::LiteralConformsTo;
560+
});
561+
562+
for (auto constraint : constraints) {
563+
literalProtos.insert(constraint->getProtocol());
564+
}
565+
}
558566

559567
// Dig out the second argument type.
560568
if (otherArgTy)
561569
otherArgTy = otherArgTy->getWithoutSpecifierType();
562570

563-
// If there is another, concrete argument, check whether it's type
564-
// conforms to the literal protocol and test against it directly.
565-
// This helps to avoid 'widening' the favored type to the default type for
566-
// the literal.
567-
if (otherArgTy && otherArgTy->getAnyNominal()) {
568-
return otherArgTy->isEqual(paramTy) &&
569-
tc.conformsToProtocol(otherArgTy, literalProto, CS.DC,
570-
ConformanceCheckFlags::InExpression);
571+
auto &tc = CS.getTypeChecker();
572+
for (auto literalProto : literalProtos) {
573+
// If there is another, concrete argument, check whether it's type
574+
// conforms to the literal protocol and test against it directly.
575+
// This helps to avoid 'widening' the favored type to the default type for
576+
// the literal.
577+
if (otherArgTy && otherArgTy->getAnyNominal()) {
578+
if (otherArgTy->isEqual(paramTy) &&
579+
tc.conformsToProtocol(otherArgTy, literalProto, CS.DC,
580+
ConformanceCheckFlags::InExpression))
581+
return true;
582+
} else if (Type defaultType = tc.getDefaultType(literalProto, CS.DC)) {
583+
// If there is a default type for the literal protocol, check whether
584+
// it is the same as the parameter type.
585+
// Check whether there is a default type to compare against.
586+
if (paramTy->isEqual(defaultType))
587+
return true;
588+
}
571589
}
572590

573-
// If there is a default type for the literal protocol, check whether
574-
// it is the same as the parameter type.
575-
// Check whether there is a default type to compare against.
576-
if (Type defaultType = tc.getDefaultType(literalProto, CS.DC))
577-
return paramTy->isEqual(defaultType);
578-
579591
return false;
580592
}
581593

@@ -744,7 +756,7 @@ namespace {
744756
auto contextualTy = CS.getContextualType(expr);
745757

746758
return isFavoredParamAndArg(
747-
CS, paramTy, expr->getArg(),
759+
CS, paramTy,
748760
CS.getType(expr->getArg())->getWithoutParens()) &&
749761
(!contextualTy || contextualTy->isEqual(resultTy));
750762
};
@@ -899,14 +911,6 @@ namespace {
899911
CS.setFavoredType(argTupleExpr->getElement(1), favoredExprTy);
900912
secondFavoredTy = favoredExprTy;
901913
}
902-
903-
if (firstFavoredTy && firstArgTy->is<TypeVariableType>()) {
904-
firstArgTy = firstFavoredTy;
905-
}
906-
907-
if (secondFavoredTy && secondArgTy->is<TypeVariableType>()) {
908-
secondArgTy = secondFavoredTy;
909-
}
910914
}
911915

912916
// Figure out the parameter type.
@@ -924,9 +928,8 @@ namespace {
924928
auto resultTy = fnTy->getResult();
925929
auto contextualTy = CS.getContextualType(expr);
926930

927-
return (isFavoredParamAndArg(CS, firstParamTy, firstArg, firstArgTy,
928-
secondArgTy) ||
929-
isFavoredParamAndArg(CS, secondParamTy, secondArg, secondArgTy,
931+
return (isFavoredParamAndArg(CS, firstParamTy, firstArgTy, secondArgTy) ||
932+
isFavoredParamAndArg(CS, secondParamTy, secondArgTy,
930933
firstArgTy)) &&
931934
firstParamTy->isEqual(secondParamTy) &&
932935
!isPotentialForcingOpportunity(firstArgTy, secondArgTy) &&
@@ -1109,7 +1112,7 @@ namespace {
11091112
auto keyTy = dictTy->first;
11101113
auto valueTy = dictTy->second;
11111114

1112-
if (isFavoredParamAndArg(CS, keyTy, index, CS.getType(index))) {
1115+
if (isFavoredParamAndArg(CS, keyTy, CS.getType(index))) {
11131116
outputTy = OptionalType::get(valueTy);
11141117

11151118
if (isLValueBase)
@@ -2523,10 +2526,8 @@ namespace {
25232526
return resultOfTypeOperation(typeOperation, expr->getArg());
25242527
}
25252528

2526-
if (isa<DeclRefExpr>(fnExpr)) {
2527-
if (auto fnType = CS.getType(fnExpr)->getAs<AnyFunctionType>()) {
2528-
outputTy = fnType->getResult();
2529-
}
2529+
if (auto fnType = CS.getType(fnExpr)->getAs<AnyFunctionType>()) {
2530+
outputTy = fnType->getResult();
25302531
} else if (auto OSR = dyn_cast<OverloadedDeclRefExpr>(fnExpr)) {
25312532
// Determine if the overloads are all functions that share a common
25322533
// return type.

0 commit comments

Comments
 (0)