Skip to content

Commit 3aa8248

Browse files
committed
Sema: Realize ParametrizedProtocolType
1 parent dcadc0d commit 3aa8248

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3712,6 +3712,10 @@ ERROR(not_a_generic_definition,none,
37123712
"cannot specialize a non-generic definition", ())
37133713
ERROR(not_a_generic_type,none,
37143714
"cannot specialize non-generic type %0", (Type))
3715+
ERROR(protocol_does_not_have_primary_assoc_type,none,
3716+
"cannot specialize protocol type %0", (Type))
3717+
ERROR(protocol_cannot_have_multiple_generic_arguments,none,
3718+
"protocol type %0 can only be specialized with exactly one argument", (Type))
37153719
ERROR(cannot_specialize_self,none,
37163720
"cannot specialize 'Self'", ())
37173721
NOTE(specialize_explicit_type_instead,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,38 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
624624
auto &ctx = dc->getASTContext();
625625
auto &diags = ctx.Diags;
626626

627+
if (ctx.LangOpts.EnableParametrizedProtocolTypes) {
628+
// Build ParametrizedProtocolType if the protocol has a primary associated
629+
// type.
630+
if (auto *protoType = type->getAs<ProtocolType>()) {
631+
auto *protoDecl = protoType->getDecl();
632+
if (protoDecl->getPrimaryAssociatedType() == nullptr) {
633+
diags.diagnose(loc, diag::protocol_does_not_have_primary_assoc_type,
634+
protoType);
635+
636+
return ErrorType::get(ctx);
637+
}
638+
639+
auto genericArgs = generic->getGenericArgs();
640+
641+
if (genericArgs.size() != 1) {
642+
diags.diagnose(loc, diag::protocol_cannot_have_multiple_generic_arguments,
643+
protoType);
644+
645+
return ErrorType::get(ctx);
646+
}
647+
648+
auto genericResolution =
649+
resolution.withOptions(adjustOptionsForGenericArgs(options));
650+
651+
Type argTy = genericResolution.resolveType(genericArgs[0], silParams);
652+
if (!argTy || argTy->hasError())
653+
return ErrorType::get(ctx);
654+
655+
return ParametrizedProtocolType::get(ctx, protoType, argTy);
656+
}
657+
}
658+
627659
// We must either have an unbound generic type, or a generic type alias.
628660
if (!type->is<UnboundGenericType>()) {
629661
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {

0 commit comments

Comments
 (0)