Skip to content

Commit 33ab33a

Browse files
committed
Sema: Diagnose parametrized protocol types in unsupported contexts
1 parent 2ad4089 commit 33ab33a

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3714,6 +3714,8 @@ ERROR(not_a_generic_definition,none,
37143714
"cannot specialize a non-generic definition", ())
37153715
ERROR(not_a_generic_type,none,
37163716
"cannot specialize non-generic type %0", (Type))
3717+
ERROR(parametrized_protocol_not_supported,none,
3718+
"protocol type with generic argument can only be used as a generic constraint", ())
37173719
ERROR(protocol_does_not_have_primary_assoc_type,none,
37183720
"cannot specialize protocol type %0", (Type))
37193721
ERROR(protocol_cannot_have_multiple_generic_arguments,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,9 +625,15 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
625625
auto &diags = ctx.Diags;
626626

627627
if (ctx.LangOpts.EnableParametrizedProtocolTypes) {
628-
// Build ParametrizedProtocolType if the protocol has a primary associated
629-
// type.
630628
if (auto *protoType = type->getAs<ProtocolType>()) {
629+
// Build ParametrizedProtocolType if the protocol has a primary associated
630+
// type and we're in a supported context (for now just generic requirements,
631+
// inheritance clause, extension binding).
632+
if (!resolution.getOptions().isParametrizedProtocolSupported()) {
633+
diags.diagnose(loc, diag::parametrized_protocol_not_supported);
634+
return ErrorType::get(ctx);
635+
}
636+
631637
auto *protoDecl = protoType->getDecl();
632638
if (protoDecl->getPrimaryAssociatedType() == nullptr) {
633639
diags.diagnose(loc, diag::protocol_does_not_have_primary_assoc_type,

lib/Sema/TypeCheckType.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class TypeResolutionOptions {
250250
case Context::TypeAliasDecl:
251251
case Context::GenericTypeAliasDecl:
252252
case Context::GenericRequirement:
253+
case Context::ExistentialConstraint:
253254
case Context::MetatypeBase:
254255
return false;
255256
case Context::None:
@@ -275,6 +276,40 @@ class TypeResolutionOptions {
275276
}
276277
}
277278

279+
/// Whether parametrized protocol types are supported in this context.
280+
bool isParametrizedProtocolSupported() const {
281+
switch (context) {
282+
case Context::Inherited:
283+
case Context::ExtensionBinding:
284+
case Context::GenericRequirement:
285+
return true;
286+
case Context::None:
287+
case Context::TypeAliasDecl:
288+
case Context::GenericTypeAliasDecl:
289+
case Context::MetatypeBase:
290+
case Context::ExistentialConstraint:
291+
case Context::InExpression:
292+
case Context::ExplicitCastExpr:
293+
case Context::ForEachStmt:
294+
case Context::PatternBindingDecl:
295+
case Context::EditorPlaceholderExpr:
296+
case Context::ClosureExpr:
297+
case Context::FunctionInput:
298+
case Context::VariadicFunctionInput:
299+
case Context::InoutFunctionInput:
300+
case Context::FunctionResult:
301+
case Context::SubscriptDecl:
302+
case Context::EnumElementDecl:
303+
case Context::EnumPatternPayload:
304+
case Context::SameTypeRequirement:
305+
case Context::ProtocolMetatypeBase:
306+
case Context::ImmediateOptionalTypeArgument:
307+
case Context::AbstractFunctionDecl:
308+
case Context::CustomAttr:
309+
return false;
310+
}
311+
}
312+
278313
/// Determine whether all of the given options are set.
279314
bool contains(TypeResolutionFlags set) const {
280315
return !static_cast<bool>(unsigned(set) & ~unsigned(flags));

0 commit comments

Comments
 (0)