Skip to content

Commit 66189dc

Browse files
authored
Merge pull request #21763 from slavapestov/match-types-cleanup
Clean up matchTypes() and related code a little
2 parents 05e5eff + 4dfbd8f commit 66189dc

File tree

5 files changed

+53
-124
lines changed

5 files changed

+53
-124
lines changed

lib/Sema/CSApply.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6367,13 +6367,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
63676367
toType->getCanonicalType() });
63686368
if (knownRestriction != solution.ConstraintRestrictions.end()) {
63696369
switch (knownRestriction->second) {
6370-
6371-
case ConversionRestrictionKind::TupleToTuple:
6372-
case ConversionRestrictionKind::LValueToRValue:
6373-
// Restrictions that don't need to be recorded.
6374-
// Should match recordRestriction() in CSSimplify
6375-
break;
6376-
63776370
case ConversionRestrictionKind::DeepEquality: {
63786371
if (toType->hasUnresolvedType())
63796372
break;

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7293,13 +7293,6 @@ bool FailureDiagnosis::diagnoseMemberFailures(
72937293
baseObjTy = baseTy->getWithoutSpecifierType();
72947294
}
72957295

7296-
if (baseTy->is<InOutType>()) {
7297-
auto diag = diagnose(baseExpr->getLoc(), diag::extraneous_address_of);
7298-
if (auto *IOE = dyn_cast<InOutExpr>(baseExpr->getSemanticsProvidingExpr()))
7299-
diag.fixItRemove(IOE->getStartLoc());
7300-
return true;
7301-
}
7302-
73037296
// If the base type is an IUO, look through it. Odds are, the code is not
73047297
// trying to find a member of it.
73057298
// FIXME: We need to rework this with IUOs out of the type system.

lib/Sema/CSSimplify.cpp

Lines changed: 53 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,9 +1667,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
16671667
auto desugar1 = type1->getDesugaredType();
16681668
auto desugar2 = type2->getDesugaredType();
16691669

1670-
auto *typeVar1 = desugar1->getAs<TypeVariableType>();
1671-
auto *typeVar2 = desugar2->getAs<TypeVariableType>();
1672-
16731670
// If the types are obviously equivalent, we're done.
16741671
if (desugar1->isEqual(desugar2))
16751672
return getTypeMatchSuccess();
@@ -1699,6 +1696,9 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
16991696
return getTypeMatchAmbiguous();
17001697
};
17011698

1699+
auto *typeVar1 = dyn_cast<TypeVariableType>(desugar1);
1700+
auto *typeVar2 = dyn_cast<TypeVariableType>(desugar2);
1701+
17021702
// If either (or both) types are type variables, unify the type variables.
17031703
if (typeVar1 || typeVar2) {
17041704
// Handle the easy case of both being type variables, and being
@@ -1800,11 +1800,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
18001800
case ConstraintKind::Conversion:
18011801
case ConstraintKind::ArgumentConversion:
18021802
case ConstraintKind::OperatorArgumentConversion:
1803-
// We couldn't solve this constraint. If only one of the types is a type
1804-
// variable, perhaps we can do something with it below.
1805-
if (typeVar1 && typeVar2)
1806-
return formUnsolvedResult();
1807-
break;
1803+
return formUnsolvedResult();
18081804

18091805
case ConstraintKind::ApplicableFunction:
18101806
case ConstraintKind::DynamicCallableApplicableFunction:
@@ -1830,11 +1826,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
18301826
}
18311827
}
18321828

1833-
bool isTypeVarOrMember1 = desugar1->isTypeVariableOrMember();
1834-
bool isTypeVarOrMember2 = desugar2->isTypeVariableOrMember();
1829+
// If one of the types is a member type of a type variable type,
1830+
// there's nothing we can do.
1831+
if (desugar1->isTypeVariableOrMember() ||
1832+
desugar2->isTypeVariableOrMember()) {
1833+
return formUnsolvedResult();
1834+
}
18351835

18361836
llvm::SmallVector<RestrictionOrFix, 4> conversionsOrFixes;
1837-
bool concrete = !isTypeVarOrMember1 && !isTypeVarOrMember2;
18381837

18391838
// Decompose parallel structure.
18401839
TypeMatchOptions subflags =
@@ -1854,35 +1853,39 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
18541853
#define BUILTIN_TYPE(id, parent) case TypeKind::id:
18551854
#define TYPE(id, parent)
18561855
#include "swift/AST/TypeNodes.def"
1857-
case TypeKind::Module:
1858-
if (desugar1 == desugar2) {
1859-
return getTypeMatchSuccess();
1860-
}
1861-
return getTypeMatchFailure(locator);
18621856

18631857
case TypeKind::Error:
18641858
case TypeKind::Unresolved:
1865-
return getTypeMatchFailure(locator);
1859+
return getTypeMatchFailure(locator);
18661860

18671861
case TypeKind::GenericTypeParam:
18681862
llvm_unreachable("unmapped dependent type in type checker");
18691863

1864+
case TypeKind::TypeVariable:
1865+
llvm_unreachable("type variables should have already been handled by now");
1866+
18701867
case TypeKind::DependentMember:
18711868
// Nothing we can solve.
18721869
return formUnsolvedResult();
18731870

1874-
case TypeKind::TypeVariable:
1871+
case TypeKind::Module:
18751872
case TypeKind::PrimaryArchetype:
18761873
case TypeKind::OpenedArchetype:
18771874
case TypeKind::NestedArchetype:
1878-
// Nothing to do here; handle type variables and archetypes below.
1879-
break;
1875+
// If two module types or archetypes were not already equal, there's
1876+
// nothing more we can do.
1877+
return getTypeMatchFailure(locator);
18801878

18811879
case TypeKind::Tuple: {
1882-
assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
1883-
// Try the tuple-to-tuple conversion.
1884-
if (!type1->is<LValueType>())
1885-
conversionsOrFixes.push_back(ConversionRestrictionKind::TupleToTuple);
1880+
auto result = matchTupleTypes(cast<TupleType>(desugar1),
1881+
cast<TupleType>(desugar2),
1882+
kind, subflags, locator);
1883+
if (result != SolutionKind::Error)
1884+
return result;
1885+
1886+
// FIXME: All cases in this switch should go down to the fix logic
1887+
// to give repairFailures() a chance to run, but this breaks stuff
1888+
// right now.
18861889
break;
18871890
}
18881891

@@ -1891,11 +1894,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
18911894
case TypeKind::Class: {
18921895
auto nominal1 = cast<NominalType>(desugar1);
18931896
auto nominal2 = cast<NominalType>(desugar2);
1894-
assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
1895-
if (!type1->is<LValueType>() &&
1896-
nominal1->getDecl() == nominal2->getDecl()) {
1897+
if (nominal1->getDecl() == nominal2->getDecl())
18971898
conversionsOrFixes.push_back(ConversionRestrictionKind::DeepEquality);
1898-
}
18991899

19001900
// Check for CF <-> ObjectiveC bridging.
19011901
if (isa<ClassType>(desugar1) &&
@@ -1904,19 +1904,15 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
19041904
auto class2 = cast<ClassDecl>(nominal2->getDecl());
19051905

19061906
// CF -> Objective-C via toll-free bridging.
1907-
assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
1908-
if (!type1->is<LValueType>() &&
1909-
class1->getForeignClassKind() == ClassDecl::ForeignKind::CFType &&
1907+
if (class1->getForeignClassKind() == ClassDecl::ForeignKind::CFType &&
19101908
class2->getForeignClassKind() != ClassDecl::ForeignKind::CFType &&
19111909
class1->getAttrs().hasAttribute<ObjCBridgedAttr>()) {
19121910
conversionsOrFixes.push_back(
19131911
ConversionRestrictionKind::CFTollFreeBridgeToObjC);
19141912
}
19151913

19161914
// Objective-C -> CF via toll-free bridging.
1917-
assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
1918-
if (!type1->is<LValueType>() &&
1919-
class2->getForeignClassKind() == ClassDecl::ForeignKind::CFType &&
1915+
if (class2->getForeignClassKind() == ClassDecl::ForeignKind::CFType &&
19201916
class1->getForeignClassKind() != ClassDecl::ForeignKind::CFType &&
19211917
class2->getAttrs().hasAttribute<ObjCBridgedAttr>()) {
19221918
conversionsOrFixes.push_back(
@@ -2001,16 +1997,24 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
20011997
auto bound1 = cast<BoundGenericType>(desugar1);
20021998
auto bound2 = cast<BoundGenericType>(desugar2);
20031999

2004-
assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
2005-
if (!type1->is<LValueType>() && bound1->getDecl() == bound2->getDecl()) {
2000+
if (bound1->getDecl() == bound2->getDecl())
20062001
conversionsOrFixes.push_back(ConversionRestrictionKind::DeepEquality);
2007-
}
20082002
break;
20092003
}
20102004
}
20112005
}
20122006

2013-
if (concrete && kind >= ConstraintKind::Subtype) {
2007+
if (kind >= ConstraintKind::Conversion) {
2008+
// An lvalue of type T1 can be converted to a value of type T2 so long as
2009+
// T1 is convertible to T2 (by loading the value). Note that we cannot get
2010+
// a value of inout type as an lvalue though.
2011+
if (type1->is<LValueType>() && !type2->is<InOutType>()) {
2012+
return matchTypes(type1->getRValueType(), type2,
2013+
kind, subflags, locator);
2014+
}
2015+
}
2016+
2017+
if (kind >= ConstraintKind::Subtype) {
20142018
// Subclass-to-superclass conversion.
20152019
if (type1->mayHaveSuperclass() &&
20162020
type2->getClassOrBoundGenericClass() &&
@@ -2166,14 +2170,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
21662170
return getTypeMatchSuccess();
21672171
}
21682172

2169-
if (concrete && kind >= ConstraintKind::Conversion) {
2170-
// An lvalue of type T1 can be converted to a value of type T2 so long as
2171-
// T1 is convertible to T2 (by loading the value). Note that we cannot get
2172-
// a value of inout type as an lvalue though.
2173-
if (type1->is<LValueType>() && !type2->is<InOutType>())
2174-
conversionsOrFixes.push_back(
2175-
ConversionRestrictionKind::LValueToRValue);
2176-
2173+
if (kind >= ConstraintKind::Conversion) {
21772174
// It is never legal to form an autoclosure that results in these
21782175
// implicit conversions to pointer types.
21792176
bool isAutoClosureArgument = false;
@@ -2301,7 +2298,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
23012298
}
23022299
}
23032300

2304-
if (concrete && kind >= ConstraintKind::OperatorArgumentConversion) {
2301+
if (kind >= ConstraintKind::OperatorArgumentConversion) {
23052302
// If the RHS is an inout type, the LHS must be an @lvalue type.
23062303
if (auto *lvt = type1->getAs<LValueType>()) {
23072304
if (auto *iot = type2->getAs<InOutType>()) {
@@ -2317,7 +2314,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
23172314
// to U by force-unwrapping the source value.
23182315
// A value of type T, T?, or T! can be converted to type U? or U! if
23192316
// T is convertible to U.
2320-
if (concrete && !type1->is<LValueType>() && kind >= ConstraintKind::Subtype) {
2317+
if (!type1->is<LValueType>() && kind >= ConstraintKind::Subtype) {
23212318
enumerateOptionalConversionRestrictions(
23222319
type1, type2, kind, locator,
23232320
[&](ConversionRestrictionKind restriction) {
@@ -2329,15 +2326,15 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
23292326
// literals.
23302327
if (auto elt = locator.last()) {
23312328
if (elt->getKind() == ConstraintLocator::ClosureResult) {
2332-
if (concrete && kind >= ConstraintKind::Subtype &&
2329+
if (kind >= ConstraintKind::Subtype &&
23332330
(type1->isUninhabited() || type2->isVoid())) {
23342331
increaseScore(SK_FunctionConversion);
23352332
return getTypeMatchSuccess();
23362333
}
23372334
}
23382335
}
23392336

2340-
if (concrete && kind == ConstraintKind::BindParam) {
2337+
if (kind == ConstraintKind::BindParam) {
23412338
if (auto *iot = dyn_cast<InOutType>(desugar1)) {
23422339
if (auto *lvt = dyn_cast<LValueType>(desugar2)) {
23432340
return matchTypes(iot->getObjectType(), lvt->getObjectType(),
@@ -2351,7 +2348,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
23512348
// Attempt fixes iff it's allowed, both types are concrete and
23522349
// we are not in the middle of attempting one already.
23532350
bool attemptFixes =
2354-
shouldAttemptFixes() && concrete && !flags.contains(TMF_ApplyingFix);
2351+
shouldAttemptFixes() && !flags.contains(TMF_ApplyingFix);
23552352

23562353
// When we hit this point, we're committed to the set of potential
23572354
// conversions recorded thus far.
@@ -2421,7 +2418,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
24212418
ForceDowncast::create(*this, type2, getConstraintLocator(locator)));
24222419
}
24232420

2424-
if (type2->getRValueType()->is<InOutType>()) {
2421+
if (type2->is<InOutType>()) {
24252422
if (type1->is<LValueType>()) {
24262423
// If we're converting an lvalue to an inout type, add the missing '&'.
24272424
conversionsOrFixes.push_back(
@@ -2446,14 +2443,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
24462443
if (attemptFixes)
24472444
repairFailures(*this, type1, type2, conversionsOrFixes, locator);
24482445

2449-
if (conversionsOrFixes.empty()) {
2450-
// If one of the types is a type variable or member thereof, we leave this
2451-
// unsolved.
2452-
if (isTypeVarOrMember1 || isTypeVarOrMember2)
2453-
return formUnsolvedResult();
2454-
2446+
if (conversionsOrFixes.empty())
24552447
return getTypeMatchFailure(locator);
2456-
}
24572448

24582449
// Where there is more than one potential conversion, create a disjunction
24592450
// so that we'll explore all of the options.
@@ -4930,6 +4921,8 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
49304921
ConstraintKind matchKind,
49314922
TypeMatchOptions flags,
49324923
ConstraintLocatorBuilder locator) {
4924+
assert(!type1->isTypeVariableOrMember() && !type2->isTypeVariableOrMember());
4925+
49334926
// Add to the score based on context.
49344927
auto addContextualScore = [&] {
49354928
// Okay, we need to perform one or more conversions. If this
@@ -4941,41 +4934,18 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
49414934
}
49424935
};
49434936

4944-
// Local function to form an unsolved result.
4945-
auto formUnsolved = [&] {
4946-
if (flags.contains(TMF_GenerateConstraints)) {
4947-
addUnsolvedConstraint(
4948-
Constraint::createRestricted(
4949-
*this, matchKind, restriction, type1, type2,
4950-
getConstraintLocator(locator)));
4951-
4952-
return SolutionKind::Solved;
4953-
}
4954-
4955-
return SolutionKind::Unsolved;
4956-
};
4957-
49584937
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
49594938

49604939
switch (restriction) {
49614940
// for $< in { <, <c, <oc }:
49624941
// T_i $< U_i ===> (T_i...) $< (U_i...)
4963-
case ConversionRestrictionKind::TupleToTuple:
4964-
return matchTupleTypes(type1->castTo<TupleType>(),
4965-
type2->castTo<TupleType>(),
4966-
matchKind, subflags, locator);
4967-
49684942
case ConversionRestrictionKind::DeepEquality:
49694943
return matchDeepEqualityTypes(type1, type2, locator);
49704944

49714945
case ConversionRestrictionKind::Superclass:
49724946
addContextualScore();
49734947
return matchSuperclassTypes(type1, type2, subflags, locator);
49744948

4975-
case ConversionRestrictionKind::LValueToRValue:
4976-
return matchTypes(type1->getRValueType(), type2,
4977-
matchKind, subflags, locator);
4978-
49794949
// for $< in { <, <c, <oc }:
49804950
// T $< U, U : P_i ===> T $< protocol<P_i...>
49814951
case ConversionRestrictionKind::Existential:
@@ -5027,9 +4997,6 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
50274997
increaseScore(SK_ValueToOptional);
50284998

50294999
assert(matchKind >= ConstraintKind::Subtype);
5030-
if (type2->isTypeVariableOrMember())
5031-
return formUnsolved();
5032-
50335000
if (auto generic2 = type2->getAs<BoundGenericType>()) {
50345001
if (generic2->getDecl()->isOptionalDecl()) {
50355002
return matchTypes(type1, generic2->getGenericArgs()[0],
@@ -5051,9 +5018,6 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
50515018
case ConversionRestrictionKind::OptionalToOptional: {
50525019
addContextualScore();
50535020

5054-
if (type1->isTypeVariableOrMember() || type2->isTypeVariableOrMember())
5055-
return formUnsolved();
5056-
50575021
assert(matchKind >= ConstraintKind::Subtype);
50585022
if (auto generic1 = type1->getAs<BoundGenericType>()) {
50595023
if (auto generic2 = type2->getAs<BoundGenericType>()) {
@@ -5296,18 +5260,6 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
52965260
llvm_unreachable("bad conversion restriction");
52975261
}
52985262

5299-
// Restrictions where CSApply can figure out the correct action from the shape of
5300-
// the types, rather than needing a record of the choice made.
5301-
static bool recordRestriction(ConversionRestrictionKind restriction) {
5302-
switch(restriction) {
5303-
case ConversionRestrictionKind::TupleToTuple:
5304-
case ConversionRestrictionKind::LValueToRValue:
5305-
return false;
5306-
default:
5307-
return true;
5308-
}
5309-
}
5310-
53115263
ConstraintSystem::SolutionKind
53125264
ConstraintSystem::simplifyRestrictedConstraint(
53135265
ConversionRestrictionKind restriction,
@@ -5318,8 +5270,7 @@ ConstraintSystem::simplifyRestrictedConstraint(
53185270
switch (simplifyRestrictedConstraintImpl(restriction, type1, type2,
53195271
matchKind, flags, locator)) {
53205272
case SolutionKind::Solved:
5321-
if (recordRestriction(restriction))
5322-
ConstraintRestrictions.push_back(std::make_tuple(type1, type2, restriction));
5273+
ConstraintRestrictions.push_back(std::make_tuple(type1, type2, restriction));
53235274
return SolutionKind::Solved;
53245275

53255276
case SolutionKind::Unsolved:

lib/Sema/Constraint.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,10 @@ void Constraint::dump(ConstraintSystem *CS) const {
428428

429429
StringRef swift::constraints::getName(ConversionRestrictionKind kind) {
430430
switch (kind) {
431-
case ConversionRestrictionKind::TupleToTuple:
432-
return "[tuple-to-tuple]";
433431
case ConversionRestrictionKind::DeepEquality:
434432
return "[deep equality]";
435433
case ConversionRestrictionKind::Superclass:
436434
return "[superclass]";
437-
case ConversionRestrictionKind::LValueToRValue:
438-
return "[lvalue-to-rvalue]";
439435
case ConversionRestrictionKind::Existential:
440436
return "[existential]";
441437
case ConversionRestrictionKind::MetatypeToExistentialMetatype:

0 commit comments

Comments
 (0)