Skip to content

Commit 3c98e4e

Browse files
committed
Sema: Handle PackElement locator in repairFailures()
1 parent 5ce17a1 commit 3c98e4e

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5877,6 +5877,19 @@ bool ConstraintSystem::repairFailures(
58775877
break;
58785878
}
58795879

5880+
case ConstraintLocator::PackElement: {
5881+
path.pop_back();
5882+
5883+
if (!path.empty() && path.back().is<LocatorPathElt::PackType>())
5884+
path.pop_back();
5885+
5886+
if (!path.empty() && path.back().is<LocatorPathElt::PackType>())
5887+
path.pop_back();
5888+
5889+
return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
5890+
getConstraintLocator(anchor, path));
5891+
}
5892+
58805893
case ConstraintLocator::SequenceElementType: {
58815894
// This is going to be diagnosed as `missing conformance`,
58825895
// so no need to create duplicate fixes.

lib/Sema/ConstraintSystem.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6708,7 +6708,14 @@ SourceRange constraints::getSourceRange(ASTNode anchor) {
67086708

67096709
static Optional<Requirement> getRequirement(ConstraintSystem &cs,
67106710
ConstraintLocator *reqLocator) {
6711-
auto reqLoc = reqLocator->getLastElementAs<LocatorPathElt::AnyRequirement>();
6711+
ArrayRef<LocatorPathElt> path = reqLocator->getPath();
6712+
6713+
// If we have something like ... -> type req # -> pack element #, we're
6714+
// solving a requirement of the form T : P where T is a type parameter pack
6715+
if (path.back().is<LocatorPathElt::PackElement>())
6716+
path = path.drop_back();
6717+
6718+
auto reqLoc = path.back().getAs<LocatorPathElt::AnyRequirement>();
67126719
if (!reqLoc)
67136720
return None;
67146721

test/Constraints/variadic_generic_constraints.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,12 @@ func takesC<T...: C>(_: T...) {} // expected-note {{where 'T' = 'NotSubclassOfC
2626
takesC() // ok
2727
takesC(SubclassOfC(), SubclassOfC(), SubclassOfC()) // ok
2828

29-
takesC(SubclassOfC(), NotSubclassOfC(), SubclassOfC()) // expected-error {{global function 'takesC' requires that 'NotSubclassOfC' inherit from 'C'}}
29+
takesC(SubclassOfC(), NotSubclassOfC(), SubclassOfC()) // expected-error {{global function 'takesC' requires that 'NotSubclassOfC' inherit from 'C'}}
30+
31+
func takesParallelSequences<T..., U...>(t: T..., u: U...) where T: Sequence, U: Sequence, T.Element == U.Element {}
32+
// expected-note@-1 {{where 'T.Element' = 'String', 'U.Element' = 'Int'}}
33+
34+
takesParallelSequences() // ok
35+
takesParallelSequences(t: Array<Int>(), u: Set<Int>()) // ok
36+
takesParallelSequences(t: Array<String>(), Set<Int>(), u: Set<String>(), Array<Int>()) // ok
37+
takesParallelSequences(t: Array<String>(), Set<Int>(), u: Array<Int>(), Set<String>()) // expected-error {{global function 'takesParallelSequences(t:u:)' requires the types 'String' and 'Int' be equivalent}}

0 commit comments

Comments
 (0)