Skip to content

Commit 250e3fd

Browse files
committed
Sema: Split off buildStaticCurryThunk() from buildMemberRef()
1 parent d81fbd6 commit 250e3fd

File tree

1 file changed

+70
-58
lines changed

1 file changed

+70
-58
lines changed

lib/Sema/CSApply.cpp

Lines changed: 70 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,73 @@ namespace {
16331633
return outerThunk;
16341634
}
16351635

1636+
Expr *buildStaticCurryThunk(Expr *base, Expr *declRefExpr,
1637+
AbstractFunctionDecl *member,
1638+
FunctionType *adjustedOpenedType,
1639+
ConstraintLocatorBuilder locator,
1640+
ConstraintLocatorBuilder memberLocator,
1641+
bool openedExistential) {
1642+
if (cs.isStaticallyDerivedMetatype(base)) {
1643+
// Add a useless ".self" to avoid downstream diagnostics.
1644+
base = new (ctx) DotSelfExpr(base, SourceLoc(), base->getEndLoc(),
1645+
cs.getType(base));
1646+
cs.setType(base, base->getType());
1647+
1648+
// Skip the code below -- we're not building an extra level of
1649+
// call by applying the metatype; instead, the closure we just
1650+
// built is the curried reference.
1651+
return buildSingleCurryThunk(
1652+
base, declRefExpr, member,
1653+
adjustedOpenedType,
1654+
memberLocator);
1655+
} else {
1656+
// Add a useless ".self" to avoid downstream diagnostics, in case
1657+
// the type ref is still a TypeExpr.
1658+
base = new (ctx) DotSelfExpr(base, SourceLoc(), base->getEndLoc(),
1659+
cs.getType(base));
1660+
// Introduce a capture variable.
1661+
cs.cacheType(base);
1662+
solution.setExprTypes(base);
1663+
auto capture = new (ctx) VarDecl(/*static*/ false,
1664+
VarDecl::Introducer::Let,
1665+
base->getEndLoc(),
1666+
ctx.getIdentifier("$base$"),
1667+
dc);
1668+
capture->setImplicit();
1669+
capture->setInterfaceType(base->getType()->mapTypeOutOfContext());
1670+
1671+
auto *capturePat =
1672+
NamedPattern::createImplicit(ctx, capture, base->getType());
1673+
1674+
auto *captureDecl = PatternBindingDecl::createImplicit(
1675+
ctx, StaticSpellingKind::None, capturePat, base, dc);
1676+
1677+
// Write the closure in terms of the capture.
1678+
auto baseRef = new (ctx)
1679+
DeclRefExpr(capture, DeclNameLoc(base->getLoc()), /*implicit*/ true);
1680+
baseRef->setType(base->getType());
1681+
cs.cacheType(baseRef);
1682+
1683+
auto *closure = buildSingleCurryThunk(
1684+
baseRef, declRefExpr, member,
1685+
adjustedOpenedType,
1686+
memberLocator);
1687+
1688+
// Wrap the closure in a capture list.
1689+
auto captureEntry = CaptureListEntry(captureDecl);
1690+
auto captureExpr = CaptureListExpr::create(ctx, captureEntry,
1691+
closure);
1692+
captureExpr->setImplicit();
1693+
captureExpr->setType(cs.getType(closure));
1694+
cs.cacheType(captureExpr);
1695+
1696+
Expr *finalExpr = captureExpr;
1697+
closeExistentials(finalExpr, locator,
1698+
/*force*/ openedExistential);
1699+
return finalExpr;
1700+
}
1701+
}
1702+
16361703
Expr *buildDynamicMemberRef(Expr *base, Type baseTy,
16371704
SourceLoc dotLoc,
16381705
ConcreteDeclRef memberRef,
@@ -2033,65 +2100,10 @@ namespace {
20332100
// or to evaluate the base as a capture and hand it down via the
20342101
// capture list.
20352102
if (isa<ConstructorDecl>(member) || member->isStatic()) {
2036-
if (cs.isStaticallyDerivedMetatype(base)) {
2037-
// Add a useless ".self" to avoid downstream diagnostics.
2038-
base = new (ctx) DotSelfExpr(base, SourceLoc(), base->getEndLoc(),
2039-
cs.getType(base));
2040-
cs.setType(base, base->getType());
2041-
2042-
// Skip the code below -- we're not building an extra level of
2043-
// call by applying the metatype; instead, the closure we just
2044-
// built is the curried reference.
2045-
return buildSingleCurryThunk(
2046-
base, declRefExpr, cast<AbstractFunctionDecl>(member),
2047-
adjustedOpenedType->castTo<FunctionType>(),
2048-
memberLocator);
2049-
} else {
2050-
// Add a useless ".self" to avoid downstream diagnostics, in case
2051-
// the type ref is still a TypeExpr.
2052-
base = new (ctx) DotSelfExpr(base, SourceLoc(), base->getEndLoc(),
2053-
cs.getType(base));
2054-
// Introduce a capture variable.
2055-
cs.cacheType(base);
2056-
solution.setExprTypes(base);
2057-
auto capture = new (ctx) VarDecl(/*static*/ false,
2058-
VarDecl::Introducer::Let,
2059-
base->getEndLoc(),
2060-
ctx.getIdentifier("$base$"),
2061-
dc);
2062-
capture->setImplicit();
2063-
capture->setInterfaceType(base->getType()->mapTypeOutOfContext());
2064-
2065-
auto *capturePat =
2066-
NamedPattern::createImplicit(ctx, capture, base->getType());
2067-
2068-
auto *captureDecl = PatternBindingDecl::createImplicit(
2069-
ctx, StaticSpellingKind::None, capturePat, base, dc);
2070-
2071-
// Write the closure in terms of the capture.
2072-
auto baseRef = new (ctx)
2073-
DeclRefExpr(capture, DeclNameLoc(base->getLoc()), /*implicit*/ true);
2074-
baseRef->setType(base->getType());
2075-
cs.cacheType(baseRef);
2076-
2077-
auto *closure = buildSingleCurryThunk(
2078-
baseRef, declRefExpr, cast<AbstractFunctionDecl>(member),
2103+
return buildStaticCurryThunk(
2104+
base, declRefExpr, cast<AbstractFunctionDecl>(member),
20792105
adjustedOpenedType->castTo<FunctionType>(),
2080-
memberLocator);
2081-
2082-
// Wrap the closure in a capture list.
2083-
auto captureEntry = CaptureListEntry(captureDecl);
2084-
auto captureExpr = CaptureListExpr::create(ctx, captureEntry,
2085-
closure);
2086-
captureExpr->setImplicit();
2087-
captureExpr->setType(cs.getType(closure));
2088-
cs.cacheType(captureExpr);
2089-
2090-
Expr *finalExpr = captureExpr;
2091-
closeExistentials(finalExpr, locator,
2092-
/*force*/ openedExistential);
2093-
return finalExpr;
2094-
}
2106+
locator, memberLocator, openedExistential);
20952107
}
20962108

20972109
FunctionType *curryThunkTy = nullptr;

0 commit comments

Comments
 (0)