Skip to content

Commit e450047

Browse files
committed
[ConstraintSystem] Dependent member simplification should be attempted if it has type variable in any position
Current logic attempts simplification of the base type only if it's a type variable or a dependent member type. That's valid for correct code but not for invalid code e.g. `(($T) -> Void).Element` is not going to be simplified even if `$T` is bound, which causes crashes in diagnostic mode because `matchTypes` is going to re-introduce constraint with partially resolved dependent member types and by doing so make it stale forever which trips constraint system state verification logic. Resolves: rdar://105149979
1 parent dd353b9 commit e450047

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,9 @@ Type ConstraintSystem::getFixedTypeRecursive(Type type,
11081108
type = type->getRValueType();
11091109

11101110
if (auto depMemType = type->getAs<DependentMemberType>()) {
1111-
if (!depMemType->getBase()->isTypeVariableOrMember()) return type;
1111+
auto baseTy = depMemType->getBase();
1112+
if (!baseTy->hasTypeVariable() && !baseTy->hasDependentMember())
1113+
return type;
11121114

11131115
// FIXME: Perform a more limited simplification?
11141116
Type newType = simplifyType(type);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: not %target-swift-frontend %s -typecheck
2+
3+
// rdar://105149979
4+
5+
protocol Component<Output> {
6+
associatedtype Output
7+
}
8+
9+
struct R<Output> : Component {
10+
}
11+
12+
extension RangeReplaceableCollection where Element: Equatable {
13+
func test<C: Collection, Replacement: Collection>(
14+
_ other: C,
15+
with replacement: Replacement,
16+
maxReplacements: Int = .max
17+
) -> Self where C.Element == Element, Replacement.Element == Element {
18+
return self
19+
}
20+
}
21+
22+
func test(str: inout String) {
23+
let elt = R<Substring>()
24+
25+
_ = str.test {
26+
elt
27+
"+"
28+
elt
29+
} with: { match in
30+
""
31+
}
32+
}

0 commit comments

Comments
 (0)