Skip to content

Commit ee558fa

Browse files
committed
Sema: Check AnyObject requirements of variadic generic functions
1 parent 3c98e4e commit ee558fa

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3655,6 +3655,19 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
36553655
return getTypeMatchFailure(locator);
36563656
}
36573657

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

36603673
// Handle existential metatypes.
@@ -3671,6 +3684,8 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
36713684
locator.withPathElement(
36723685
ConstraintLocator::InstanceType));
36733686
}
3687+
3688+
return getTypeMatchSuccess();
36743689
}
36753690

36763691
if (!type2->isExistentialType())
@@ -7516,7 +7531,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
75167531
return SolutionKind::Solved;
75177532
}
75187533

7519-
75207534
auto *loc = getConstraintLocator(locator);
75217535

75227536
/// 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)