Skip to content

Commit 6a8dc61

Browse files
authored
Merge pull request #13728 from rudkx/redo-disjunction-constraint-locators
IUO: Replace one ConstraintLocator with two.
2 parents 07507da + dbb2932 commit 6a8dc61

File tree

5 files changed

+58
-27
lines changed

5 files changed

+58
-27
lines changed

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3413,7 +3413,7 @@ namespace {
34133413
auto *TR = expr->getCastTypeLoc().getTypeRepr();
34143414
if (TR && TR->getKind() == TypeReprKind::ImplicitlyUnwrappedOptional) {
34153415
auto *locator = cs.getConstraintLocator(
3416-
expr, ConstraintLocator::ImplicitlyUnwrappedCoercionResult);
3416+
expr, ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice);
34173417
return solution.getDisjunctionChoice(locator);
34183418
}
34193419
return false;

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,7 @@ namespace {
24982498
createTypeVariableAndDisjunctionForIUOCoercion(Type toType,
24992499
ConstraintLocator *locator) {
25002500
auto implicitUnwrapLocator = CS.getConstraintLocator(
2501-
locator, ConstraintLocator::ImplicitlyUnwrappedCoercionResult);
2501+
locator, ConstraintLocator::ImplicitlyUnwrappedValue);
25022502
auto typeVar =
25032503
CS.createTypeVariable(implicitUnwrapLocator, /*options=*/0);
25042504
CS.buildDisjunctionForImplicitlyUnwrappedOptional(typeVar, toType,

lib/Sema/ConstraintLocator.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
7878
case KeyPathComponent:
7979
case ConditionalRequirement:
8080
case TypeParameterRequirement:
81-
case ImplicitlyUnwrappedCoercionResult:
81+
case ImplicitlyUnwrappedValue:
82+
case ImplicitlyUnwrappedDisjunctionChoice:
8283
if (unsigned numValues = numNumericValuesInPathElement(elt.getKind())) {
8384
id.AddInteger(elt.getValue());
8485
if (numValues > 1)
@@ -250,8 +251,12 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
250251
out << "type parameter requirement #" << llvm::utostr(elt.getValue());
251252
break;
252253

253-
case ImplicitlyUnwrappedCoercionResult:
254-
out << "implictly unwrapped coercion result";
254+
case ImplicitlyUnwrappedValue:
255+
out << "implictly unwrapped value";
256+
break;
257+
258+
case ImplicitlyUnwrappedDisjunctionChoice:
259+
out << "implictly unwrapped disjunction choice";
255260
break;
256261
}
257262
}

lib/Sema/ConstraintLocator.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,14 @@ class ConstraintLocator : public llvm::FoldingSetNode {
127127
ConditionalRequirement,
128128
/// A single requirement placed on the type parameters.
129129
TypeParameterRequirement,
130-
/// \brief A coercion to an Optional type that can potentially be
131-
/// force-unwrapped to the underlying type.
132-
ImplicitlyUnwrappedCoercionResult,
130+
/// \brief For Optional types that can be implicitly unwrapped as
131+
/// needed to successfully type check.
132+
ImplicitlyUnwrappedValue,
133+
/// \brief For the disjunction choices that result from when we
134+
/// see ImplicitlyUnwrappedValue. This is used to avoid infinite
135+
/// recursion where we would split those types out again into
136+
/// another disjunction.
137+
ImplicitlyUnwrappedDisjunctionChoice,
133138
};
134139

135140
/// \brief Determine the number of numeric values used for the given path
@@ -162,7 +167,8 @@ class ConstraintLocator : public llvm::FoldingSetNode {
162167
case Requirement:
163168
case Witness:
164169
case OpenedGeneric:
165-
case ImplicitlyUnwrappedCoercionResult:
170+
case ImplicitlyUnwrappedValue:
171+
case ImplicitlyUnwrappedDisjunctionChoice:
166172
return 0;
167173

168174
case GenericArgument:
@@ -225,7 +231,8 @@ class ConstraintLocator : public llvm::FoldingSetNode {
225231
case KeyPathComponent:
226232
case ConditionalRequirement:
227233
case TypeParameterRequirement:
228-
case ImplicitlyUnwrappedCoercionResult:
234+
case ImplicitlyUnwrappedValue:
235+
case ImplicitlyUnwrappedDisjunctionChoice:
229236
return 0;
230237

231238
case FunctionArgument:

lib/Sema/ConstraintSystem.h

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,34 +2338,53 @@ class ConstraintSystem {
23382338
void buildDisjunctionForImplicitlyUnwrappedOptional(
23392339
TypeVariableType *tv, Type type, ConstraintLocator *locator) {
23402340

2341+
// Get a locator based on the anchor expression so that it's easy to
2342+
// regenerate the same locator for lookup when applying the results.
2343+
auto *disjunctionLocator = getConstraintLocator(
2344+
locator->getAnchor(),
2345+
ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice);
2346+
23412347
// Create the constraint to bind to the optional type and make it
23422348
// the favored choice.
2343-
auto *bindToOptional =
2344-
Constraint::create(*this, ConstraintKind::Bind, tv, type, locator);
2349+
auto *bindToOptional = Constraint::create(*this, ConstraintKind::Bind, tv,
2350+
type, disjunctionLocator);
23452351
bindToOptional->setFavored();
23462352

23472353
Type underlyingType;
2354+
if (auto *fnTy = type->getAs<AnyFunctionType>()) {
2355+
auto resultTy = fnTy->getResult();
2356+
while (resultTy->is<AnyFunctionType>())
2357+
resultTy = resultTy->castTo<AnyFunctionType>()->getResult();
2358+
2359+
assert(resultTy->getAnyOptionalObjectType());
2360+
2361+
if (auto genericFn = type->getAs<GenericFunctionType>()) {
2362+
underlyingType = GenericFunctionType::get(
2363+
genericFn->getGenericSignature(), genericFn->getParams(),
2364+
resultTy->getAnyOptionalObjectType(), genericFn->getExtInfo());
2365+
} else {
2366+
underlyingType = FunctionType::get(fnTy->getParams(),
2367+
resultTy->getAnyOptionalObjectType(),
2368+
fnTy->getExtInfo());
2369+
}
2370+
} else {
2371+
underlyingType =
2372+
type->getWithoutSpecifierType()->getAnyOptionalObjectType();
2373+
assert(underlyingType);
2374+
2375+
if (type->is<LValueType>())
2376+
underlyingType = LValueType::get(underlyingType);
2377+
assert(!type->is<InOutType>());
2378+
}
23482379

2349-
// FIXME: Support unwrapping results of function calls.
2350-
assert(!type->is<AnyFunctionType>());
2351-
2352-
underlyingType = type->getWithoutSpecifierType()->getAnyOptionalObjectType();
2353-
assert(underlyingType);
2354-
2355-
if (type->is<LValueType>())
2356-
underlyingType = LValueType::get(underlyingType);
2357-
else if (type->is<InOutType>())
2358-
underlyingType = InOutType::get(underlyingType);
2359-
2360-
// Create the constraint to bind to the underlying type.
2361-
auto *bindToUnderlying = Constraint::create(*this, ConstraintKind::Bind, tv,
2362-
underlyingType, locator);
2380+
auto *bindToUnderlying = Constraint::create(
2381+
*this, ConstraintKind::Bind, tv, underlyingType, disjunctionLocator);
23632382

23642383
llvm::SmallVector<Constraint *, 2> choices = {bindToOptional,
23652384
bindToUnderlying};
23662385

23672386
// Create the disjunction
2368-
addDisjunctionConstraint(choices, locator, RememberChoice);
2387+
addDisjunctionConstraint(choices, disjunctionLocator, RememberChoice);
23692388
}
23702389

23712390

0 commit comments

Comments
 (0)