Skip to content

Commit be65895

Browse files
committed
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.
1 parent d4ae238 commit be65895

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3590,6 +3590,12 @@ void AttributeChecker::visitAbstractSpecializeAttr(AbstractSpecializeAttr *attr)
35903590
}
35913591

35923592
(void)attr->getSpecializedSignature(FD);
3593+
3594+
// Force resolution of interface types written in requirements here to check
3595+
// that generic types satisfy generic requirements, and so on.
3596+
WhereClauseOwner(FD, attr)
3597+
.visitRequirements(TypeResolutionStage::Interface,
3598+
[](Requirement, RequirementRepr *) { return false; });
35933599
}
35943600

35953601
GenericSignature

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,8 @@ static void checkGenericParams(GenericContext *ownerCtx) {
602602
checkInheritanceClause(gp);
603603
}
604604

605-
// Force resolution of interface types written in requirements here.
605+
// Force resolution of interface types written in requirements here to check
606+
// that generic types satisfy generic requirements, and so on.
606607
WhereClauseOwner(ownerCtx)
607608
.visitRequirements(TypeResolutionStage::Interface,
608609
[](Requirement, RequirementRepr *) { return false; });

test/attr/attr_specialize.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,3 +405,9 @@ func nonGenericParam2(x: Int) {}
405405
@_specialize(where T == Int)
406406
@_specialize(where T == Int)
407407
func genericParamDuplicate<T>(t: T) {}
408+
409+
struct GG<T: P> {}
410+
411+
// expected-error@+1 {{type 'String' does not conform to protocol 'P'}}
412+
@_specialize(where T == GG<String>)
413+
func genericArgInvalidSpecialize<T>(t: T) {}

0 commit comments

Comments
 (0)