Skip to content

Commit cc28774

Browse files
authored
Merge pull request #6973 from colinhowell/SR-3668
[CSGen] Fix for exponential dictionary literal behavior in SR-3668
2 parents 902880a + fb23512 commit cc28774

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

lib/Sema/CSGen.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,42 @@ namespace {
17841784
C.getIdentifier("Value")).front());
17851785

17861786
auto locator = CS.getConstraintLocator(expr);
1787+
auto contextualType = CS.getContextualType(expr);
1788+
Type contextualDictionaryType = nullptr;
1789+
Type contextualDictionaryKeyType = nullptr;
1790+
Type contextualDictionaryValueType = nullptr;
1791+
1792+
// If a contextual type exists for this expression, apply it directly.
1793+
Optional<std::pair<Type, Type>> dictionaryKeyValue;
1794+
if (contextualType &&
1795+
(dictionaryKeyValue = ConstraintSystem::isDictionaryType(contextualType))) {
1796+
// Is the contextual type a dictionary type?
1797+
contextualDictionaryType = contextualType;
1798+
std::tie(contextualDictionaryKeyType,
1799+
contextualDictionaryValueType) = *dictionaryKeyValue;
1800+
1801+
// Form an explicit tuple type from the contextual type's key and value types.
1802+
TupleTypeElt tupleElts[2] = { TupleTypeElt(contextualDictionaryKeyType),
1803+
TupleTypeElt(contextualDictionaryValueType) };
1804+
Type contextualDictionaryElementType = TupleType::get(tupleElts, C);
1805+
1806+
CS.addConstraint(ConstraintKind::LiteralConformsTo, contextualType,
1807+
dictionaryProto->getDeclaredType(),
1808+
locator);
1809+
1810+
unsigned index = 0;
1811+
for (auto element : expr->getElements()) {
1812+
CS.addConstraint(ConstraintKind::Conversion,
1813+
element->getType(),
1814+
contextualDictionaryElementType,
1815+
CS.getConstraintLocator(expr,
1816+
LocatorPathElt::
1817+
getTupleElement(index++)));
1818+
}
1819+
1820+
return contextualDictionaryType;
1821+
}
1822+
17871823
auto dictionaryTy = CS.createTypeVariable(locator,
17881824
TVO_PrefersSubtypeBinding);
17891825

test/Sema/complex_expressions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,21 @@ let v4 = [1 + 2 + 3, 4] as [UInt32] + [2 * 3] as [UInt32]
9797
let v5 = ([1 + 2 + 3, 4] as [UInt32]) + ([2 * 3] as [UInt32])
9898
let v6 = [1 + 2 + 3, 4] as Set<UInt32>
9999
let v7: [UInt32] = [55 * 8, 0]
100+
101+
// SR-3668
102+
// "Expression was too complex" errors for short dictionary literals
103+
// of simple closure expressions
104+
105+
let sr3668Dict1: Dictionary<Int, (Int, Int) -> Bool> =
106+
[ 0: { $0 == $1 }, 1: { $0 == $1 }, 2: { $0 == $1 }, 3: { $0 == $1 },
107+
4: { $0 == $1 }, 5: { $0 == $1 }, 6: { $0 == $1 }, 7: { $0 == $1 },
108+
8: { $0 == $1 }, 9: { $0 == $1 }, 10: { $0 == $1 }, 11: { $0 == $1 },
109+
12: { $0 == $1 }, 13: { $0 == $1 }, 14: { $0 == $1 }, 15: { $0 == $1 },
110+
16: { $0 == $1 }, 17: { $0 == $1 }, 18: { $0 == $1 }, 19: { $0 == $1 } ]
111+
112+
let sr3668Dict2: [Int: (Int, Int) -> Bool] =
113+
[ 0: { $0 != $1 }, 1: { $0 != $1 }, 2: { $0 != $1 }, 3: { $0 != $1 },
114+
4: { $0 != $1 }, 5: { $0 != $1 }, 6: { $0 != $1 }, 7: { $0 != $1 },
115+
8: { $0 != $1 }, 9: { $0 != $1 }, 10: { $0 != $1 }, 11: { $0 != $1 },
116+
12: { $0 != $1 }, 13: { $0 != $1 }, 14: { $0 != $1 }, 15: { $0 != $1 },
117+
16: { $0 != $1 }, 17: { $0 != $1 }, 18: { $0 != $1 }, 19: { $0 != $1 } ]

0 commit comments

Comments
 (0)