Skip to content

Commit ec72db1

Browse files
authored
Merge pull request #34019 from DougGregor/curry-thunk-dot-syntax-call-source-locs
[Type checker] Use DotSyntaxCallExpr consistently for instance members.
2 parents 0aaade6 + 6ce4eb2 commit ec72db1

File tree

3 files changed

+60
-36
lines changed

3 files changed

+60
-36
lines changed

include/swift/AST/Expr.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4568,16 +4568,10 @@ class DotSyntaxCallExpr : public SelfApplyExpr {
45684568

45694569
SourceLoc getDotLoc() const { return DotLoc; }
45704570

4571-
SourceLoc getLoc() const {
4572-
return isImplicit() ? getBase()->getStartLoc() : getFn()->getLoc();
4573-
}
4574-
SourceLoc getStartLoc() const {
4575-
return getBase()->getStartLoc();
4576-
}
4577-
SourceLoc getEndLoc() const {
4578-
return isImplicit() ? getBase()->getEndLoc() : getFn()->getEndLoc();
4579-
}
4580-
4571+
SourceLoc getLoc() const;
4572+
SourceLoc getStartLoc() const;
4573+
SourceLoc getEndLoc() const;
4574+
45814575
static bool classof(const Expr *E) {
45824576
return E->getKind() == ExprKind::DotSyntaxCall;
45834577
}

lib/AST/Expr.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,6 +1678,12 @@ CallExpr::CallExpr(Expr *fn, Expr *arg, bool Implicit,
16781678
Bits.CallExpr.HasArgLabelLocs = !argLabelLocs.empty();
16791679
Bits.CallExpr.HasTrailingClosure = hasTrailingClosure;
16801680
initializeCallArguments(argLabels, argLabelLocs);
1681+
1682+
#ifndef NDEBUG
1683+
Expr *calleeFn = fn->getSemanticsProvidingExpr();
1684+
if (auto *calleeDRE = dyn_cast<DeclRefExpr>(calleeFn))
1685+
assert(!calleeDRE->getDecl()->isInstanceMember());
1686+
#endif
16811687
}
16821688

16831689
CallExpr *CallExpr::create(ASTContext &ctx, Expr *fn, Expr *arg,
@@ -1751,6 +1757,33 @@ Expr *CallExpr::getDirectCallee() const {
17511757
}
17521758
}
17531759

1760+
SourceLoc DotSyntaxCallExpr::getLoc() const {
1761+
if (isImplicit()) {
1762+
SourceLoc baseLoc = getBase()->getLoc();
1763+
return baseLoc.isValid() ? baseLoc : getFn()->getLoc();
1764+
}
1765+
1766+
return getFn()->getLoc();
1767+
}
1768+
1769+
SourceLoc DotSyntaxCallExpr::getStartLoc() const {
1770+
if (isImplicit()) {
1771+
SourceLoc baseLoc = getBase()->getStartLoc();
1772+
return baseLoc.isValid() ? baseLoc : getFn()->getStartLoc();
1773+
}
1774+
1775+
return getBase()->getStartLoc();
1776+
}
1777+
1778+
SourceLoc DotSyntaxCallExpr::getEndLoc() const {
1779+
if (isImplicit()) {
1780+
SourceLoc fnLoc = getFn()->getEndLoc();
1781+
return fnLoc.isValid() ? fnLoc : getBase()->getEndLoc();
1782+
}
1783+
1784+
return getFn()->getEndLoc();
1785+
}
1786+
17541787
void ExplicitCastExpr::setCastType(Type type) {
17551788
CastTy->setType(MetatypeType::get(type));
17561789
}

lib/Sema/CSApply.cpp

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,24 @@ namespace {
916916

917917
Expr *selfOpenedRef = selfParamRef;
918918

919+
// If the 'self' parameter has non-trivial ownership, adjust the
920+
// argument accordingly.
921+
switch (selfParam.getValueOwnership()) {
922+
case ValueOwnership::Default:
923+
case ValueOwnership::InOut:
924+
break;
925+
926+
case ValueOwnership::Owned:
927+
case ValueOwnership::Shared:
928+
// Ensure that the argument type matches up exactly.
929+
auto selfArgTy = ParenType::get(context,
930+
selfParam.getPlainType(),
931+
selfParam.getParameterFlags());
932+
selfOpenedRef->setType(selfArgTy);
933+
cs.cacheType(selfOpenedRef);
934+
break;
935+
}
936+
919937
if (selfParamTy->hasOpenedExistential()) {
920938
// If we're opening an existential:
921939
// - the type of 'ref' inside the closure is written in terms of the
@@ -931,31 +949,10 @@ namespace {
931949
}
932950

933951
// (Self) -> ...
934-
ApplyExpr *selfCall;
935-
936-
// We build either a CallExpr or a DotSyntaxCallExpr depending on whether
937-
// the base is implicit or not. This helps maintain some invariants around
938-
// source ranges.
939-
if (selfParamRef->isImplicit()) {
940-
selfCall =
941-
CallExpr::createImplicit(context, ref, selfOpenedRef, {},
942-
[&](Expr *E) { return cs.getType(E); });
943-
selfCall->setType(refTy->getResult());
944-
cs.cacheType(selfCall);
945-
946-
// FIXME: This is a holdover from the old tuple-based function call
947-
// representation.
948-
auto selfArgTy = ParenType::get(context,
949-
selfParam.getPlainType(),
950-
selfParam.getParameterFlags());
951-
selfCall->getArg()->setType(selfArgTy);
952-
cs.cacheType(selfCall->getArg());
953-
} else {
954-
selfCall = new (context) DotSyntaxCallExpr(ref, SourceLoc(), selfOpenedRef);
955-
selfCall->setImplicit(false);
956-
selfCall->setType(refTy->getResult());
957-
cs.cacheType(selfCall);
958-
}
952+
ApplyExpr *selfCall = new (context) DotSyntaxCallExpr(
953+
ref, SourceLoc(), selfOpenedRef);
954+
selfCall->setType(refTy->getResult());
955+
cs.cacheType(selfCall);
959956

960957
if (selfParamRef->isSuperExpr())
961958
selfCall->setIsSuper(true);
@@ -7132,7 +7129,7 @@ ExprRewriter::buildDynamicCallable(ApplyExpr *apply, SelectedOverload selected,
71327129

71337130
// Construct expression referencing the `dynamicallyCall` method.
71347131
auto member = buildMemberRef(fn, SourceLoc(), selected,
7135-
DeclNameLoc(method->getNameLoc()), loc, loc,
7132+
DeclNameLoc(), loc, loc,
71367133
/*implicit=*/true, AccessSemantics::Ordinary);
71377134

71387135
// Construct argument to the method (either an array or dictionary

0 commit comments

Comments
 (0)