Skip to content

Commit 4af5140

Browse files
Merge pull request #70579 from AnthonyLatsis/super-sema
Move unsupported `super` use diagnosis from Parse to Sema
2 parents 4364612 + fa6924a commit 4af5140

25 files changed

+500
-276
lines changed

include/swift/AST/ASTSynthesis.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ void synthesizeDefaultArgumentFromExpr(SynthesisContext &SC, const S &s,
361361
// to render the default argument if you mess up the call.
362362
auto expr = synthesizeExpr(SC, s);
363363
param->setDefaultArgumentKind(DefaultArgumentKind::Normal);
364-
param->setDefaultExpr(expr, /*type checked*/ false);
364+
param->setDefaultExpr(expr);
365365
}
366366

367367
/// Default arguments.
@@ -545,7 +545,7 @@ inline void synthesizeDefaultArgument(SynthesisContext &SC,
545545
case _nil: {
546546
auto expr = synthesizeExpr(SC, s);
547547
param->setDefaultArgumentKind(DefaultArgumentKind::NilLiteral);
548-
param->setDefaultExpr(expr, /*type checked*/ false);
548+
param->setDefaultExpr(expr);
549549
return;
550550
}
551551

include/swift/AST/Decl.h

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6670,8 +6670,15 @@ class ParamDecl : public VarDecl {
66706670
Identifier argumentName, SourceLoc parameterNameLoc,
66716671
Identifier parameterName, DeclContext *dc);
66726672

6673-
/// Create a new ParamDecl identical to the first except without the interface type.
6674-
static ParamDecl *cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD);
6673+
/// Create a new `ParamDecl` identical to the given one except without the
6674+
/// interface type.
6675+
///
6676+
/// \param PD The parameter to clone.
6677+
/// \param defaultArgKind The default argument kind for the cloned parameter.
6678+
/// If \c std::nullopt, use the default argument kind of \p PD.
6679+
static ParamDecl *cloneWithoutType(
6680+
const ASTContext &Ctx, ParamDecl *PD,
6681+
std::optional<DefaultArgumentKind> defaultArgKind = std::nullopt);
66756682

66766683
/// Create a an identical copy of this ParamDecl.
66776684
static ParamDecl *clone(const ASTContext &Ctx, ParamDecl *PD);
@@ -6689,6 +6696,13 @@ class ParamDecl : public VarDecl {
66896696
DeclContext *Parent,
66906697
ParamSpecifier specifier = ParamSpecifier::Default);
66916698

6699+
static ParamDecl *createParsed(ASTContext &Context, SourceLoc specifierLoc,
6700+
SourceLoc argumentNameLoc,
6701+
Identifier argumentName,
6702+
SourceLoc parameterNameLoc,
6703+
Identifier parameterName, Expr *defaultValue,
6704+
DeclContext *dc);
6705+
66926706
/// Retrieve the argument (API) name for this function parameter.
66936707
Identifier getArgumentName() const {
66946708
return ArgumentNameAndFlags.getPointer();
@@ -6729,9 +6743,8 @@ class ParamDecl : public VarDecl {
67296743
bool isDefaultArgument() const {
67306744
return getDefaultArgumentKind() != DefaultArgumentKind::None;
67316745
}
6732-
void setDefaultArgumentKind(DefaultArgumentKind K) {
6733-
Bits.ParamDecl.defaultArgumentKind = static_cast<unsigned>(K);
6734-
}
6746+
6747+
void setDefaultArgumentKind(DefaultArgumentKind K);
67356748

67366749
void setDefaultArgumentKind(ArgumentAttrs K) {
67376750
setDefaultArgumentKind(K.argumentKind);
@@ -6777,13 +6790,19 @@ class ParamDecl : public VarDecl {
67776790
}
67786791

67796792
/// Sets a new default argument expression for this parameter. This should
6780-
/// only be called internally by ParamDecl and AST walkers.
6793+
/// only be called internally by `ParamDecl` and `ASTWalker`.
67816794
///
67826795
/// \param E The new default argument.
6783-
/// \param isTypeChecked Whether this argument should be used as the
6784-
/// parameter's fully type-checked default argument.
6785-
void setDefaultExpr(Expr *E, bool isTypeChecked);
6796+
void setDefaultExpr(Expr *E);
67866797

6798+
// FIXME: private:
6799+
/// Sets a type-checked default argument expression for this parameter. This
6800+
/// should only be called by the `DefaultArgumentExprRequest` request.
6801+
///
6802+
/// \param E The type-checked default argument.
6803+
void setTypeCheckedDefaultExpr(Expr *E);
6804+
6805+
public:
67876806
/// Sets a type of default expression associated with this parameter.
67886807
/// This should only be called by deserialization.
67896808
void setDefaultExprType(Type type);

include/swift/AST/DefaultArgumentKind.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ class StringRef;
2727

2828
namespace swift {
2929

30-
class Expr;
31-
3230
/// Describes the kind of default argument a tuple pattern element has.
3331
enum class DefaultArgumentKind : uint8_t {
3432
/// No default argument.
@@ -56,11 +54,6 @@ enum class DefaultArgumentKind : uint8_t {
5654
};
5755
enum { NumDefaultArgumentKindBits = 4 };
5856

59-
/// Determine the kind of a default argument given a parsed expression that has
60-
/// not yet been type-checked.
61-
/// FIXME: Requestify/internalize the computation of the default arg expr and its kind (given a parsed expr) once the old parser no longer needs this.
62-
DefaultArgumentKind getDefaultArgKind(Expr *init);
63-
6457
struct ArgumentAttrs {
6558
DefaultArgumentKind argumentKind;
6659
bool isUnavailableInSwift = false;

include/swift/AST/DiagnosticsCommon.def

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ NOTE(while_parsing_as_left_angle_bracket,none,
5656
REMARK(remark_max_determinism_overriding,none,
5757
"SWIFTC_MAXIMUM_DETERMINISM overriding %0", (StringRef))
5858

59-
// FIXME: This is used both as a parse error (a literal "super" outside a
60-
// method) and a type-checker error ("super" in a method of a non-class type).
61-
ERROR(super_not_in_class_method,none,
62-
"'super' cannot be used outside of class members", ())
63-
6459
ERROR(class_func_not_in_class,none,
6560
"class methods are only allowed within classes; "
6661
"use 'static' to declare a %select{static|requirement fulfilled by either a static or class}0 method", (bool))

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,13 +1344,6 @@ ERROR(expected_identifier_after_dot_expr,none,
13441344
ERROR(expected_identifier_after_super_dot_expr,
13451345
PointsToFirstBadToken,
13461346
"expected identifier or 'init' after super '.' expression", ())
1347-
ERROR(expected_dot_or_subscript_after_super,PointsToFirstBadToken,
1348-
"expected '.' or '[' after 'super'", ())
1349-
ERROR(super_in_closure_with_capture,none,
1350-
"using 'super' in a closure where 'self' is explicitly captured is "
1351-
"not yet supported", ())
1352-
NOTE(super_in_closure_with_capture_here,none,
1353-
"'self' explicitly captured here", ())
13541347

13551348
WARNING(await_before_try,none, "'try' must precede 'await'", ())
13561349

include/swift/AST/DiagnosticsSema.def

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4315,8 +4315,28 @@ ERROR(no_MaxBuiltinFloatType_found,none,
43154315
ERROR(no_member_of_module,none,
43164316
"module %0 has no member named %1", (Identifier, DeclNameRef))
43174317

4318-
ERROR(super_with_no_base_class,none,
4319-
"'super' members cannot be referenced in a root class", ())
4318+
// 'super'.
4319+
4320+
ERROR(super_invalid_parent_expr,none,
4321+
"'super' may be used only to access a superclass member, subscript, or "
4322+
"initializer", ())
4323+
ERROR(super_no_superclass,none,
4324+
"'super' cannot be used in %select{|extension of }0class %1 because it "
4325+
"has no superclass",
4326+
(bool, const ClassDecl *))
4327+
ERROR(super_invalid_context,none,
4328+
"'super' cannot be used outside of a class computed property, method, "
4329+
"initializer, deinitializer, or subscript", ())
4330+
ERROR(super_in_nonclass_type,none,
4331+
"'super' cannot be used in non-class type %0",
4332+
(const NominalTypeDecl *))
4333+
4334+
ERROR(super_in_closure_with_capture,none,
4335+
"using 'super' in a closure where 'self' is explicitly captured is "
4336+
"not yet supported", ())
4337+
NOTE(super_in_closure_with_capture_here,none,
4338+
"'self' explicitly captured here", ())
4339+
43204340
ERROR(unqualified_init,none,
43214341
"initializer expression requires explicit access"
43224342
"%select{|; did you mean to prepend it with|; did you mean to prepend "

include/swift/Parse/Parser.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,9 +1593,6 @@ class Parser {
15931593
/// The default argument for this parameter.
15941594
Expr *DefaultArg = nullptr;
15951595

1596-
/// True if this parameter inherits a default argument via '= super'
1597-
bool hasInheritedDefaultArg = false;
1598-
15991596
/// True if we emitted a parse error about this parameter.
16001597
bool isInvalid = false;
16011598

lib/AST/ASTBridging.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -840,22 +840,10 @@ BridgedParamDecl BridgedParamDecl_createParsed(
840840
BridgedSourceLoc cArgNameLoc, BridgedIdentifier cParamName,
841841
BridgedSourceLoc cParamNameLoc, BridgedNullableTypeRepr opaqueType,
842842
BridgedNullableExpr opaqueDefaultValue) {
843-
auto *declContext = cDeclContext.unbridged();
844-
845-
auto *defaultValue = opaqueDefaultValue.unbridged();
846-
DefaultArgumentKind defaultArgumentKind;
847-
848-
if (declContext->getParentSourceFile()->Kind == SourceFileKind::Interface &&
849-
isa<SuperRefExpr>(defaultValue)) {
850-
defaultValue = nullptr;
851-
defaultArgumentKind = DefaultArgumentKind::Inherited;
852-
} else {
853-
defaultArgumentKind = getDefaultArgKind(defaultValue);
854-
}
855-
856-
auto *paramDecl = new (cContext.unbridged()) ParamDecl(
857-
cSpecifierLoc.unbridged(), cArgNameLoc.unbridged(), cArgName.unbridged(),
858-
cParamNameLoc.unbridged(), cParamName.unbridged(), declContext);
843+
auto *paramDecl = ParamDecl::createParsed(
844+
cContext.unbridged(), cSpecifierLoc.unbridged(), cArgNameLoc.unbridged(),
845+
cArgName.unbridged(), cParamNameLoc.unbridged(), cParamName.unbridged(),
846+
opaqueDefaultValue.unbridged(), cDeclContext.unbridged());
859847

860848
if (auto type = opaqueType.unbridged()) {
861849
paramDecl->setTypeRepr(type);
@@ -899,9 +887,6 @@ BridgedParamDecl BridgedParamDecl_createParsed(
899887
}
900888
}
901889

902-
paramDecl->setDefaultExpr(defaultValue, /*isTypeChecked*/ false);
903-
paramDecl->setDefaultArgumentKind(defaultArgumentKind);
904-
905890
return paramDecl;
906891
}
907892

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
370370
if (auto *E = P->getStructuralDefaultExpr()) {
371371
auto res = doIt(E);
372372
if (!res) return true;
373-
P->setDefaultExpr(res, /*isTypeChecked*/ (bool)res->getType());
373+
P->setDefaultExpr(res);
374374
}
375375

376376
if (!Walker.shouldWalkAccessorsTheOldWay()) {

lib/AST/Decl.cpp

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8253,13 +8253,19 @@ ParamDecl::ParamDecl(SourceLoc specifierLoc, SourceLoc argumentNameLoc,
82538253
static_cast<unsigned>(DefaultArgumentKind::None);
82548254
}
82558255

8256-
ParamDecl *ParamDecl::cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD) {
8256+
ParamDecl *
8257+
ParamDecl::cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD,
8258+
std::optional<DefaultArgumentKind> defaultArgKind) {
82578259
auto *Clone = new (Ctx) ParamDecl(
82588260
SourceLoc(), SourceLoc(), PD->getArgumentName(),
82598261
SourceLoc(), PD->getParameterName(), PD->getDeclContext());
82608262
Clone->setOptionsAndPointers(nullptr, nullptr, PD->getOptions());
8261-
Clone->Bits.ParamDecl.defaultArgumentKind =
8262-
PD->Bits.ParamDecl.defaultArgumentKind;
8263+
8264+
if (defaultArgKind) {
8265+
Clone->setDefaultArgumentKind(*defaultArgKind);
8266+
} else {
8267+
Clone->setDefaultArgumentKind(PD->getDefaultArgumentKind());
8268+
}
82638269

82648270
Clone->setSpecifier(PD->getSpecifier());
82658271
Clone->setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
@@ -8301,7 +8307,9 @@ ParamDecl *ParamDecl::createImplicit(ASTContext &Context,
83018307
interfaceType, Parent, specifier);
83028308
}
83038309

8304-
DefaultArgumentKind swift::getDefaultArgKind(Expr *init) {
8310+
/// Determine the kind of a default argument for the given expression.
8311+
static DefaultArgumentKind computeDefaultArgumentKind(DeclContext *dc,
8312+
Expr *init) {
83058313
if (!init)
83068314
return DefaultArgumentKind::None;
83078315

@@ -8314,6 +8322,19 @@ DefaultArgumentKind swift::getDefaultArgKind(Expr *init) {
83148322
if (isa<MacroExpansionExpr>(init))
83158323
return DefaultArgumentKind::ExpressionMacro;
83168324

8325+
if (isa<SuperRefExpr>(init)) {
8326+
// The compiler does not synthesize inherited initializers when
8327+
// type-checking Swift module interfaces. Instead, module interfaces are
8328+
// expected to include them explicitly in subclasses. A default argument of
8329+
// '= super' in a parameter of such initializer indicates that the default
8330+
// argument is inherited.
8331+
if (dc->getParentSourceFile()->Kind == SourceFileKind::Interface) {
8332+
return DefaultArgumentKind::Inherited;
8333+
} else {
8334+
return DefaultArgumentKind::Normal;
8335+
}
8336+
}
8337+
83178338
auto magic = dyn_cast<MagicIdentifierLiteralExpr>(init);
83188339
if (!magic)
83198340
return DefaultArgumentKind::Normal;
@@ -8328,6 +8349,36 @@ DefaultArgumentKind swift::getDefaultArgKind(Expr *init) {
83288349
llvm_unreachable("Unhandled MagicIdentifierLiteralExpr in switch.");
83298350
}
83308351

8352+
ParamDecl *ParamDecl::createParsed(ASTContext &Context, SourceLoc specifierLoc,
8353+
SourceLoc argumentNameLoc,
8354+
Identifier argumentName,
8355+
SourceLoc parameterNameLoc,
8356+
Identifier parameterName, Expr *defaultValue,
8357+
DeclContext *dc) {
8358+
auto *decl =
8359+
new (Context) ParamDecl(specifierLoc, argumentNameLoc, argumentName,
8360+
parameterNameLoc, parameterName, dc);
8361+
8362+
const auto kind = computeDefaultArgumentKind(dc, defaultValue);
8363+
if (kind == DefaultArgumentKind::Inherited) {
8364+
// The 'super' in inherited default arguments is a specifier rather than an
8365+
// expression.
8366+
// TODO: However, we may want to retain its location for diagnostics.
8367+
defaultValue = nullptr;
8368+
}
8369+
8370+
decl->setDefaultExpr(defaultValue);
8371+
decl->setDefaultArgumentKind(kind);
8372+
8373+
return decl;
8374+
}
8375+
8376+
void ParamDecl::setDefaultArgumentKind(DefaultArgumentKind K) {
8377+
assert(getDefaultArgumentKind() == DefaultArgumentKind::None &&
8378+
"Overwrite of default argument kind");
8379+
Bits.ParamDecl.defaultArgumentKind = static_cast<unsigned>(K);
8380+
}
8381+
83318382
/// Retrieve the type of 'self' for the given context.
83328383
Type DeclContext::getSelfTypeInContext() const {
83338384
return mapTypeIntoContext(getSelfInterfaceType());
@@ -8576,28 +8627,39 @@ Type ParamDecl::getTypeOfDefaultExpr() const {
85768627
return Type();
85778628
}
85788629

8579-
void ParamDecl::setDefaultExpr(Expr *E, bool isTypeChecked) {
8580-
if (!DefaultValueAndFlags.getPointer()) {
8630+
void ParamDecl::setDefaultExpr(Expr *E) {
8631+
auto *defaultInfo = DefaultValueAndFlags.getPointer();
8632+
if (defaultInfo) {
8633+
assert(defaultInfo->DefaultArg.isNull() ||
8634+
defaultInfo->DefaultArg.is<Expr *>());
8635+
8636+
auto *const oldE = defaultInfo->DefaultArg.dyn_cast<Expr *>();
8637+
assert((bool)E == (bool)oldE && "Overwrite of non-null default with null");
8638+
assert((!oldE || !oldE->getType() || (bool)E->getType()) &&
8639+
"Overwrite of type-checked default with non-type-checked default");
8640+
} else {
85818641
if (!E) return;
85828642

8583-
DefaultValueAndFlags.setPointer(
8584-
getASTContext().Allocate<StoredDefaultArgument>());
8643+
defaultInfo = getASTContext().Allocate<StoredDefaultArgument>();
8644+
DefaultValueAndFlags.setPointer(defaultInfo);
8645+
8646+
defaultInfo->InitContextAndIsTypeChecked.setInt(false);
85858647
}
85868648

8587-
auto *defaultInfo = DefaultValueAndFlags.getPointer();
8588-
assert(defaultInfo->DefaultArg.isNull() ||
8589-
defaultInfo->DefaultArg.is<Expr *>());
8649+
defaultInfo->DefaultArg = E;
8650+
}
8651+
8652+
void ParamDecl::setTypeCheckedDefaultExpr(Expr *E) {
8653+
assert(E || getDefaultArgumentKind() == DefaultArgumentKind::Inherited);
8654+
setDefaultExpr(E);
85908655

8591-
if (!isTypeChecked) {
8592-
assert(!defaultInfo->InitContextAndIsTypeChecked.getInt() &&
8593-
"Can't overwrite type-checked default with un-type-checked default");
8656+
auto *defaultInfo = DefaultValueAndFlags.getPointer();
8657+
if (!defaultInfo) {
8658+
defaultInfo = getASTContext().Allocate<StoredDefaultArgument>();
8659+
DefaultValueAndFlags.setPointer(defaultInfo);
85948660
}
8595-
defaultInfo->DefaultArg = E;
8596-
// `Inherited` default arguments do not have an expression,
8597-
// so if the storage has been pre-allocated already we need
8598-
// to be careful requesting type here.
8599-
defaultInfo->ExprType = E ? E->getType() : Type();
8600-
defaultInfo->InitContextAndIsTypeChecked.setInt(isTypeChecked);
8661+
8662+
defaultInfo->InitContextAndIsTypeChecked.setInt(true);
86018663
}
86028664

86038665
void ParamDecl::setDefaultExprType(Type type) {
@@ -10306,10 +10368,6 @@ AccessorDecl *AccessorDecl::createParsed(
1030610368
// The cloned parameter is implicit.
1030710369
param->setImplicit();
1030810370

10309-
// It has no default arguments; these will be always be taken
10310-
// from the subscript declaration.
10311-
param->setDefaultArgumentKind(DefaultArgumentKind::None);
10312-
1031310371
newParams.push_back(param);
1031410372
}
1031510373
}

0 commit comments

Comments
 (0)