Skip to content

Commit 01d54da

Browse files
committed
[TypeChecker] SE-0347: Allow same-type requirements connecting dependent members
Since the types don't flow from member to the base, there is no risk that dependent member type is going to affect other generic parameters through this kind of requirement. Resolves: SR-16069
1 parent 3e739f6 commit 01d54da

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,12 @@ Type TypeChecker::typeCheckParameterDefault(Expr *&defaultValue,
621621
!containsTypes(rhsTy, genericParameters))
622622
continue;
623623

624+
// If both sides are dependent members, that's okay because types
625+
// don't flow from member to the base e.g. `T.Element == U.Element`.
626+
if (lhsTy->is<DependentMemberType>() &&
627+
rhsTy->is<DependentMemberType>())
628+
continue;
629+
624630
// Allow a subset of generic same-type requirements that only mention
625631
// "in scope" generic parameters e.g. `T.X == Int` or `T == U.Z`
626632
if (!containsGenericParamsExcluding(lhsTy, genericParameters) &&

test/Constraints/type_inference_from_default_exprs.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,27 @@ func test_magic_defaults() {
175175
let _ = with_magic()
176176
let _: String = generic_with_magic()
177177
}
178+
179+
// SR-16069
180+
func test_allow_same_type_between_dependent_types() {
181+
struct Default : P {
182+
typealias X = Int
183+
}
184+
185+
struct Other : P {
186+
typealias X = Int
187+
}
188+
189+
struct S<T: P> {
190+
func test<U: P>(_: U = Default()) where U.X == T.X { // expected-note {{where 'T.X' = 'String', 'U.X' = 'Default.X' (aka 'Int')}}
191+
}
192+
}
193+
194+
func test_ok<T: P>(s: S<T>) where T.X == Int {
195+
s.test() // Ok: U == Default
196+
}
197+
198+
func test_bad<T: P>(s: S<T>) where T.X == String {
199+
s.test() // expected-error {{instance method 'test' requires the types 'String' and 'Default.X' (aka 'Int') be equivalent}}
200+
}
201+
}

0 commit comments

Comments
 (0)