Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2229,7 +2229,7 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,

SmallVector<unsigned, 4> mismatches;
auto result = matchDeepTypeArguments(
*this, subflags, args1, args2, locator,
*this, subflags | TMF_ApplyingFix, args1, args2, locator,
[&mismatches](unsigned position) { mismatches.push_back(position); });

if (mismatches.empty())
Expand Down Expand Up @@ -4270,6 +4270,24 @@ bool ConstraintSystem::repairFailures(
break;
}

case ConstraintLocator::GenericArgument: {
// If any of the types is a hole, consider it fixed.
if (lhs->isHole() || rhs->isHole())
return true;

// Ignoring the generic argument because we may have a generic requirement
// failure e.g. `String bind T.Element`, so let's drop the generic argument
// path element and recurse in repairFailures to check and potentially
// record the requirement failure fix.
path.pop_back();

if (path.empty() || !path.back().is<LocatorPathElt::AnyRequirement>())
break;

return repairFailures(lhs, rhs, matchKind, conversionsOrFixes,
getConstraintLocator(anchor, path));
}

default:
break;
}
Expand Down
21 changes: 21 additions & 0 deletions test/Generics/sr13226.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %target-typecheck-verify-swift
struct W<T> {}

struct S<C1: Collection> {
init(){}
// expected-note@+2 {{where 'C1.Element' = 'String', 'W<C2.Element>' = 'Int'}}
// expected-note@+1 {{where 'C1.Element' = 'C1', 'W<C2.Element>' = 'C2.Element'}}
init<C2>(_ c2: W<C2>) where C2: Collection, C1.Element == W<C2.Element> {}
// expected-note@+1 {{where 'C1.Element' = 'String', 'W<C2.Element>' = 'Int'}}
static func f<C2>(_ c2: W<C2>) where C2: Collection, C1.Element == W<C2.Element> {}
// expected-note@+1 {{where 'C1.Element' = 'String', 'W<C2.Element>' = 'Int'}}
func instancef<C2>(_ c2: W<C2>) where C2: Collection, C1.Element == W<C2.Element> {}
}
let _ = S<[W<String>]>(W<[Int]>()) // expected-error{{initializer 'init(_:)' requires the types 'String' and 'Int' be equivalent}}
let _ = S<[W<String>]>.f(W<[Int]>()) // expected-error{{static method 'f' requires the types 'String' and 'Int' be equivalent}}
let _ = S<[W<String>]>().instancef(W<[Int]>()) // expected-error{{instance method 'instancef' requires the types 'String' and 'Int' be equivalent}}

// Archetypes requirement failure
func genericFunc<C1: Collection, C2: Collection>(_ c2: W<C2>, c1: C1.Type) where C1.Element == W<C2.Element> {
let _ = S<[W<C1>]>(W<C2>()) // expected-error{{initializer 'init(_:)' requires the types 'C1' and 'C2.Element' be equivalent}}
}