Skip to content

Commit 9d9a8d6

Browse files
committed
[ConstraintSystem] Start using implicit conversion to/from CGFloat
Add logic to `matchTypes` to insert an implicit conversion to/from CGFloat type when two nominal types are matched and one of them is of `CGFloat` type.
1 parent 491ba2c commit 9d9a8d6

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5089,6 +5089,41 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
50895089
}
50905090
}
50915091

5092+
if (kind >= ConstraintKind::Subtype &&
5093+
nominal1->getDecl() != nominal2->getDecl() &&
5094+
(desugar1->isCGFloatType() || desugar2->isCGFloatType())) {
5095+
SmallVector<LocatorPathElt, 4> path;
5096+
auto anchor = locator.getLocatorParts(path);
5097+
5098+
// Try implicit CGFloat conversion only if:
5099+
// - This is not an explicit call to a CGFloat initializer;
5100+
// - This is a first type such conversion is attempted for
5101+
// for a given path (AST element).
5102+
5103+
bool isCGFloatInit = false;
5104+
if (auto *call = getAsExpr<CallExpr>(anchor)) {
5105+
if (auto *typeExpr = dyn_cast<TypeExpr>(call->getFn())) {
5106+
isCGFloatInit = getInstanceType(typeExpr)->isCGFloatType();
5107+
}
5108+
}
5109+
5110+
if (!isCGFloatInit &&
5111+
llvm::none_of(path, [&](const LocatorPathElt &rawElt) {
5112+
if (auto elt =
5113+
rawElt.getAs<LocatorPathElt::ImplicitConversion>()) {
5114+
auto convKind = elt->getConversionKind();
5115+
return convKind == ConversionRestrictionKind::TypeToCGFloat ||
5116+
convKind == ConversionRestrictionKind::CGFloatToType;
5117+
}
5118+
return false;
5119+
})) {
5120+
conversionsOrFixes.push_back(
5121+
desugar1->isCGFloatType()
5122+
? ConversionRestrictionKind::CGFloatToType
5123+
: ConversionRestrictionKind::TypeToCGFloat);
5124+
}
5125+
}
5126+
50925127
break;
50935128
}
50945129

lib/Sema/ConstraintSystem.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4477,6 +4477,29 @@ ConstraintSystem::getArgumentInfo(ConstraintLocator *locator) {
44774477
if (!locator)
44784478
return None;
44794479

4480+
// Implicit conversions to/from CGFloat type are modeled without
4481+
// any changes to the AST, so we have to accomodate for that here
4482+
// by faking presence of appopriate AST location.
4483+
if (locator->isLastElement<LocatorPathElt::ApplyArgument>() ||
4484+
locator->isLastElement<LocatorPathElt::ApplyFunction>()) {
4485+
auto path = locator->getPath().drop_back();
4486+
if (!path.empty() && path.back().is<LocatorPathElt::ImplicitConversion>()) {
4487+
auto conversion = path.back()
4488+
.castTo<LocatorPathElt::ImplicitConversion>()
4489+
.getConversionKind();
4490+
4491+
if (conversion == ConversionRestrictionKind::TypeToCGFloat ||
4492+
conversion == ConversionRestrictionKind::CGFloatToType) {
4493+
// TODO: This is not very efficient, long term we should just
4494+
// save a single `ArgumentInfo` and use it for all of
4495+
// the locations where conversion is needed.
4496+
ArrayRef<Identifier> labels{Identifier()};
4497+
return ArgumentInfo{.Labels = allocateCopy(labels),
4498+
.UnlabeledTrailingClosureIndex = None};
4499+
}
4500+
}
4501+
}
4502+
44804503
if (auto *infoLocator = getArgumentInfoLocator(locator)) {
44814504
auto known = ArgumentInfos.find(infoLocator);
44824505
if (known != ArgumentInfos.end())

0 commit comments

Comments
 (0)