Skip to content

Commit 53b6acf

Browse files
authored
Merge pull request #14045 from rudkx/keypaths-fix-iuo-on-master
Add support for key paths for the new IUO implementation.
2 parents d76c17e + f86e9ed commit 53b6acf

File tree

1 file changed

+59
-25
lines changed

1 file changed

+59
-25
lines changed

lib/Sema/CSApply.cpp

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4175,6 +4175,24 @@ namespace {
41754175
continue;
41764176
}
41774177

4178+
auto getObjectType = [](Type optionalTy) -> Type {
4179+
Type objectTy;
4180+
if (auto lvalue = optionalTy->getAs<LValueType>()) {
4181+
objectTy = lvalue->getObjectType()->getAnyOptionalObjectType();
4182+
if (optionalTy->hasUnresolvedType() && !objectTy) {
4183+
objectTy = optionalTy;
4184+
}
4185+
objectTy = LValueType::get(objectTy);
4186+
} else {
4187+
objectTy = optionalTy->getAnyOptionalObjectType();
4188+
if (optionalTy->hasUnresolvedType() && !objectTy) {
4189+
objectTy = optionalTy;
4190+
}
4191+
}
4192+
assert(objectTy);
4193+
return objectTy;
4194+
};
4195+
41784196
KeyPathExpr::Component component;
41794197
switch (auto kind = origComponent.getKind()) {
41804198
case KeyPathExpr::Component::Kind::UnresolvedProperty: {
@@ -4220,8 +4238,9 @@ namespace {
42204238
else
42214239
baseTy = objTy;
42224240

4241+
auto loc = origComponent.getLoc();
42234242
resolvedComponents.push_back(
4224-
KeyPathExpr::Component::forOptionalForce(baseTy, SourceLoc()));
4243+
KeyPathExpr::Component::forOptionalForce(baseTy, loc));
42254244
}
42264245

42274246
cs.TC.requestMemberLayout(property);
@@ -4241,6 +4260,17 @@ namespace {
42414260
component = KeyPathExpr::Component::forProperty(ref,
42424261
resolvedTy,
42434262
origComponent.getLoc());
4263+
4264+
baseTy = component.getComponentType();
4265+
resolvedComponents.push_back(component);
4266+
4267+
if (shouldForceUnwrapResult(property, locator)) {
4268+
auto objectTy = getObjectType(baseTy);
4269+
auto loc = origComponent.getLoc();
4270+
component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
4271+
baseTy = component.getComponentType();
4272+
resolvedComponents.push_back(component);
4273+
}
42444274
break;
42454275
}
42464276
case KeyPathExpr::Component::Kind::UnresolvedSubscript: {
@@ -4268,8 +4298,9 @@ namespace {
42684298
else
42694299
baseTy = objTy;
42704300

4301+
auto loc = origComponent.getLoc();
42714302
resolvedComponents.push_back(
4272-
KeyPathExpr::Component::forOptionalForce(baseTy, SourceLoc()));
4303+
KeyPathExpr::Component::forOptionalForce(baseTy, loc));
42734304
}
42744305

42754306
cs.TC.requestMemberLayout(subscript);
@@ -4306,6 +4337,17 @@ namespace {
43064337
// Save a reference to the component so we can do a post-pass to check
43074338
// the Hashable conformance of the indexes.
43084339
KeyPathSubscriptComponents.push_back({E, resolvedComponents.size()});
4340+
4341+
baseTy = component.getComponentType();
4342+
resolvedComponents.push_back(component);
4343+
4344+
if (shouldForceUnwrapResult(subscript, locator)) {
4345+
auto objectTy = getObjectType(baseTy);
4346+
auto loc = origComponent.getLoc();
4347+
component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
4348+
baseTy = component.getComponentType();
4349+
resolvedComponents.push_back(component);
4350+
}
43094351
break;
43104352
}
43114353
case KeyPathExpr::Component::Kind::OptionalChain: {
@@ -4318,43 +4360,34 @@ namespace {
43184360
}
43194361
assert(objectTy);
43204362

4321-
component = KeyPathExpr::Component::forOptionalChain(objectTy,
4322-
origComponent.getLoc());
4363+
auto loc = origComponent.getLoc();
4364+
component = KeyPathExpr::Component::forOptionalChain(objectTy, loc);
4365+
4366+
baseTy = component.getComponentType();
4367+
resolvedComponents.push_back(component);
43234368
break;
43244369
}
43254370
case KeyPathExpr::Component::Kind::OptionalForce: {
4326-
Type objectTy;
4327-
if (auto lvalue = baseTy->getAs<LValueType>()) {
4328-
objectTy = lvalue->getObjectType()->getAnyOptionalObjectType();
4329-
if (baseTy->hasUnresolvedType() && !objectTy) {
4330-
objectTy = baseTy;
4331-
}
4332-
objectTy = LValueType::get(objectTy);
4333-
} else {
4334-
objectTy = baseTy->getAnyOptionalObjectType();
4335-
if (baseTy->hasUnresolvedType() && !objectTy) {
4336-
objectTy = baseTy;
4337-
}
4338-
assert(objectTy);
4339-
}
4340-
4341-
component = KeyPathExpr::Component::forOptionalForce(objectTy,
4342-
origComponent.getLoc());
4371+
auto objectTy = getObjectType(baseTy);
4372+
auto loc = origComponent.getLoc();
4373+
component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
4374+
baseTy = component.getComponentType();
4375+
resolvedComponents.push_back(component);
43434376
break;
43444377
}
43454378
case KeyPathExpr::Component::Kind::Invalid:
43464379
component = origComponent;
43474380
component.setComponentType(leafTy);
4381+
4382+
baseTy = component.getComponentType();
4383+
resolvedComponents.push_back(component);
43484384
break;
43494385

43504386
case KeyPathExpr::Component::Kind::Property:
43514387
case KeyPathExpr::Component::Kind::Subscript:
43524388
case KeyPathExpr::Component::Kind::OptionalWrap:
43534389
llvm_unreachable("already resolved");
43544390
}
4355-
4356-
baseTy = component.getComponentType();
4357-
resolvedComponents.push_back(component);
43584391
}
43594392

43604393
// Wrap a non-optional result if there was chaining involved.
@@ -4389,7 +4422,8 @@ namespace {
43894422

43904423
// The final component type ought to line up with the leaf type of the
43914424
// key path.
4392-
assert(!baseTy || baseTy->getWithoutSpecifierType()->isEqual(leafTy));
4425+
assert(!baseTy || baseTy->hasUnresolvedType()
4426+
|| baseTy->getWithoutSpecifierType()->isEqual(leafTy));
43934427
return E;
43944428
}
43954429

0 commit comments

Comments
 (0)