Sema: Re-visit @specialize attribute where clause in interface resolution stage

As with all other where clauses, we must resolve the requirements twice;
first in structural stage to build the generic signature, and second in
interface stage to check that any generic types that appear within
satisfy requirements. We weren't doing the latter for @specialize, which
would result in SIL crashes if such invalid SIL types appeared therein.

Fixes rdar://165909327.
This commit is contained in:
Slava Pestov
2025-12-05 09:25:33 -05:00
parent bf760aa3dd
commit 459a874f00
3 changed files with 14 additions and 1 deletions

View File

@@ -3590,6 +3590,12 @@ void AttributeChecker::visitAbstractSpecializeAttr(AbstractSpecializeAttr *attr)
}
(void)attr->getSpecializedSignature(FD);
// Force resolution of interface types written in requirements here to check
// that generic types satisfy generic requirements, and so on.
WhereClauseOwner(FD, attr)
.visitRequirements(TypeResolutionStage::Interface,
[](Requirement, RequirementRepr *) { return false; });
}
GenericSignature

View File

@@ -602,7 +602,8 @@ static void checkGenericParams(GenericContext *ownerCtx) {
checkInheritanceClause(gp);
}
// Force resolution of interface types written in requirements here.
// Force resolution of interface types written in requirements here to check
// that generic types satisfy generic requirements, and so on.
WhereClauseOwner(ownerCtx)
.visitRequirements(TypeResolutionStage::Interface,
[](Requirement, RequirementRepr *) { return false; });

View File

@@ -405,3 +405,9 @@ func nonGenericParam2(x: Int) {}
@_specialize(where T == Int)
@_specialize(where T == Int)
func genericParamDuplicate<T>(t: T) {}
struct GG<T: P> {}
// expected-error@+1 {{type 'String' does not conform to protocol 'P'}}
@_specialize(where T == GG<String>)
func genericArgInvalidSpecialize<T>(t: T) {}