Skip to content

Commit 6bb36b5

Browse files
committed
Sema: Subscript default arguments
Fixes <https://bugs.swift.org/browse/SR-6118>.
1 parent 043d76a commit 6bb36b5

19 files changed

+308
-44
lines changed

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() {

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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,10 @@ ResilienceExpansion DeclContext::getResilienceExpansion() const {
318318
const ValueDecl *VD;
319319
if (auto *FD = dyn_cast<AbstractFunctionDecl>(dc)) {
320320
VD = FD;
321+
} else if (auto *EED = dyn_cast<EnumElementDecl>(dc)) {
322+
VD = EED;
321323
} else {
322-
VD = cast<EnumElementDecl>(dc);
324+
VD = cast<SubscriptDecl>(dc);
323325
}
324326

325327
auto access =

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/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");

0 commit comments

Comments
 (0)