Skip to content

Commit 19e199e

Browse files
authored
Use DefaultArgumentExpr for caller-side defaults (#28279)
Use DefaultArgumentExpr for caller-side defaults
2 parents 5c60af3 + 7e788b8 commit 19e199e

29 files changed

+317
-193
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5263,6 +5263,10 @@ class ParamDecl : public VarDecl {
52635263
/// have a textual representation of their default expression.
52645264
bool hasDefaultExpr() const;
52655265

5266+
/// Whether this parameter has a caller-side default argument expression
5267+
/// such as the magic literal \c #function.
5268+
bool hasCallerSideDefaultExpr() const;
5269+
52665270
/// Retrieve the fully type-checked default argument expression for this
52675271
/// parameter, or \c nullptr if there is no default expression.
52685272
///

include/swift/AST/Expr.h

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ namespace swift {
4848
class Decl;
4949
class DeclRefExpr;
5050
class OpenedArchetypeType;
51+
class ParamDecl;
5152
class Pattern;
5253
class SubscriptDecl;
5354
class Stmt;
@@ -3864,6 +3865,8 @@ class OpaqueValueExpr : public Expr {
38643865
/// A DefaultArgumentExpr must only appear as a direct child of a
38653866
/// ParenExpr or a TupleExpr that is itself a call argument.
38663867
class DefaultArgumentExpr final : public Expr {
3868+
friend class CallerSideDefaultArgExprRequest;
3869+
38673870
/// The owning declaration.
38683871
ConcreteDeclRef DefaultArgsOwner;
38693872

@@ -3873,11 +3876,17 @@ class DefaultArgumentExpr final : public Expr {
38733876
/// The source location of the argument list.
38743877
SourceLoc Loc;
38753878

3879+
/// Stores either a DeclContext or, upon type-checking, the caller-side
3880+
/// default expression.
3881+
PointerUnion<DeclContext *, Expr *> ContextOrCallerSideExpr;
3882+
38763883
public:
3877-
explicit DefaultArgumentExpr(ConcreteDeclRef defaultArgsOwner, unsigned paramIndex,
3878-
SourceLoc loc, Type Ty)
3884+
explicit DefaultArgumentExpr(ConcreteDeclRef defaultArgsOwner,
3885+
unsigned paramIndex, SourceLoc loc, Type Ty,
3886+
DeclContext *dc)
38793887
: Expr(ExprKind::DefaultArgument, /*Implicit=*/true, Ty),
3880-
DefaultArgsOwner(defaultArgsOwner), ParamIndex(paramIndex), Loc(loc) { }
3888+
DefaultArgsOwner(defaultArgsOwner), ParamIndex(paramIndex), Loc(loc),
3889+
ContextOrCallerSideExpr(dc) { }
38813890

38823891
SourceRange getSourceRange() const {
38833892
return Loc;
@@ -3891,46 +3900,19 @@ class DefaultArgumentExpr final : public Expr {
38913900
return ParamIndex;
38923901
}
38933902

3894-
static bool classof(const Expr *E) {
3895-
return E->getKind() == ExprKind::DefaultArgument;
3896-
}
3897-
};
3898-
3899-
/// An expression referring to a caller-side default argument left unspecified
3900-
/// at the call site.
3901-
///
3902-
/// A CallerDefaultArgumentExpr must only appear as a direct child of a
3903-
/// ParenExpr or a TupleExpr that is itself a call argument.
3904-
///
3905-
/// FIXME: This only exists to distinguish caller default arguments from arguments
3906-
/// that were specified at the call site. Once we remove SanitizeExpr, we can remove
3907-
/// this hack too.
3908-
class CallerDefaultArgumentExpr final : public Expr {
3909-
/// The expression that is evaluated to produce the default argument value.
3910-
Expr *SubExpr;
3911-
3912-
/// The source location of the argument list.
3913-
SourceLoc Loc;
3914-
3915-
public:
3916-
explicit CallerDefaultArgumentExpr(Expr *subExpr, SourceLoc loc, Type Ty)
3917-
: Expr(ExprKind::CallerDefaultArgument, /*Implicit=*/true, Ty),
3918-
SubExpr(subExpr), Loc(loc) { }
3903+
/// Retrieves the parameter declaration for this default argument.
3904+
const ParamDecl *getParamDecl() const;
39193905

3920-
SourceRange getSourceRange() const {
3921-
return Loc;
3922-
}
3906+
/// Checks whether this is a caller-side default argument that is emitted
3907+
/// directly at the call site.
3908+
bool isCallerSide() const;
39233909

3924-
Expr *getSubExpr() const {
3925-
return SubExpr;
3926-
}
3927-
3928-
void setSubExpr(Expr *subExpr) {
3929-
SubExpr = subExpr;
3930-
}
3910+
/// For a caller-side default argument, retrieves the fully type-checked
3911+
/// expression within the context of the call site.
3912+
Expr *getCallerSideDefaultExpr() const;
39313913

39323914
static bool classof(const Expr *E) {
3933-
return E->getKind() == ExprKind::CallerDefaultArgument;
3915+
return E->getKind() == ExprKind::DefaultArgument;
39343916
}
39353917
};
39363918

@@ -5398,6 +5380,9 @@ Expr *packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc,
53985380
});
53995381

54005382
void simple_display(llvm::raw_ostream &out, const ClosureExpr *CE);
5383+
void simple_display(llvm::raw_ostream &out, const DefaultArgumentExpr *expr);
5384+
5385+
SourceLoc extractNearestSourceLoc(const DefaultArgumentExpr *expr);
54015386

54025387
} // end namespace swift
54035388

include/swift/AST/ExprNodes.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ EXPR(DynamicType, Expr)
127127
EXPR(RebindSelfInConstructor, Expr)
128128
EXPR(OpaqueValue, Expr)
129129
EXPR(DefaultArgument, Expr)
130-
EXPR(CallerDefaultArgument, Expr)
131130
EXPR(BindOptional, Expr)
132131
EXPR(OptionalEvaluation, Expr)
133132
EXPR(ForceValue, Expr)

include/swift/AST/TypeCheckRequests.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace swift {
3333
class AbstractStorageDecl;
3434
class AccessorDecl;
3535
enum class AccessorKind;
36+
class DefaultArgumentExpr;
3637
class GenericParamList;
3738
class PrecedenceGroupDecl;
3839
struct PropertyWrapperBackingPropertyInfo;
@@ -1886,6 +1887,29 @@ class DefaultArgumentExprRequest
18861887
void cacheResult(Expr *expr) const;
18871888
};
18881889

1890+
/// Computes the fully type-checked caller-side default argument within the
1891+
/// context of the call site that it will be inserted into.
1892+
class CallerSideDefaultArgExprRequest
1893+
: public SimpleRequest<CallerSideDefaultArgExprRequest,
1894+
Expr *(DefaultArgumentExpr *),
1895+
CacheKind::SeparatelyCached> {
1896+
public:
1897+
using SimpleRequest::SimpleRequest;
1898+
1899+
private:
1900+
friend SimpleRequest;
1901+
1902+
// Evaluation.
1903+
llvm::Expected<Expr *> evaluate(Evaluator &evaluator,
1904+
DefaultArgumentExpr *defaultExpr) const;
1905+
1906+
public:
1907+
// Separate caching.
1908+
bool isCached() const { return true; }
1909+
Optional<Expr *> getCachedResult() const;
1910+
void cacheResult(Expr *expr) const;
1911+
};
1912+
18891913
// Allow AnyValue to compare two Type values, even though Type doesn't
18901914
// support ==.
18911915
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ SWIFT_REQUEST(TypeChecker, AttachedPropertyWrapperTypeRequest,
2727
SWIFT_REQUEST(TypeChecker, AttachedPropertyWrappersRequest,
2828
llvm::TinyPtrVector<CustomAttr *>(VarDecl *), Cached,
2929
NoLocationInfo)
30+
SWIFT_REQUEST(TypeChecker, CallerSideDefaultArgExprRequest,
31+
Expr *(DefaultArgumentExpr *), SeparatelyCached, NoLocationInfo)
3032
SWIFT_REQUEST(TypeChecker, ClassAncestryFlagsRequest,
3133
AncestryFlags(ClassDecl *), Cached, NoLocationInfo)
3234
SWIFT_REQUEST(TypeChecker, CompareDeclSpecializationRequest,

lib/AST/ASTDumper.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,12 +2494,6 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
24942494
PrintWithColorRAII(OS, ParenthesisColor) << ')';
24952495
}
24962496

2497-
void visitCallerDefaultArgumentExpr(CallerDefaultArgumentExpr *E) {
2498-
printCommon(E, "caller_default_argument_expr");
2499-
printRec(E->getSubExpr());
2500-
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2501-
}
2502-
25032497
void printArgumentLabels(ArrayRef<Identifier> argLabels) {
25042498
PrintWithColorRAII(OS, ArgumentsColor) << " arg_labels=";
25052499
for (auto label : argLabels) {

lib/AST/ASTWalker.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
483483

484484
Expr *visitDefaultArgumentExpr(DefaultArgumentExpr *E) { return E; }
485485

486-
Expr *visitCallerDefaultArgumentExpr(CallerDefaultArgumentExpr *E) {
487-
if (auto subExpr = doIt(E->getSubExpr())) {
488-
E->setSubExpr(subExpr);
489-
return E;
490-
}
491-
492-
return nullptr;
493-
}
494-
495486
Expr *visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *E) {
496487
if (auto oldAppendingExpr = E->getAppendingExpr()) {
497488
if (auto appendingExpr = doIt(oldAppendingExpr))

lib/AST/Decl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6081,6 +6081,25 @@ bool ParamDecl::hasDefaultExpr() const {
60816081
llvm_unreachable("Unhandled case in switch");
60826082
}
60836083

6084+
bool ParamDecl::hasCallerSideDefaultExpr() const {
6085+
switch (getDefaultArgumentKind()) {
6086+
case DefaultArgumentKind::None:
6087+
case DefaultArgumentKind::Inherited:
6088+
case DefaultArgumentKind::StoredProperty:
6089+
case DefaultArgumentKind::Normal:
6090+
return false;
6091+
case DefaultArgumentKind::File:
6092+
case DefaultArgumentKind::Line:
6093+
case DefaultArgumentKind::Column:
6094+
case DefaultArgumentKind::Function:
6095+
case DefaultArgumentKind::DSOHandle:
6096+
case DefaultArgumentKind::NilLiteral:
6097+
case DefaultArgumentKind::EmptyArray:
6098+
case DefaultArgumentKind::EmptyDictionary:
6099+
return true;
6100+
}
6101+
}
6102+
60846103
Expr *ParamDecl::getTypeCheckedDefaultExpr() const {
60856104
// Don't kick off a request if we know there's no default expr. The only
60866105
// exception is for inherited default args which we need to perform a couple

lib/AST/Expr.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/ASTWalker.h"
2626
#include "swift/AST/AvailabilitySpec.h"
2727
#include "swift/AST/PrettyStackTrace.h"
28+
#include "swift/AST/TypeCheckRequests.h"
2829
#include "swift/AST/TypeLoc.h"
2930
#include "llvm/ADT/APFloat.h"
3031
#include "llvm/ADT/PointerUnion.h"
@@ -311,7 +312,6 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
311312

312313
NO_REFERENCE(OpaqueValue);
313314
NO_REFERENCE(DefaultArgument);
314-
NO_REFERENCE(CallerDefaultArgument);
315315

316316
PASS_THROUGH_REFERENCE(BindOptional, getSubExpr);
317317
PASS_THROUGH_REFERENCE(OptionalEvaluation, getSubExpr);
@@ -620,7 +620,6 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
620620
case ExprKind::RebindSelfInConstructor:
621621
case ExprKind::OpaqueValue:
622622
case ExprKind::DefaultArgument:
623-
case ExprKind::CallerDefaultArgument:
624623
case ExprKind::BindOptional:
625624
case ExprKind::OptionalEvaluation:
626625
return false;
@@ -1382,6 +1381,23 @@ static ValueDecl *getCalledValue(Expr *E) {
13821381
return nullptr;
13831382
}
13841383

1384+
const ParamDecl *DefaultArgumentExpr::getParamDecl() const {
1385+
return getParameterAt(DefaultArgsOwner.getDecl(), ParamIndex);
1386+
}
1387+
1388+
bool DefaultArgumentExpr::isCallerSide() const {
1389+
return getParamDecl()->hasCallerSideDefaultExpr();
1390+
}
1391+
1392+
Expr *DefaultArgumentExpr::getCallerSideDefaultExpr() const {
1393+
assert(isCallerSide());
1394+
auto &ctx = DefaultArgsOwner.getDecl()->getASTContext();
1395+
auto *mutableThis = const_cast<DefaultArgumentExpr *>(this);
1396+
return evaluateOrDefault(ctx.evaluator,
1397+
CallerSideDefaultArgExprRequest{mutableThis},
1398+
new (ctx) ErrorExpr(getSourceRange(), getType()));
1399+
}
1400+
13851401
ValueDecl *ApplyExpr::getCalledValue() const {
13861402
return ::getCalledValue(Fn);
13871403
}
@@ -2209,6 +2225,23 @@ void swift::simple_display(llvm::raw_ostream &out, const ClosureExpr *CE) {
22092225
}
22102226
}
22112227

2228+
void swift::simple_display(llvm::raw_ostream &out,
2229+
const DefaultArgumentExpr *expr) {
2230+
if (!expr) {
2231+
out << "(null)";
2232+
return;
2233+
}
2234+
2235+
out << "default arg for param ";
2236+
out << "#" << expr->getParamIndex() + 1 << " ";
2237+
out << "of ";
2238+
simple_display(out, expr->getDefaultArgsOwner().getDecl());
2239+
}
2240+
2241+
SourceLoc swift::extractNearestSourceLoc(const DefaultArgumentExpr *expr) {
2242+
return expr->getLoc();
2243+
}
2244+
22122245
// See swift/Basic/Statistic.h for declaration: this enables tracing Exprs, is
22132246
// defined here to avoid too much layering violation / circular linkage
22142247
// dependency.

lib/AST/TypeCheckRequests.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,3 +1218,23 @@ void DefaultArgumentExprRequest::cacheResult(Expr *expr) const {
12181218
auto *param = std::get<0>(getStorage());
12191219
param->setDefaultExpr(expr, /*isTypeChecked*/ true);
12201220
}
1221+
1222+
//----------------------------------------------------------------------------//
1223+
// CallerSideDefaultArgExprRequest computation.
1224+
//----------------------------------------------------------------------------//
1225+
1226+
Optional<Expr *> CallerSideDefaultArgExprRequest::getCachedResult() const {
1227+
auto *defaultExpr = std::get<0>(getStorage());
1228+
auto storage = defaultExpr->ContextOrCallerSideExpr;
1229+
assert(!storage.isNull());
1230+
1231+
if (auto *expr = storage.dyn_cast<Expr *>())
1232+
return expr;
1233+
1234+
return None;
1235+
}
1236+
1237+
void CallerSideDefaultArgExprRequest::cacheResult(Expr *expr) const {
1238+
auto *defaultExpr = std::get<0>(getStorage());
1239+
defaultExpr->ContextOrCallerSideExpr = expr;
1240+
}

lib/SILGen/ASTVisitor.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ class ASTVisitor : public swift::ASTVisitor<ImplClass,
6060
llvm_unreachable("DefaultArgumentExpr should not appear in this position");
6161
}
6262

63-
ExprRetTy visitCallerDefaultArgumentExpr(CallerDefaultArgumentExpr *E, Args... AA) {
64-
return static_cast<ImplClass*>(this)->visit(E->getSubExpr(),
65-
std::forward<Args>(AA)...);
66-
}
67-
6863
ExprRetTy visitVarargExpansionExpr(VarargExpansionExpr *E, Args... AA) {
6964
return static_cast<ImplClass*>(this)->visit(E->getSubExpr(),
7065
std::forward<Args>(AA)...);

lib/SILGen/ArgumentSource.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,22 @@ class ArgumentSource {
172172
bool isRValue() const & { return StoredKind == Kind::RValue; }
173173
bool isLValue() const & { return StoredKind == Kind::LValue; }
174174

175-
bool isDefaultArg() const {
175+
/// Whether this argument is for a default argument that should be delayed.
176+
/// Note that this will return false for caller-side default arguments which
177+
/// are emitted directly.
178+
bool isDelayedDefaultArg() const {
176179
switch (StoredKind) {
177180
case Kind::Invalid:
178181
llvm_unreachable("argument source is invalid");
179182
case Kind::RValue:
180183
case Kind::LValue:
181184
return false;
182-
case Kind::Expr:
183-
return isa<DefaultArgumentExpr>(asKnownExpr());
185+
case Kind::Expr: {
186+
auto *defaultArg = dyn_cast<DefaultArgumentExpr>(asKnownExpr());
187+
if (!defaultArg)
188+
return false;
189+
return !defaultArg->isCallerSide();
190+
}
184191
}
185192
llvm_unreachable("bad kind");
186193
}

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,9 +2634,9 @@ class ArgEmitter {
26342634

26352635
// origParamType is a parameter type.
26362636
void emitSingleArg(ArgumentSource &&arg, AbstractionPattern origParamType) {
2637-
// If this is default argument, prepare to emit the default argument
2637+
// If this is delayed default argument, prepare to emit the default argument
26382638
// generator later.
2639-
if (arg.isDefaultArg()) {
2639+
if (arg.isDelayedDefaultArg()) {
26402640
auto substParamType = arg.getSubstRValueType();
26412641
auto defArg = std::move(arg).asKnownDefaultArg();
26422642

0 commit comments

Comments
 (0)