Skip to content

Commit 8167442

Browse files
authored
Merge pull request #42225 from slavapestov/enable-se-0346-by-default
Enable parameterized protocols by default, and add new staging flag for parameterized existentials
2 parents 767f7b7 + 1bf248e commit 8167442

16 files changed

+128
-123
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,6 @@ ERROR(expected_rbrace_actor,none,
378378
"expected '}' in actor", ())
379379

380380
// Protocol
381-
ERROR(generic_arguments_protocol,PointsToFirstBadToken,
382-
"protocols do not allow generic parameters; use associated types instead",
383-
())
384381
ERROR(expected_lbrace_protocol,PointsToFirstBadToken,
385382
"expected '{' in protocol type", ())
386383
ERROR(expected_rbrace_protocol,none,

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,9 @@ namespace swift {
330330
/// in calls to generic functions.
331331
bool EnableOpenedExistentialTypes = false;
332332

333-
/// Enable support for protocol types parameterized by primary
334-
/// associated type.
335-
bool EnableParameterizedProtocolTypes = false;
333+
/// Enable support for parameterized protocol types in existential
334+
/// position.
335+
bool EnableParameterizedExistentialTypes = false;
336336

337337
/// Enable experimental flow-sensitive concurrent captures.
338338
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,9 @@ def enable_explicit_existential_types :
540540
Flag<["-"], "enable-explicit-existential-types">,
541541
HelpText<"Enable experimental support for explicit existential types">;
542542

543-
def enable_parameterized_protocol_types :
544-
Flag<["-"], "enable-parameterized-protocol-types">,
545-
HelpText<"Enable experimental support for primary associated types and parameterized protocols">;
543+
def enable_parameterized_existential_types :
544+
Flag<["-"], "enable-parameterized-existential-types">,
545+
HelpText<"Enable experimental support for parameterized existential types">;
546546

547547
def enable_experimental_opened_existential_types :
548548
Flag<["-"], "enable-experimental-opened-existential-types">,

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
448448
Opts.EnableExperimentalNamedOpaqueTypes |=
449449
Args.hasArg(OPT_enable_experimental_named_opaque_types);
450450

451-
Opts.EnableParameterizedProtocolTypes |=
452-
Args.hasArg(OPT_enable_parameterized_protocol_types);
451+
Opts.EnableParameterizedExistentialTypes |=
452+
Args.hasArg(OPT_enable_parameterized_existential_types);
453453

454454
Opts.EnableOpenedExistentialTypes =
455455
Args.hasFlag(OPT_enable_experimental_opened_existential_types,

lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8066,19 +8066,8 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
80668066
return Status;
80678067

80688068
SmallVector<PrimaryAssociatedTypeName, 2> PrimaryAssociatedTypeNames;
8069-
8070-
if (Context.LangOpts.EnableParameterizedProtocolTypes) {
8071-
if (startsWithLess(Tok)) {
8072-
Status |= parsePrimaryAssociatedTypes(PrimaryAssociatedTypeNames);
8073-
}
8074-
} else {
8075-
// Protocols don't support generic parameters, but people often want them and
8076-
// we want to have good error recovery if they try them out. Parse them and
8077-
// produce a specific diagnostic if present.
8078-
if (startsWithLess(Tok)) {
8079-
diagnose(Tok, diag::generic_arguments_protocol);
8080-
maybeParseGenericParams();
8081-
}
8069+
if (startsWithLess(Tok)) {
8070+
Status |= parsePrimaryAssociatedTypes(PrimaryAssociatedTypeNames);
80828071
}
80838072

80848073
DebuggerContextChange DCC (*this);

lib/Sema/TypeCheckType.cpp

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -628,50 +628,48 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
628628
auto &ctx = dc->getASTContext();
629629
auto &diags = ctx.Diags;
630630

631-
if (ctx.LangOpts.EnableParameterizedProtocolTypes) {
632-
if (auto *protoType = type->getAs<ProtocolType>()) {
633-
// Build ParameterizedProtocolType if the protocol has a primary associated
634-
// type and we're in a supported context (for now just generic requirements,
635-
// inheritance clause, extension binding).
636-
if (!resolution.getOptions().isParameterizedProtocolSupported()) {
637-
diags.diagnose(loc, diag::parameterized_protocol_not_supported);
638-
return ErrorType::get(ctx);
639-
}
631+
if (auto *protoType = type->getAs<ProtocolType>()) {
632+
// Build ParameterizedProtocolType if the protocol has a primary associated
633+
// type and we're in a supported context (for now just generic requirements,
634+
// inheritance clause, extension binding).
635+
if (!resolution.getOptions().isParameterizedProtocolSupported(ctx.LangOpts)) {
636+
diags.diagnose(loc, diag::parameterized_protocol_not_supported);
637+
return ErrorType::get(ctx);
638+
}
640639

641-
auto *protoDecl = protoType->getDecl();
642-
auto assocTypes = protoDecl->getPrimaryAssociatedTypes();
643-
if (assocTypes.empty()) {
644-
diags.diagnose(loc, diag::protocol_does_not_have_primary_assoc_type,
645-
protoType);
640+
auto *protoDecl = protoType->getDecl();
641+
auto assocTypes = protoDecl->getPrimaryAssociatedTypes();
642+
if (assocTypes.empty()) {
643+
diags.diagnose(loc, diag::protocol_does_not_have_primary_assoc_type,
644+
protoType);
646645

647-
return ErrorType::get(ctx);
648-
}
649-
650-
auto genericArgs = generic->getGenericArgs();
646+
return ErrorType::get(ctx);
647+
}
651648

652-
if (genericArgs.size() != assocTypes.size()) {
653-
diags.diagnose(loc,
654-
diag::parameterized_protocol_type_argument_count_mismatch,
655-
protoType, genericArgs.size(), assocTypes.size(),
656-
(genericArgs.size() < assocTypes.size()) ? 1 : 0);
649+
auto genericArgs = generic->getGenericArgs();
657650

658-
return ErrorType::get(ctx);
659-
}
651+
if (genericArgs.size() != assocTypes.size()) {
652+
diags.diagnose(loc,
653+
diag::parameterized_protocol_type_argument_count_mismatch,
654+
protoType, genericArgs.size(), assocTypes.size(),
655+
(genericArgs.size() < assocTypes.size()) ? 1 : 0);
660656

661-
auto genericResolution =
662-
resolution.withOptions(adjustOptionsForGenericArgs(options));
657+
return ErrorType::get(ctx);
658+
}
663659

664-
SmallVector<Type, 2> argTys;
665-
for (auto *genericArg : genericArgs) {
666-
Type argTy = genericResolution.resolveType(genericArg, silParams);
667-
if (!argTy || argTy->hasError())
668-
return ErrorType::get(ctx);
660+
auto genericResolution =
661+
resolution.withOptions(adjustOptionsForGenericArgs(options));
669662

670-
argTys.push_back(argTy);
671-
}
663+
SmallVector<Type, 2> argTys;
664+
for (auto *genericArg : genericArgs) {
665+
Type argTy = genericResolution.resolveType(genericArg, silParams);
666+
if (!argTy || argTy->hasError())
667+
return ErrorType::get(ctx);
672668

673-
return ParameterizedProtocolType::get(ctx, protoType, argTys);
669+
argTys.push_back(argTy);
674670
}
671+
672+
return ParameterizedProtocolType::get(ctx, protoType, argTys);
675673
}
676674

677675
// We must either have an unbound generic type, or a generic type alias.

lib/Sema/TypeCheckType.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/Type.h"
2020
#include "swift/AST/Types.h"
2121
#include "swift/AST/TypeResolutionStage.h"
22+
#include "swift/Basic/LangOptions.h"
2223
#include "llvm/ADT/None.h"
2324

2425
namespace swift {
@@ -277,13 +278,17 @@ class TypeResolutionOptions {
277278
}
278279

279280
/// Whether parameterized protocol types are supported in this context.
280-
bool isParameterizedProtocolSupported() const {
281+
///
282+
/// FIXME: Remove LangOptions parameter once EnableParameterizedExistentialTypes
283+
/// staging flag is gone.
284+
bool isParameterizedProtocolSupported(const LangOptions &opts) const {
281285
switch (context) {
282286
case Context::Inherited:
283287
case Context::ExtensionBinding:
284288
case Context::GenericRequirement:
285-
case Context::ExistentialConstraint:
286289
return true;
290+
case Context::ExistentialConstraint:
291+
return opts.EnableParameterizedExistentialTypes;
287292
case Context::None:
288293
case Context::TypeAliasDecl:
289294
case Context::GenericTypeAliasDecl:

test/Constraints/opened_existentials.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -enable-experimental-opened-existential-types -enable-parameterized-protocol-types
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-opened-existential-types
22

33
protocol Q { }
44

test/ModuleInterface/parameterized-protocols.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -typecheck -module-name ParameterizedProtocols -emit-module-interface-path %t/ParameterizedProtocols.swiftinterface -enable-parameterized-protocol-types %s
2+
// RUN: %target-swift-frontend -typecheck -module-name ParameterizedProtocols -emit-module-interface-path %t/ParameterizedProtocols.swiftinterface %s
33
// RUN: %FileCheck %s < %t/ParameterizedProtocols.swiftinterface
44

55
public protocol HasPrimaryAssociatedTypes<T, U> {

test/Parse/invalid.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func d(_ b: String -> <T>() -> T) {} // expected-error {{expected type for funct
6767

6868

6969
// <rdar://problem/22143680> QoI: terrible diagnostic when trying to form a generic protocol
70-
protocol Animal<Food> { // expected-error {{protocols do not allow generic parameters; use associated types instead}}
70+
protocol Animal<Food> { // expected-error {{an associated type named 'Food' must be declared in the protocol 'Animal' or a protocol it inherits}}
7171
func feed(_ food: Food) // expected-error {{cannot find type 'Food' in scope}}
7272
}
7373

0 commit comments

Comments
 (0)