Skip to content

Commit c95252e

Browse files
author
Nathan Hawes
committed
Change from using the @_inheritedDefaultValue attribute to mark parameters with an inherited default argument to using '= super'
1 parent b425987 commit c95252e

File tree

9 files changed

+47
-35
lines changed

9 files changed

+47
-35
lines changed

include/swift/AST/Attr.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,6 @@ SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly,
396396
DECL_ATTR(_custom, Custom,
397397
OnAnyDecl | UserInaccessible,
398398
85)
399-
SIMPLE_DECL_ATTR(_inheritedDefaultValue, InheritedDefaultValue,
400-
OnParam | UserInaccessible,
401-
86)
402399

403400
#undef TYPE_ATTR
404401
#undef DECL_ATTR_ALIAS

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,13 +1282,14 @@ WARNING(expr_dynamic_lookup_swift3_objc_inference,none,
12821282
(DescriptiveDeclKind, DeclName, Identifier))
12831283

12841284
ERROR(inherited_default_value_not_on_constructor_param,none,
1285-
"@_inheritedDefaultValue is only valid on parameter declarations of initializers", ())
1285+
"default value inheritance via 'super' is only valid for initializer "
1286+
"parameters", ())
12861287
ERROR(corresponding_param_not_defaulted,none,
1287-
"@_inheritedDefaultValue requires that the corresponding parameter of "
1288-
"the overridden initializer has a default value", ())
1288+
"default value inheritance via 'super' requires that the corresponding "
1289+
"parameter of the overridden initializer has a default value", ())
12891290
ERROR(inherited_default_value_used_in_non_overriding_constructor,none,
1290-
"@_inheritedDefaultValue can only be used on the parameters of "
1291-
"overriding initializers", ())
1291+
"default value inheritance via 'super' can only be used on the "
1292+
"parameters of overriding initializers", ())
12921293

12931294
// Alignment attribute
12941295
ERROR(alignment_not_power_of_two,none,

include/swift/Parse/Parser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,9 @@ class Parser {
11431143

11441144
/// The default argument for this parameter.
11451145
Expr *DefaultArg = nullptr;
1146+
1147+
/// True if this parameter inherits a default argument via '= super'
1148+
bool hasInheritedDefaultArg = false;
11461149

11471150
/// True if we emitted a parse error about this parameter.
11481151
bool isInvalid = false;

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,12 +2510,6 @@ void PrintAST::printOneParameter(const ParamDecl *param,
25102510
Printer.printStructurePost(PrintStructureKind::FunctionParameter, param);
25112511
};
25122512

2513-
bool inheritsDefault =
2514-
param->getDefaultArgumentKind() == DefaultArgumentKind::Inherited;
2515-
if (inheritsDefault) {
2516-
Printer << "@_inheritedDefaultValue ";
2517-
}
2518-
25192513
auto printArgName = [&]() {
25202514
// Print argument name.
25212515
auto ArgName = param->getArgumentName();
@@ -2594,7 +2588,7 @@ void PrintAST::printOneParameter(const ParamDecl *param,
25942588
if (param->isVariadic())
25952589
Printer << "...";
25962590

2597-
if (param->isDefaultArgument() && !inheritsDefault) {
2591+
if (param->isDefaultArgument()) {
25982592
SmallString<128> scratch;
25992593
auto defaultArgStr = param->getDefaultValueStringRepresentation(scratch);
26002594

lib/AST/Decl.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5403,6 +5403,7 @@ ParamDecl::getDefaultValueStringRepresentation(
54035403
var->getParentInitializer(),
54045404
scratch);
54055405
}
5406+
case DefaultArgumentKind::Inherited: return "super";
54065407
case DefaultArgumentKind::File: return "#file";
54075408
case DefaultArgumentKind::Line: return "#line";
54085409
case DefaultArgumentKind::Column: return "#column";
@@ -5411,10 +5412,6 @@ ParamDecl::getDefaultValueStringRepresentation(
54115412
case DefaultArgumentKind::NilLiteral: return "nil";
54125413
case DefaultArgumentKind::EmptyArray: return "[]";
54135414
case DefaultArgumentKind::EmptyDictionary: return "[:]";
5414-
case DefaultArgumentKind::Inherited:
5415-
// Inherited default values are set via the @_inheritedDefaultValue
5416-
// attribute, so should be printed in the attribute position
5417-
llvm_unreachable("inherted default should be printed as an attribute");
54185415
}
54195416
llvm_unreachable("unhandled kind");
54205417
}

lib/Parse/ParsePattern.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,22 @@ void Parser::DefaultArgumentInfo::setFunctionContext(
6666

6767
static ParserStatus parseDefaultArgument(
6868
Parser &P, Parser::DefaultArgumentInfo *defaultArgs, unsigned argIndex,
69-
Expr *&init, Parser::ParameterContextKind paramContext) {
69+
Expr *&init, bool &hasInheritedDefaultArg,
70+
Parser::ParameterContextKind paramContext) {
7071
SyntaxParsingContext DefaultArgContext(P.SyntaxContext,
7172
SyntaxKind::InitializerClause);
7273
SourceLoc equalLoc = P.consumeToken(tok::equal);
74+
// Handle the special '= super' syntax for inherited default values in module
75+
// interface files
76+
if (P.SF.Kind == SourceFileKind::Interface) {
77+
if (P.Tok.is(tok::kw_super) && P.peekToken().isAny(tok::comma, tok::r_paren)) {
78+
hasInheritedDefaultArg = true;
79+
P.consumeToken(tok::kw_super);
80+
P.SyntaxContext->createNodeInPlace(SyntaxKind::SuperRefExpr);
81+
defaultArgs->HasDefaultArgument = true;
82+
return ParserStatus();
83+
}
84+
}
7385

7486
// Enter a fresh default-argument context with a meaningless parent.
7587
// We'll change the parent to the function later after we've created
@@ -365,7 +377,9 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
365377
if (Tok.is(tok::equal)) {
366378
SourceLoc EqualLoc = Tok.getLoc();
367379
status |= parseDefaultArgument(*this, defaultArgs, defaultArgIndex,
368-
param.DefaultArg, paramContext);
380+
param.DefaultArg,
381+
param.hasInheritedDefaultArg,
382+
paramContext);
369383

370384
if (param.EllipsisLoc.isValid() && param.DefaultArg) {
371385
// The range of the complete default argument.
@@ -604,7 +618,7 @@ mapParsedParameters(Parser &parser,
604618
}
605619

606620
assert (((!param.DefaultArg &&
607-
!param.Attrs.hasAttribute<InheritedDefaultValueAttr>()) ||
621+
!param.hasInheritedDefaultArg) ||
608622
paramContext == Parser::ParameterContextKind::Function ||
609623
paramContext == Parser::ParameterContextKind::Operator ||
610624
paramContext == Parser::ParameterContextKind::Initializer ||
@@ -616,7 +630,7 @@ mapParsedParameters(Parser &parser,
616630
DefaultArgumentKind kind = getDefaultArgKind(param.DefaultArg);
617631
result->setDefaultArgumentKind(kind);
618632
result->setDefaultValue(param.DefaultArg);
619-
} else if (param.Attrs.hasAttribute<InheritedDefaultValueAttr>()) {
633+
} else if (param.hasInheritedDefaultArg) {
620634
result->setDefaultArgumentKind(DefaultArgumentKind::Inherited);
621635
}
622636

lib/Sema/TypeCheckAttr.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
126126
IGNORED_ATTR(DynamicReplacement)
127127
IGNORED_ATTR(PrivateImport)
128128
IGNORED_ATTR(Custom)
129-
IGNORED_ATTR(InheritedDefaultValue)
130129
#undef IGNORED_ATTR
131130

132131
void visitAlignmentAttr(AlignmentAttr *attr) {
@@ -757,7 +756,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
757756
IGNORED_ATTR(ImplementationOnly)
758757
IGNORED_ATTR(ImplicitlyUnwrappedOptional)
759758
IGNORED_ATTR(Indirect)
760-
IGNORED_ATTR(InheritedDefaultValue)
761759
IGNORED_ATTR(Inline)
762760
IGNORED_ATTR(Lazy) // checked early.
763761
IGNORED_ATTR(LLDBDebuggerFunction)

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,6 @@ namespace {
12981298
UNINTERESTING_ATTR(Specialize)
12991299
UNINTERESTING_ATTR(DynamicReplacement)
13001300
UNINTERESTING_ATTR(PrivateImport)
1301-
UNINTERESTING_ATTR(InheritedDefaultValue)
13021301

13031302
// These can't appear on overridable declarations.
13041303
UNINTERESTING_ATTR(Prefix)

lib/Sema/TypeCheckStmt.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,25 +1748,29 @@ getParamIndex(const ParameterList *paramList, const ParamDecl *decl) {
17481748

17491749
static void
17501750
checkInheritedDefaultValueRestrictions(TypeChecker &TC, ParamDecl *PD) {
1751-
auto *attr = PD->getAttrs().getAttribute<InheritedDefaultValueAttr>();
1752-
if (!attr)
1751+
if (PD->getDefaultArgumentKind() != DefaultArgumentKind::Inherited)
17531752
return;
17541753

17551754
auto *DC = PD->getInnermostDeclContext();
1755+
const SourceFile *SF = DC->getParentSourceFile();
1756+
if (!SF || SF->Kind != SourceFileKind::Interface)
1757+
return;
1758+
17561759
if (!isa<ConstructorDecl>(DC)) {
1757-
TC.diagnose(attr->getLocation(),
1760+
TC.diagnose(PD->getLoc(),
17581761
diag::inherited_default_value_not_on_constructor_param);
1759-
attr->setInvalid();
17601762
return;
17611763
}
17621764

17631765
// Check the matching parameter of an overriden decl has a default value
17641766
auto ctor = cast<ConstructorDecl>(DC);
17651767
Optional<unsigned> idx = getParamIndex(ctor->getParameters(), PD);
1768+
bool foundOverriden = false;
17661769
assert(idx && "containing decl does not contain param?");
17671770
for (auto overridden = ctor->getOverriddenDecl();
17681771
overridden != nullptr;
17691772
overridden = overridden->getOverriddenDecl()) {
1773+
foundOverriden = true;
17701774
auto equivalentParam = overridden->getParameters()->get(*idx);
17711775
assert(equivalentParam && "inherited decl mismatched arguments?");
17721776

@@ -1777,18 +1781,23 @@ checkInheritedDefaultValueRestrictions(TypeChecker &TC, ParamDecl *PD) {
17771781

17781782
// If it doesn't have a default value, diagnose it
17791783
if (equivalentParam->getDefaultArgumentKind() == DefaultArgumentKind::None) {
1780-
TC.diagnose(attr->getLocation(),
1784+
TC.diagnose(PD->getLoc(),
17811785
diag::corresponding_param_not_defaulted);
1782-
attr->setInvalid();
17831786
}
17841787
// We found a match: it's valid
17851788
return;
17861789
}
17871790

1788-
// used on a param of a non-overriding initializer
1789-
TC.diagnose(attr->getLocation(),
1791+
// Used with a param of a non-overriding initializer, or one where the
1792+
// corresponding param in the overridden decl was also inherited but *it*
1793+
// didn't override anything. Diagnose the first case and ignore the second.
1794+
// The second will be diagnosed when checking the default args of the
1795+
// overridden declaration.
1796+
if (foundOverriden)
1797+
return;
1798+
1799+
TC.diagnose(PD->getLoc(),
17901800
diag::inherited_default_value_used_in_non_overriding_constructor);
1791-
attr->setInvalid();
17921801
}
17931802

17941803
/// Check the default arguments that occur within this pattern.

0 commit comments

Comments
 (0)