Skip to content

Commit c34f8d3

Browse files
committed
Sema: Check AnyObject requirements of variadic generic functions
1 parent f3fcc44 commit c34f8d3

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3659,6 +3659,19 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
36593659
return getTypeMatchFailure(locator);
36603660
}
36613661

3662+
// ConformsTo constraints are generated when opening a generic
3663+
// signature with a RequirementKind::Conformance requirement, so
3664+
// we must handle pack types on the left by splitting up into
3665+
// smaller constraints.
3666+
if (auto *packType = type1->getAs<PackType>()) {
3667+
for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
3668+
addConstraint(kind, packType->getElementType(i), type2,
3669+
locator.withPathElement(LocatorPathElt::PackElement(i)));
3670+
}
3671+
3672+
return getTypeMatchSuccess();
3673+
}
3674+
36623675
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
36633676

36643677
// Handle existential metatypes.
@@ -7522,7 +7535,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
75227535
return SolutionKind::Solved;
75237536
}
75247537

7525-
75267538
auto *loc = getConstraintLocator(locator);
75277539

75287540
/// Record the given conformance as the result, adding any conditional

test/Constraints/variadic_generic_constraints.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// Test instantiation of constraint solver constraints from generic requirements
44
// involving type pack parameters
55

6+
// Conformance requirements
7+
68
protocol P {}
79

810
func takesP<T...: P>(_: T...) {} // expected-note {{where 'T' = 'DoesNotConformToP'}}
@@ -13,9 +15,10 @@ struct DoesNotConformToP {}
1315
takesP() // ok
1416
takesP(ConformsToP(), ConformsToP(), ConformsToP()) // ok
1517

16-
// FIXME: Bad diagnostic
1718
takesP(ConformsToP(), DoesNotConformToP(), ConformsToP()) // expected-error {{global function 'takesP' requires that 'DoesNotConformToP' conform to 'P'}}
1819

20+
// Superclass requirements
21+
1922
class C {}
2023

2124
class SubclassOfC: C {}
@@ -28,6 +31,20 @@ takesC(SubclassOfC(), SubclassOfC(), SubclassOfC()) // ok
2831

2932
takesC(SubclassOfC(), NotSubclassOfC(), SubclassOfC()) // expected-error {{global function 'takesC' requires that 'NotSubclassOfC' inherit from 'C'}}
3033

34+
// Layout requirements
35+
36+
struct S {}
37+
38+
func takesAnyObject<T...: AnyObject>(_: T...) {}
39+
40+
takesAnyObject()
41+
takesAnyObject(C(), C(), C())
42+
43+
// FIXME: Bad diagnostic
44+
takesAnyObject(C(), S(), C()) // expected-error {{type of expression is ambiguous without more context}}
45+
46+
// Same-type requirements
47+
3148
func takesParallelSequences<T..., U...>(t: T..., u: U...) where T: Sequence, U: Sequence, T.Element == U.Element {}
3249
// expected-note@-1 {{where 'T.Element' = 'String', 'U.Element' = 'Int'}}
3350

0 commit comments

Comments
 (0)