Skip to content

Commit d74e8c9

Browse files
committed
[ConstraintSystem] Convert ConversionRestrictions to a map vector to avoid duplicates
1 parent 880374e commit d74e8c9

File tree

3 files changed

+33
-27
lines changed

3 files changed

+33
-27
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,10 +2184,6 @@ class SolutionApplicationTarget {
21842184
using RewriteTargetFn = std::function<
21852185
Optional<SolutionApplicationTarget> (SolutionApplicationTarget)>;
21862186

2187-
/// Represents a conversion restriction between two types.
2188-
using ConversionRestriction =
2189-
std::tuple<TypeBase *, TypeBase *, ConversionRestrictionKind>;
2190-
21912187
enum class ConstraintSystemPhase {
21922188
ConstraintGeneration,
21932189
Solving,
@@ -2377,7 +2373,8 @@ class ConstraintSystem {
23772373
/// there are multiple ways in which one type could convert to another, e.g.,
23782374
/// given class types A and B, the solver might choose either a superclass
23792375
/// conversion or a user-defined conversion.
2380-
std::vector<ConversionRestriction> ConstraintRestrictions;
2376+
llvm::MapVector<std::pair<TypeBase *, TypeBase *>, ConversionRestrictionKind>
2377+
ConstraintRestrictions;
23812378

23822379
/// The set of fixes applied to make the solution work.
23832380
llvm::SmallVector<ConstraintFix *, 4> Fixes;
@@ -3472,6 +3469,16 @@ class ConstraintSystem {
34723469
});
34733470
}
34743471

3472+
bool
3473+
hasConversionRestriction(Type type1, Type type2,
3474+
ConversionRestrictionKind restrictionKind) const {
3475+
auto restriction =
3476+
ConstraintRestrictions.find({type1.getPointer(), type2.getPointer()});
3477+
return restriction == ConstraintRestrictions.end()
3478+
? false
3479+
: restriction->second == restrictionKind;
3480+
}
3481+
34753482
/// If an UnresolvedDotExpr, SubscriptMember, etc has been resolved by the
34763483
/// constraint system, return the decl that it references.
34773484
ValueDecl *findResolvedMemberRef(ConstraintLocator *locator);

lib/Sema/CSSimplify.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,10 +3973,10 @@ bool ConstraintSystem::repairFailures(
39733973
// we can instead suggest the conditional downcast as it is safer in
39743974
// situations like conditional binding.
39753975
auto useConditionalCast =
3976-
llvm::any_of(ConstraintRestrictions, [&](auto &restriction) {
3977-
ConversionRestrictionKind restrictionKind;
3976+
llvm::any_of(ConstraintRestrictions, [&](const auto &restriction) {
39783977
Type type1, type2;
3979-
std::tie(type1, type2, restrictionKind) = restriction;
3978+
std::tie(type1, type2) = restriction.first;
3979+
auto restrictionKind = restriction.second;
39803980

39813981
if (restrictionKind != ConversionRestrictionKind::ValueToOptional)
39823982
return false;
@@ -6770,7 +6770,6 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
67706770
ConstraintSystem &cs, Type origFromType, Type origToType, Type fromType,
67716771
Type toType, SmallVector<Type, 4> fromOptionals,
67726772
SmallVector<Type, 4> toOptionals,
6773-
const std::vector<ConversionRestriction> &constraintRestrictions,
67746773
ConstraintSystem::TypeMatchOptions flags,
67756774
ConstraintLocatorBuilder locator) {
67766775

@@ -6797,10 +6796,8 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
67976796
// "from" expression could be a type variable with value-to-optional
67986797
// restrictions that we have to account for optionality mismatch.
67996798
const auto subExprType = cs.getType(castExpr->getSubExpr());
6800-
if (llvm::is_contained(
6801-
constraintRestrictions,
6802-
std::make_tuple(fromType.getPointer(), subExprType.getPointer(),
6803-
ConversionRestrictionKind::ValueToOptional))) {
6799+
if (cs.hasConversionRestriction(fromType, subExprType,
6800+
ConversionRestrictionKind::ValueToOptional)) {
68046801
extraOptionals++;
68056802
origFromType = OptionalType::get(origFromType);
68066803
}
@@ -6960,7 +6957,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
69606957

69616958
if (auto *fix = maybeWarnAboutExtraneousCast(
69626959
*this, origFromType, origToType, fromType, toType, fromOptionals,
6963-
toOptionals, ConstraintRestrictions, flags, locator)) {
6960+
toOptionals, flags, locator)) {
69646961
(void)recordFix(fix);
69656962
}
69666963
};
@@ -7028,7 +7025,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
70287025
// succeed or fail.
70297026
if (auto *fix = maybeWarnAboutExtraneousCast(
70307027
*this, origFromType, origToType, fromType, toType, fromOptionals,
7031-
toOptionals, ConstraintRestrictions, flags, locator)) {
7028+
toOptionals, flags, locator)) {
70327029
(void)recordFix(fix);
70337030
}
70347031

@@ -11358,8 +11355,8 @@ ConstraintSystem::simplifyRestrictedConstraint(
1135811355
addFixConstraint(fix, matchKind, type1, type2, locator);
1135911356
}
1136011357

11361-
ConstraintRestrictions.push_back(
11362-
std::make_tuple(type1.getPointer(), type2.getPointer(), restriction));
11358+
ConstraintRestrictions.insert({
11359+
std::make_pair(type1.getPointer(), type2.getPointer()), restriction});
1136311360
return SolutionKind::Solved;
1136411361
}
1136511362
case SolutionKind::Unsolved:

lib/Sema/CSSolver.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,13 @@ Solution ConstraintSystem::finalize() {
109109
// For each of the constraint restrictions, record it with simplified,
110110
// canonical types.
111111
if (solverState) {
112-
for (auto &restriction : ConstraintRestrictions) {
113-
using std::get;
114-
CanType first = simplifyType(get<0>(restriction))->getCanonicalType();
115-
CanType second = simplifyType(get<1>(restriction))->getCanonicalType();
116-
solution.ConstraintRestrictions[{first, second}] = get<2>(restriction);
112+
for (const auto &entry : ConstraintRestrictions) {
113+
const auto &types = entry.first;
114+
auto restriction = entry.second;
115+
116+
CanType first = simplifyType(types.first)->getCanonicalType();
117+
CanType second = simplifyType(types.second)->getCanonicalType();
118+
solution.ConstraintRestrictions[{first, second}] = restriction;
117119
}
118120
}
119121

@@ -224,11 +226,11 @@ void ConstraintSystem::applySolution(const Solution &solution) {
224226

225227
// Register constraint restrictions.
226228
// FIXME: Copy these directly into some kind of partial solution?
227-
for (auto restriction : solution.ConstraintRestrictions) {
228-
auto &types = restriction.first;
229-
ConstraintRestrictions.push_back(std::make_tuple(types.first.getPointer(),
230-
types.second.getPointer(),
231-
restriction.second));
229+
for ( auto &restriction : solution.ConstraintRestrictions) {
230+
auto *type1 = restriction.first.first.getPointer();
231+
auto *type2 = restriction.first.second.getPointer();
232+
233+
ConstraintRestrictions.insert({{type1, type2}, restriction.second});
232234
}
233235

234236
// Register the solution's disjunction choices.

0 commit comments

Comments
 (0)