Skip to content

Commit c023e0f

Browse files
authored
Merge pull request #23734 from slavapestov/subscript-default-arguments
Subscript default arguments
2 parents 1395c25 + 560d3ad commit c023e0f

29 files changed

+345
-293
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -393,16 +393,11 @@ class alignas(1 << DeclAlignInBits) Decl {
393393
/// Information about a symbolic default argument, like #file.
394394
defaultArgumentKind : NumDefaultArgumentKindBits
395395
);
396-
396+
397397
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
398398
StaticSpelling : 2
399399
);
400400

401-
SWIFT_INLINE_BITFIELD(EnumElementDecl, ValueDecl, 1,
402-
/// The ResilienceExpansion to use for default arguments.
403-
DefaultArgumentResilienceExpansion : 1
404-
);
405-
406401
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1+1,
407402
/// \see AbstractFunctionDecl::BodyKind
408403
BodyKind : 3,
@@ -425,9 +420,6 @@ class alignas(1 << DeclAlignInBits) Decl {
425420
/// Whether NeedsNewVTableEntry is valid.
426421
HasComputedNeedsNewVTableEntry : 1,
427422

428-
/// The ResilienceExpansion to use for default arguments.
429-
DefaultArgumentResilienceExpansion : 1,
430-
431423
/// Whether this member was synthesized as part of a derived
432424
/// protocol conformance.
433425
Synthesized : 1
@@ -5307,8 +5299,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
53075299
Bits.AbstractFunctionDecl.Throws = Throws;
53085300
Bits.AbstractFunctionDecl.NeedsNewVTableEntry = false;
53095301
Bits.AbstractFunctionDecl.HasComputedNeedsNewVTableEntry = false;
5310-
Bits.AbstractFunctionDecl.DefaultArgumentResilienceExpansion =
5311-
unsigned(ResilienceExpansion::Maximal);
53125302
Bits.AbstractFunctionDecl.Synthesized = false;
53135303
}
53145304

@@ -5556,21 +5546,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
55565546
/// Resolved during type checking
55575547
void setIsOverridden() { Bits.AbstractFunctionDecl.Overridden = true; }
55585548

5559-
/// The ResilienceExpansion for default arguments.
5560-
///
5561-
/// In Swift 4 mode, default argument expressions are serialized, and must
5562-
/// obey the restrictions imposed upon inlinable function bodies.
5563-
ResilienceExpansion getDefaultArgumentResilienceExpansion() const {
5564-
return ResilienceExpansion(
5565-
Bits.AbstractFunctionDecl.DefaultArgumentResilienceExpansion);
5566-
}
5567-
5568-
/// Set the ResilienceExpansion for default arguments.
5569-
void setDefaultArgumentResilienceExpansion(ResilienceExpansion expansion) {
5570-
Bits.AbstractFunctionDecl.DefaultArgumentResilienceExpansion =
5571-
unsigned(expansion);
5572-
}
5573-
55745549
/// Set information about the foreign error convention used by this
55755550
/// declaration.
55765551
void setForeignErrorConvention(const ForeignErrorConvention &convention);
@@ -6025,10 +6000,7 @@ class EnumElementDecl : public DeclContext, public ValueDecl {
60256000
Params(Params),
60266001
EqualsLoc(EqualsLoc),
60276002
RawValueExpr(RawValueExpr)
6028-
{
6029-
Bits.EnumElementDecl.DefaultArgumentResilienceExpansion =
6030-
static_cast<unsigned>(ResilienceExpansion::Maximal);
6031-
}
6003+
{}
60326004

60336005
Identifier getName() const { return getFullName().getBaseIdentifier(); }
60346006

@@ -6057,21 +6029,6 @@ class EnumElementDecl : public DeclContext, public ValueDecl {
60576029
TypeCheckedRawValueExpr = e;
60586030
}
60596031

6060-
/// The ResilienceExpansion for default arguments.
6061-
///
6062-
/// In Swift 4 mode, default argument expressions are serialized, and must
6063-
/// obey the restrictions imposed upon inlinable function bodies.
6064-
ResilienceExpansion getDefaultArgumentResilienceExpansion() const {
6065-
return ResilienceExpansion(
6066-
Bits.EnumElementDecl.DefaultArgumentResilienceExpansion);
6067-
}
6068-
6069-
/// Set the ResilienceExpansion for default arguments.
6070-
void setDefaultArgumentResilienceExpansion(ResilienceExpansion expansion) {
6071-
Bits.EnumElementDecl.DefaultArgumentResilienceExpansion =
6072-
unsigned(expansion);
6073-
}
6074-
60756032
/// Return the containing EnumDecl.
60766033
EnumDecl *getParentEnum() const {
60776034
return cast<EnumDecl>(getDeclContext());

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,6 @@ ERROR(untyped_pattern_ellipsis,none,
821821
"'...' cannot be applied to a subpattern which is not explicitly typed", ())
822822
ERROR(no_default_arg_closure,none,
823823
"default arguments are not allowed in closures", ())
824-
ERROR(no_default_arg_subscript,none,
825-
"default arguments are not allowed in subscripts", ())
826824
ERROR(no_default_arg_curried,none,
827825
"default arguments are not allowed in curried parameter lists", ())
828826
ERROR(var_pattern_in_var,none,

include/swift/Parse/Parser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,8 +1098,8 @@ class Parser {
10981098
/// all the arguments, not just those that have default arguments.
10991099
unsigned claimNextIndex() { return NextIndex++; }
11001100

1101-
/// Set the parsed context for all the initializers to the given
1102-
/// function.
1101+
/// Set the parsed context of all default argument initializers to
1102+
/// the given function, enum case or subscript.
11031103
void setFunctionContext(DeclContext *DC, ParameterList *paramList);
11041104

11051105
DefaultArgumentInfo() {

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 482; // static subscripts
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 483; // Remove default arg expansion
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1002,7 +1002,6 @@ namespace decls_block {
10021002
DeclIDField, // overridden decl
10031003
AccessLevelField, // access level
10041004
BCFixed<1>, // requires a new vtable slot
1005-
BCFixed<1>, // default argument resilience expansion
10061005
BCFixed<1>, // 'required' but overridden is not (used for recovery)
10071006
BCVBR<5>, // number of parameter name components
10081007
BCArray<IdentifierIDField> // name components,
@@ -1069,7 +1068,6 @@ namespace decls_block {
10691068
// components plus one
10701069
AccessLevelField, // access level
10711070
BCFixed<1>, // requires a new vtable slot
1072-
BCFixed<1>, // default argument resilience expansion
10731071
BCArray<IdentifierIDField> // name components,
10741072
// followed by TypeID dependencies
10751073
// The record is trailed by:
@@ -1099,7 +1097,6 @@ namespace decls_block {
10991097
AccessorKindField, // accessor kind
11001098
AccessLevelField, // access level
11011099
BCFixed<1>, // requires a new vtable slot
1102-
BCFixed<1>, // default argument resilience expansion
11031100
BCArray<IdentifierIDField> // name components,
11041101
// followed by TypeID dependencies
11051102
// The record is trailed by:
@@ -1158,7 +1155,6 @@ namespace decls_block {
11581155
EnumElementRawValueKindField, // raw value kind
11591156
BCFixed<1>, // negative raw value?
11601157
IdentifierIDField, // raw value
1161-
BCFixed<1>, // default argument resilience expansion
11621158
BCVBR<5>, // number of parameter name components
11631159
BCArray<IdentifierIDField> // name components,
11641160

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ class Verifier : public ASTWalker {
761761
FUNCTION_LIKE(DestructorDecl)
762762
FUNCTION_LIKE(FuncDecl)
763763
FUNCTION_LIKE(EnumElementDecl)
764+
FUNCTION_LIKE(SubscriptDecl)
764765
SCOPE_LIKE(NominalTypeDecl)
765766
SCOPE_LIKE(ExtensionDecl)
766767

lib/AST/Decl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5551,8 +5551,10 @@ const ParamDecl *swift::getParameterAt(ValueDecl *source, unsigned index) {
55515551
const ParameterList *paramList;
55525552
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(source)) {
55535553
paramList = AFD->getParameters();
5554+
} else if (auto *EED = dyn_cast<EnumElementDecl>(source)) {
5555+
paramList = EED->getParameterList();
55545556
} else {
5555-
paramList = cast<EnumElementDecl>(source)->getParameterList();
5557+
paramList = cast<SubscriptDecl>(source)->getIndices();
55565558
}
55575559

55585560
return paramList->get(index);

lib/AST/DeclContext.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,25 @@ ResilienceExpansion DeclContext::getResilienceExpansion() const {
313313
// Default argument initializer contexts have their resilience expansion
314314
// set when they're type checked.
315315
if (isa<DefaultArgumentInitializer>(dc)) {
316-
if (auto *EED = dyn_cast<EnumElementDecl>(dc->getParent())) {
317-
return EED->getDefaultArgumentResilienceExpansion();
316+
dc = dc->getParent();
317+
318+
const ValueDecl *VD;
319+
if (auto *FD = dyn_cast<AbstractFunctionDecl>(dc)) {
320+
VD = FD;
321+
} else if (auto *EED = dyn_cast<EnumElementDecl>(dc)) {
322+
VD = EED;
323+
} else {
324+
VD = cast<SubscriptDecl>(dc);
318325
}
319-
return cast<AbstractFunctionDecl>(dc->getParent())
320-
->getDefaultArgumentResilienceExpansion();
326+
327+
auto access =
328+
VD->getFormalAccessScope(/*useDC=*/nullptr,
329+
/*treatUsableFromInlineAsPublic=*/true);
330+
331+
if (access.isPublic())
332+
return ResilienceExpansion::Minimal;
333+
334+
return ResilienceExpansion::Maximal;
321335
}
322336

323337
// Stored property initializer contexts use minimal resilience expansion

lib/Parse/ParseDecl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6364,10 +6364,11 @@ Parser::parseDeclSubscript(ParseDeclOptions Flags,
63646364
return makeParserCodeCompletionStatus();
63656365

63666366
// Parse the parameter list.
6367+
DefaultArgumentInfo DefaultArgs;
63676368
SmallVector<Identifier, 4> argumentNames;
63686369
ParserResult<ParameterList> Indices
63696370
= parseSingleParameterClause(ParameterContextKind::Subscript,
6370-
&argumentNames);
6371+
&argumentNames, &DefaultArgs);
63716372
Status |= Indices;
63726373

63736374
SignatureHasCodeCompletion |= Indices.hasCodeCompletion();
@@ -6419,6 +6420,8 @@ Parser::parseDeclSubscript(ParseDeclOptions Flags,
64196420
nullptr);
64206421
Subscript->getAttrs() = Attributes;
64216422

6423+
DefaultArgs.setFunctionContext(Subscript, Subscript->getIndices());
6424+
64226425
// Parse a 'where' clause if present, adding it to our GenericParamList.
64236426
if (Tok.is(tok::kw_where)) {
64246427
ContextChange CC(*this, Subscript);

lib/Parse/ParsePattern.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,11 @@ static ParserStatus parseDefaultArgument(
9292
case Parser::ParameterContextKind::Operator:
9393
case Parser::ParameterContextKind::Initializer:
9494
case Parser::ParameterContextKind::EnumElement:
95+
case Parser::ParameterContextKind::Subscript:
9596
break;
9697
case Parser::ParameterContextKind::Closure:
9798
diagID = diag::no_default_arg_closure;
9899
break;
99-
case Parser::ParameterContextKind::Subscript:
100-
diagID = diag::no_default_arg_subscript;
101-
break;
102100
case Parser::ParameterContextKind::Curried:
103101
diagID = diag::no_default_arg_curried;
104102
break;
@@ -609,7 +607,8 @@ mapParsedParameters(Parser &parser,
609607
assert((paramContext == Parser::ParameterContextKind::Function ||
610608
paramContext == Parser::ParameterContextKind::Operator ||
611609
paramContext == Parser::ParameterContextKind::Initializer ||
612-
paramContext == Parser::ParameterContextKind::EnumElement) &&
610+
paramContext == Parser::ParameterContextKind::EnumElement ||
611+
paramContext == Parser::ParameterContextKind::Subscript) &&
613612
"Default arguments are only permitted on the first param clause");
614613
DefaultArgumentKind kind = getDefaultArgKind(param.DefaultArg);
615614
result->setDefaultArgumentKind(kind);

lib/SIL/SILDeclRef.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -476,19 +476,13 @@ IsSerialized_t SILDeclRef::isSerialized() const {
476476
// Default argument generators are serialized if the containing
477477
// declaration is public.
478478
if (isDefaultArgGenerator()) {
479-
ResilienceExpansion expansion;
480-
if (auto *EED = dyn_cast<EnumElementDecl>(d)) {
481-
expansion = EED->getDefaultArgumentResilienceExpansion();
482-
} else {
483-
expansion = cast<AbstractFunctionDecl>(d)
484-
->getDefaultArgumentResilienceExpansion();
485-
}
486-
switch (expansion) {
487-
case ResilienceExpansion::Minimal:
479+
auto scope =
480+
d->getFormalAccessScope(/*useDC=*/nullptr,
481+
/*treatUsableFromInlineAsPublic=*/true);
482+
483+
if (scope.isPublic())
488484
return IsSerialized;
489-
case ResilienceExpansion::Maximal:
490-
return IsNotSerialized;
491-
}
485+
return IsNotSerialized;
492486
}
493487

494488
// Stored property initializers are inlinable if the type is explicitly

lib/SIL/TypeLowering.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,9 +1755,14 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
17551755
}
17561756

17571757
// Get the generic signature from the surrounding context.
1758-
auto funcInfo = TC.getConstantInfo(SILDeclRef(VD));
1759-
return CanAnyFunctionType::get(funcInfo.FormalType.getOptGenericSignature(),
1760-
{}, canResultTy);
1758+
CanGenericSignature sig;
1759+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(VD)) {
1760+
auto funcInfo = TC.getConstantInfo(SILDeclRef(VD));
1761+
sig = funcInfo.FormalType.getOptGenericSignature();
1762+
} else {
1763+
sig = TC.getEffectiveGenericSignature(DC);
1764+
}
1765+
return CanAnyFunctionType::get(sig, {}, canResultTy);
17611766
}
17621767

17631768
/// Get the type of a stored property initializer, () -> T.
@@ -1940,7 +1945,8 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
19401945
return getGlobalAccessorType(var->getInterfaceType()->getCanonicalType());
19411946
}
19421947
case SILDeclRef::Kind::DefaultArgGenerator:
1943-
return getDefaultArgGeneratorInterfaceType(*this, vd, vd->getDeclContext(),
1948+
return getDefaultArgGeneratorInterfaceType(*this, vd,
1949+
vd->getInnermostDeclContext(),
19441950
c.defaultArgIndex);
19451951
case SILDeclRef::Kind::StoredPropertyInitializer:
19461952
return getStoredPropertyInitializerInterfaceType(*this,
@@ -1995,7 +2001,10 @@ TypeConverter::getConstantGenericEnvironment(SILDeclRef c) {
19952001
return cast<ClassDecl>(vd)->getGenericEnvironmentOfContext();
19962002
case SILDeclRef::Kind::DefaultArgGenerator:
19972003
// Use the generic environment of the original function.
1998-
return getConstantGenericEnvironment(SILDeclRef(c.getDecl()));
2004+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(c.getDecl()))
2005+
return getConstantGenericEnvironment(SILDeclRef(c.getDecl()));
2006+
return c.getDecl()->getInnermostDeclContext()
2007+
->getGenericEnvironmentOfContext();
19992008
case SILDeclRef::Kind::StoredPropertyInitializer:
20002009
// Use the generic environment of the containing type.
20012010
return c.getDecl()->getDeclContext()->getGenericEnvironmentOfContext();

lib/SILGen/SILGenFunction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ DeclName SILGenModule::getMagicFunctionName(DeclContext *dc) {
100100
if (auto EED = dyn_cast<EnumElementDecl>(dc)) {
101101
return EED->getFullName();
102102
}
103+
if (auto SD = dyn_cast<SubscriptDecl>(dc)) {
104+
return SD->getFullName();
105+
}
103106
llvm_unreachable("unexpected #function context");
104107
}
105108

lib/SILGen/SILGenType.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,12 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
10441044
visitAbstractStorageDecl(vd);
10451045
}
10461046

1047+
void visitSubscriptDecl(SubscriptDecl *sd) {
1048+
SGM.emitDefaultArgGenerators(sd, sd->getIndices());
1049+
1050+
visitAbstractStorageDecl(sd);
1051+
}
1052+
10471053
void visitAbstractStorageDecl(AbstractStorageDecl *asd) {
10481054
// FIXME: Default implementations in protocols.
10491055
if (asd->isObjC() && !isa<ProtocolDecl>(asd->getDeclContext()))
@@ -1154,6 +1160,11 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
11541160
visitAbstractStorageDecl(vd);
11551161
}
11561162

1163+
void visitSubscriptDecl(SubscriptDecl *sd) {
1164+
SGM.emitDefaultArgGenerators(sd, sd->getIndices());
1165+
visitAbstractStorageDecl(sd);
1166+
}
1167+
11571168
void visitEnumCaseDecl(EnumCaseDecl *ecd) {}
11581169
void visitEnumElementDecl(EnumElementDecl *ed) {
11591170
llvm_unreachable("enum elements aren't allowed in extensions");

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5290,8 +5290,7 @@ Expr *ExprRewriter::coerceCallArguments(
52905290
findCalleeDeclRef(cs, solution, cs.getConstraintLocator(locator));
52915291

52925292
// Determine whether this application has curried self.
5293-
bool skipCurriedSelf = apply ? hasCurriedSelf(cs, callee, apply) : false;
5294-
5293+
bool skipCurriedSelf = apply ? hasCurriedSelf(cs, callee, apply) : true;
52955294
// Determine the parameter bindings.
52965295
SmallBitVector defaultMap
52975296
= computeDefaultMap(params, callee.getDecl(), skipCurriedSelf);

0 commit comments

Comments
 (0)