Skip to content

Commit 8d2f2ba

Browse files
committed
[CS] Remove external type logic from getTypeForPattern
This shouldn't be necessary, we should be able to solve with type variables instead. This makes sure we don't end up with weird special cases that only occur when an external type is present.
1 parent 23dbf6f commit 8d2f2ba

File tree

3 files changed

+15
-78
lines changed

3 files changed

+15
-78
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8756,7 +8756,7 @@ bool InvalidWeakAttributeUse::diagnoseAsError() {
87568756
return false;
87578757

87588758
auto *var = pattern->getDecl();
8759-
auto varType = OptionalType::get(getType(var));
8759+
auto varType = getType(var);
87608760

87618761
auto diagnostic =
87628762
emitDiagnosticAt(var, diag::invalid_ownership_not_optional,

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,17 +2438,12 @@ namespace {
24382438
/// \param locator The locator to use for generated constraints and
24392439
/// type variables.
24402440
///
2441-
/// \param externalPatternType The type imposed by the enclosing pattern,
2442-
/// if any. This will be non-null in cases where there is, e.g., a
2443-
/// pattern such as "is SubClass".
2444-
///
24452441
/// \param bindPatternVarsOneWay When true, generate fresh type variables
24462442
/// for the types of each variable declared within the pattern, along
24472443
/// with a one-way constraint binding that to the type to which the
24482444
/// variable will be ascribed or inferred.
24492445
Type getTypeForPattern(
24502446
Pattern *pattern, ConstraintLocatorBuilder locator,
2451-
Type externalPatternType,
24522447
bool bindPatternVarsOneWay,
24532448
PatternBindingDecl *patternBinding = nullptr,
24542449
unsigned patternBindingIndex = 0) {
@@ -2476,19 +2471,11 @@ namespace {
24762471
case PatternKind::Paren: {
24772472
auto *paren = cast<ParenPattern>(pattern);
24782473

2479-
// Parentheses don't affect the canonical type, but record them as
2480-
// type sugar.
2481-
if (externalPatternType &&
2482-
isa<ParenType>(externalPatternType.getPointer())) {
2483-
externalPatternType = cast<ParenType>(externalPatternType.getPointer())
2484-
->getUnderlyingType();
2485-
}
2486-
24872474
auto *subPattern = paren->getSubPattern();
24882475
auto underlyingType = getTypeForPattern(
24892476
subPattern,
24902477
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
2491-
externalPatternType, bindPatternVarsOneWay);
2478+
bindPatternVarsOneWay);
24922479

24932480
if (!underlyingType)
24942481
return Type();
@@ -2497,7 +2484,7 @@ namespace {
24972484
}
24982485
case PatternKind::Binding: {
24992486
auto *subPattern = cast<BindingPattern>(pattern)->getSubPattern();
2500-
auto type = getTypeForPattern(subPattern, locator, externalPatternType,
2487+
auto type = getTypeForPattern(subPattern, locator,
25012488
bindPatternVarsOneWay);
25022489

25032490
if (!type)
@@ -2526,9 +2513,7 @@ namespace {
25262513
locator.withPathElement(LocatorPathElt::PatternMatch(pattern));
25272514

25282515
// Always prefer a contextual type when it's available.
2529-
if (externalPatternType) {
2530-
type = externalPatternType;
2531-
} else if (auto *initializer = getInitializerExpr()) {
2516+
if (auto *initializer = getInitializerExpr()) {
25322517
// For initialization always assume a type of initializer.
25332518
type = CS.getType(initializer)->getRValueType();
25342519
} else {
@@ -2608,18 +2593,13 @@ namespace {
26082593
// diagnostic in the middle of the solver path.
26092594

26102595
CS.addConstraint(ConstraintKind::OneWayEqual, oneWayVarType,
2611-
externalPatternType ? externalPatternType : varType,
2612-
locator);
2596+
varType, locator);
26132597
}
26142598

26152599
// Ascribe a type to the declaration so it's always available to
26162600
// constraint system.
26172601
if (oneWayVarType) {
26182602
CS.setType(var, oneWayVarType);
2619-
} else if (externalPatternType) {
2620-
// If there is an externally imposed type, that's what the
2621-
// declaration is going to be bound to.
2622-
CS.setType(var, externalPatternType);
26232603
} else {
26242604
// Otherwise, let's use the type of the pattern. The type
26252605
// of the declaration has to be r-value, so let's add an
@@ -2708,7 +2688,7 @@ namespace {
27082688
Type subPatternType = getTypeForPattern(
27092689
subPattern,
27102690
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
2711-
openedType, bindPatternVarsOneWay);
2691+
bindPatternVarsOneWay);
27122692

27132693
if (!subPatternType)
27142694
return Type();
@@ -2731,38 +2711,16 @@ namespace {
27312711
case PatternKind::Tuple: {
27322712
auto tuplePat = cast<TuplePattern>(pattern);
27332713

2734-
// If there's an externally-imposed type, decompose it into element
2735-
// types so long as we have the right number of such types.
2736-
SmallVector<AnyFunctionType::Param, 4> externalEltTypes;
2737-
if (externalPatternType) {
2738-
decomposeTuple(externalPatternType, externalEltTypes);
2739-
2740-
// If we have the wrong number of elements, we may not be able to
2741-
// provide more specific types.
2742-
if (tuplePat->getNumElements() != externalEltTypes.size()) {
2743-
externalEltTypes.clear();
2744-
2745-
// Implicit tupling.
2746-
if (tuplePat->getNumElements() == 1) {
2747-
externalEltTypes.push_back(
2748-
AnyFunctionType::Param(externalPatternType));
2749-
}
2750-
}
2751-
}
2752-
27532714
SmallVector<TupleTypeElt, 4> tupleTypeElts;
27542715
tupleTypeElts.reserve(tuplePat->getNumElements());
27552716
for (unsigned i = 0, e = tuplePat->getNumElements(); i != e; ++i) {
27562717
auto &tupleElt = tuplePat->getElement(i);
2757-
Type externalEltType;
2758-
if (!externalEltTypes.empty())
2759-
externalEltType = externalEltTypes[i].getPlainType();
27602718

27612719
auto *eltPattern = tupleElt.getPattern();
27622720
Type eltTy = getTypeForPattern(
27632721
eltPattern,
27642722
locator.withPathElement(LocatorPathElt::PatternMatch(eltPattern)),
2765-
externalEltType, bindPatternVarsOneWay);
2723+
bindPatternVarsOneWay);
27662724

27672725
if (!eltTy)
27682726
return Type();
@@ -2774,25 +2732,12 @@ namespace {
27742732
}
27752733

27762734
case PatternKind::OptionalSome: {
2777-
// Remove an optional from the object type.
2778-
if (externalPatternType) {
2779-
Type objVar = CS.createTypeVariable(
2780-
CS.getConstraintLocator(
2781-
locator.withPathElement(ConstraintLocator::OptionalPayload)),
2782-
TVO_CanBindToNoEscape);
2783-
CS.addConstraint(
2784-
ConstraintKind::OptionalObject, externalPatternType, objVar,
2785-
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
2786-
2787-
externalPatternType = objVar;
2788-
}
2789-
27902735
auto *subPattern = cast<OptionalSomePattern>(pattern)->getSubPattern();
27912736
// The subpattern must have optional type.
27922737
Type subPatternType = getTypeForPattern(
27932738
subPattern,
27942739
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
2795-
externalPatternType, bindPatternVarsOneWay);
2740+
bindPatternVarsOneWay);
27962741

27972742
if (!subPatternType)
27982743
return Type();
@@ -2827,7 +2772,7 @@ namespace {
28272772
auto subPatternType = getTypeForPattern(
28282773
subPattern,
28292774
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
2830-
castType, bindPatternVarsOneWay);
2775+
bindPatternVarsOneWay);
28312776

28322777
// NOTE: The order here is important! Pattern matching equality is
28332778
// not symmetric (we need to fix that either by using a different
@@ -2912,18 +2857,6 @@ namespace {
29122857
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
29132858

29142859
baseType = parentType;
2915-
// Perform member lookup into the external pattern metatype. e.g.
2916-
// `case let .test(tuple) as Test`.
2917-
} else if (externalPatternType) {
2918-
Type externalMetaType = MetatypeType::get(externalPatternType);
2919-
2920-
CS.addValueMemberConstraint(
2921-
externalMetaType, enumPattern->getName(), memberType, CurDC,
2922-
functionRefKind, {},
2923-
CS.getConstraintLocator(locator,
2924-
LocatorPathElt::PatternMatch(pattern)));
2925-
2926-
baseType = externalPatternType;
29272860
} else {
29282861
// Use the pattern type for member lookup.
29292862
CS.addUnresolvedValueMemberConstraint(
@@ -2941,7 +2874,7 @@ namespace {
29412874
Type subPatternType = getTypeForPattern(
29422875
subPattern,
29432876
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
2944-
Type(), bindPatternVarsOneWay);
2877+
bindPatternVarsOneWay);
29452878

29462879
if (!subPatternType)
29472880
return Type();
@@ -4856,7 +4789,7 @@ Type ConstraintSystem::generateConstraints(
48564789
bool bindPatternVarsOneWay, PatternBindingDecl *patternBinding,
48574790
unsigned patternIndex) {
48584791
ConstraintGenerator cg(*this, nullptr);
4859-
return cg.getTypeForPattern(pattern, locator, Type(), bindPatternVarsOneWay,
4792+
return cg.getTypeForPattern(pattern, locator, bindPatternVarsOneWay,
48604793
patternBinding, patternIndex);
48614794
}
48624795

test/Constraints/patterns.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,3 +564,7 @@ struct TestIUOMatchOp {
564564
if case self = self {}
565565
}
566566
}
567+
568+
struct TestRecursiveVarRef<T> {
569+
lazy var e: () -> Int = {e}()
570+
}

0 commit comments

Comments
 (0)