Skip to content

Commit 9f04a5e

Browse files
committed
[CS] Reverse the type order in a couple of pattern equality constraints
Order them such that if they were changed to conversions, they would be sound. This shouldn't make a difference, but unfortunately it turns out pattern equality is not symmetric. As such, tweak the pattern equality logic to account for the reversed types. This allows us to remove a special case from function matching.
1 parent 21512ac commit 9f04a5e

File tree

2 files changed

+27
-22
lines changed

2 files changed

+27
-22
lines changed

lib/Sema/CSGen.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,8 +2648,11 @@ namespace {
26482648
if (!subPatternType)
26492649
return Type();
26502650

2651+
// NOTE: The order here is important! Pattern matching equality is
2652+
// not symmetric (we need to fix that either by using a different
2653+
// constraint, or actually making it symmetric).
26512654
CS.addConstraint(
2652-
ConstraintKind::Equal, subPatternType, openedType,
2655+
ConstraintKind::Equal, openedType, subPatternType,
26532656
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
26542657

26552658
// FIXME [OPAQUE SUPPORT]: the distinction between where we want opaque
@@ -2760,8 +2763,11 @@ namespace {
27602763
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
27612764
castType, bindPatternVarsOneWay);
27622765

2766+
// NOTE: The order here is important! Pattern matching equality is
2767+
// not symmetric (we need to fix that either by using a different
2768+
// constraint, or actually making it symmetric).
27632769
CS.addConstraint(
2764-
ConstraintKind::Equal, subPatternType, castType,
2770+
ConstraintKind::Equal, castType, subPatternType,
27652771
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
27662772
}
27672773
return setType(isType);
@@ -2890,7 +2896,11 @@ namespace {
28902896
// FIXME: Verify ExtInfo state is correct, not working by accident.
28912897
FunctionType::ExtInfo info;
28922898
Type functionType = FunctionType::get(params, outputType, info);
2893-
// TODO: Convert to FunctionInput/FunctionResult constraints.
2899+
2900+
// TODO: Convert to ApplicableFn?
2901+
// NOTE: The order here is important! Pattern matching equality is
2902+
// not symmetric (we need to fix that either by using a different
2903+
// constraint, or actually making it symmetric).
28942904
CS.addConstraint(
28952905
ConstraintKind::Equal, functionType, memberType,
28962906
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));

lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,7 +2125,9 @@ class TupleMatcher {
21252125
const auto &elt1 = tuple1->getElement(i);
21262126
const auto &elt2 = tuple2->getElement(i);
21272127

2128-
if (elt1.hasName() && elt1.getName() != elt2.getName())
2128+
// FIXME: The fact that this isn't symmetric is wrong since this logic
2129+
// is called for bind and equal constraints...
2130+
if (elt2.hasName() && elt1.getName() != elt2.getName())
21292131
return true;
21302132

21312133
pairs.emplace_back(elt1.getType(), elt2.getType(), i, i);
@@ -3502,21 +3504,12 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
35023504
// FIXME: We should check value ownership too, but it's not completely
35033505
// trivial because of inout-to-pointer conversions.
35043506

3505-
// For equality contravariance doesn't matter, but let's make sure
3506-
// that types are matched in original order because that is important
3507-
// when function types are equated as part of pattern matching.
3508-
auto paramType1 = kind == ConstraintKind::Equal ? func1Param.getOldType()
3509-
: func2Param.getOldType();
3510-
3511-
auto paramType2 = kind == ConstraintKind::Equal ? func2Param.getOldType()
3512-
: func1Param.getOldType();
3513-
3514-
// Compare the parameter types.
3515-
auto result = matchTypes(paramType1, paramType2, subKind, subflags,
3516-
(func1Params.size() == 1
3517-
? argumentLocator
3518-
: argumentLocator.withPathElement(
3519-
LocatorPathElt::TupleElement(i))));
3507+
// Compare the parameter types, taking contravariance into account.
3508+
auto result = matchTypes(
3509+
func2Param.getOldType(), func1Param.getOldType(), subKind, subflags,
3510+
(func1Params.size() == 1 ? argumentLocator
3511+
: argumentLocator.withPathElement(
3512+
LocatorPathElt::TupleElement(i))));
35203513
if (result.isFailure())
35213514
return result;
35223515
}
@@ -6356,7 +6349,7 @@ bool ConstraintSystem::repairFailures(
63566349
if (auto *OA = var->getAttrs().getAttribute<ReferenceOwnershipAttr>())
63576350
ROK = OA->get();
63586351

6359-
if (!rhs->getOptionalObjectType() &&
6352+
if (!lhs->getOptionalObjectType() &&
63606353
optionalityOf(ROK) == ReferenceOwnershipOptionality::Required) {
63616354
conversionsOrFixes.push_back(
63626355
AllowNonOptionalWeak::create(*this, getConstraintLocator(NP)));
@@ -14298,8 +14291,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1429814291
if (recordFix(fix))
1429914292
return SolutionKind::Error;
1430014293

14301-
(void)matchTypes(type1, OptionalType::get(type2),
14302-
ConstraintKind::Equal,
14294+
// NOTE: The order here is important! Pattern matching equality is
14295+
// not symmetric (we need to fix that either by using a different
14296+
// constraint, or actually making it symmetric).
14297+
(void)matchTypes(OptionalType::get(type1), type2, ConstraintKind::Equal,
1430314298
TypeMatchFlags::TMF_ApplyingFix, locator);
1430414299

1430514300
return SolutionKind::Solved;

0 commit comments

Comments
 (0)