Skip to content

Commit ff950a4

Browse files
committed
Sema: Refactor logic for excluding arrays / optionals out of closure
1 parent 2cefbe0 commit ff950a4

File tree

3 files changed

+46
-42
lines changed

3 files changed

+46
-42
lines changed

lib/Sema/CSFix.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ enum class FixKind : uint8_t {
167167
/// associated with single declaration.
168168
ExplicitlySpecifyGenericArguments,
169169

170-
/// Skip any unhandled constructs that occur within a closure argument that matches up with a
170+
/// Skip any unhandled constructs that occur within a closure argument that
171+
/// matches up with a
171172
/// parameter that has a function builder.
172173
SkipUnhandledConstructInFunctionBuilder,
173174
};

lib/Sema/CSSimplify.cpp

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,23 +1598,24 @@ static ConstraintSystem::TypeMatchResult matchDeepTypeArguments(
15981598
ConstraintSystem &cs, ConstraintSystem::TypeMatchOptions subflags,
15991599
ArrayRef<Type> args1, ArrayRef<Type> args2,
16001600
ConstraintLocatorBuilder locator,
1601-
llvm::function_ref<bool(unsigned)> recordMismatch = [](unsigned) { return false; }) {
1601+
llvm::function_ref<void(unsigned)> recordMismatch = [](unsigned) {}) {
16021602
if (args1.size() != args2.size()) {
16031603
return cs.getTypeMatchFailure(locator);
16041604
}
16051605

1606+
auto allMatch = cs.getTypeMatchSuccess();
16061607
for (unsigned i = 0, n = args1.size(); i != n; ++i) {
16071608
auto result = cs.matchTypes(
16081609
args1[i], args2[i], ConstraintKind::Bind, subflags,
16091610
locator.withPathElement(LocatorPathElt::getGenericArgument(i)));
16101611

16111612
if (result.isFailure()) {
1612-
if (!cs.shouldAttemptFixes() || !recordMismatch(i))
1613-
return result;
1613+
recordMismatch(i);
1614+
allMatch = result;
16141615
}
16151616
}
16161617

1617-
return cs.getTypeMatchSuccess();
1618+
return allMatch;
16181619
}
16191620

16201621
ConstraintSystem::TypeMatchResult
@@ -1670,46 +1671,48 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
16701671
return result;
16711672
}
16721673

1673-
bool forRequirement = false;
1674-
if (auto last = locator.last()) {
1675-
forRequirement =
1676-
last->isTypeParameterRequirement() || last->isConditionalRequirement();
1677-
}
1678-
// Optionals and arrays have a lot of special diagnostics and only one
1679-
// generic argument so if we' re dealing with one, don't produce generic
1680-
// arguments mismatch fixes.
1681-
// TODO(diagnostics): Move Optional and Array diagnostics over to the
1682-
// new framework.
1683-
bool isOptional = bound1->getDecl()->isOptionalDecl();
1684-
bool isArray = isArrayType(bound1).hasValue();
1685-
16861674
auto args1 = bound1->getGenericArgs();
16871675
auto args2 = bound2->getGenericArgs();
16881676

1689-
SmallVector<unsigned, 4> failedArguments;
16901677
// Match up the generic arguments, exactly.
1691-
auto result =
1692-
matchDeepTypeArguments(*this, subflags, args1, args2, locator,
1693-
[&](unsigned position) {
1694-
if (forRequirement || isOptional || isArray)
1695-
return false;
1696-
1697-
failedArguments.push_back(position);
1698-
return true;
1699-
});
1700-
if (!failedArguments.empty()) {
1701-
auto *fix = GenericArgumentsMismatch::create(
1702-
*this, bound1, bound2, failedArguments, getConstraintLocator(locator));
1703-
// Increase the solution's score for each mismtach this fixes.
1704-
for (unsigned i = 0; i < failedArguments.size(); ++i) {
1705-
increaseScore(SK_Fix);
1678+
1679+
if (shouldAttemptFixes()) {
1680+
bool forRequirement = false;
1681+
if (auto last = locator.last()) {
1682+
forRequirement = last->isTypeParameterRequirement() ||
1683+
last->isConditionalRequirement();
17061684
}
17071685

1686+
// Optionals and arrays have a lot of special diagnostics and only one
1687+
// generic argument so if we' re dealing with one, don't produce generic
1688+
// arguments mismatch fixes.
1689+
// TODO(diagnostics): Move Optional and Array diagnostics over to the
1690+
// new framework.
1691+
bool isOptional = bound1->getDecl()->isOptionalDecl();
1692+
bool isArray = isArrayType(bound1).hasValue();
1693+
1694+
if (forRequirement || isOptional || isArray)
1695+
return matchDeepTypeArguments(*this, subflags, args1, args2, locator);
1696+
1697+
SmallVector<unsigned, 4> mismatches;
1698+
auto result = matchDeepTypeArguments(
1699+
*this, subflags, args1, args2, locator,
1700+
[&mismatches](unsigned position) { mismatches.push_back(position); });
1701+
1702+
if (mismatches.empty())
1703+
return result;
1704+
1705+
auto *fix = GenericArgumentsMismatch::create(
1706+
*this, bound1, bound2, mismatches, getConstraintLocator(locator));
1707+
17081708
if (!recordFix(fix)) {
1709+
// Increase the solution's score for each mismtach this fixes.
1710+
increaseScore(SK_Fix, mismatches.size());
17091711
return getTypeMatchSuccess();
17101712
}
1713+
return result;
17111714
}
1712-
return result;
1715+
return matchDeepTypeArguments(*this, subflags, args1, args2, locator);
17131716
}
17141717

17151718
ConstraintSystem::TypeMatchResult
@@ -2150,12 +2153,12 @@ bool ConstraintSystem::repairFailures(
21502153
}
21512154

21522155
auto hasConversionOrRestriction = [&](ConversionRestrictionKind kind) {
2153-
return llvm::any_of(
2154-
conversionsOrFixes, [kind](const RestrictionOrFix correction) {
2155-
if (auto restriction = correction.getRestriction())
2156-
return restriction == kind;
2157-
return false;
2158-
});
2156+
return llvm::any_of(conversionsOrFixes,
2157+
[kind](const RestrictionOrFix correction) {
2158+
if (auto restriction = correction.getRestriction())
2159+
return restriction == kind;
2160+
return false;
2161+
});
21592162
};
21602163

21612164
auto &elt = path.back();

test/decl/protocol/protocol_with_superclass.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ extension ProtoRefinesClass {
4343
let _: BaseProto & Generic<Int> = self
4444
let _: BaseProto & Concrete = self
4545

46-
let _: Generic<String> = self;
46+
let _: Generic<String> = self
4747
// expected-error@-1 {{cannot assign value of type 'Generic<Int>' to type 'Generic<String>'}}
4848
}
4949
}

0 commit comments

Comments
 (0)