Skip to content

Commit e5e4f2a

Browse files
authored
Merge pull request #25181 from xedin/rdar-50099849
[TypeChecker] Don't try to validate generic requirements when unbound…
2 parents 5fa42c0 + 6b35f5d commit e5e4f2a

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,10 @@ Type TypeChecker::applyUnboundGenericArguments(
805805
// generic arguments.
806806
auto resultType = decl->getDeclaredInterfaceType();
807807

808-
bool hasTypeVariable = false;
808+
// If types involved in requirements check have either type variables
809+
// or unbound generics, let's skip the check here, and let the solver
810+
// do it when missing types are deduced.
811+
bool skipRequirementsCheck = false;
809812

810813
// Get the substitutions for outer generic parameters from the parent
811814
// type.
@@ -822,7 +825,7 @@ Type TypeChecker::applyUnboundGenericArguments(
822825
}
823826

824827
subs = parentType->getContextSubstitutions(decl->getDeclContext());
825-
hasTypeVariable |= parentType->hasTypeVariable();
828+
skipRequirementsCheck |= parentType->hasTypeVariable();
826829
}
827830

828831
SourceLoc noteLoc = decl->getLoc();
@@ -839,13 +842,14 @@ Type TypeChecker::applyUnboundGenericArguments(
839842
subs[origTy->getCanonicalType()->castTo<GenericTypeParamType>()] =
840843
substTy;
841844

842-
hasTypeVariable |= substTy->hasTypeVariable();
845+
skipRequirementsCheck |=
846+
substTy->hasTypeVariable() || substTy->hasUnboundGenericType();
843847
}
844848

845849
// Check the generic arguments against the requirements of the declaration's
846850
// generic signature.
847851
auto dc = resolution.getDeclContext();
848-
if (!hasTypeVariable &&
852+
if (!skipRequirementsCheck &&
849853
resolution.getStage() > TypeResolutionStage::Structural) {
850854
auto result =
851855
checkGenericArguments(dc, loc, noteLoc, unboundType,

test/Constraints/generics.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ class GenericClass<A> {}
452452
func genericFunc<T>(t: T) {
453453
_ = [T: GenericClass] // expected-error {{generic parameter 'A' could not be inferred}}
454454
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}}
455-
// expected-error@-2 {{type 'T' does not conform to protocol 'Hashable'}}
456455
}
457456

458457
struct SR_3525<T> {}

test/Constraints/protocols.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,27 @@ func testClonableExistential(_ v: Clonable, _ vv: Clonable.Type) {
377377
let _ = v.veryBadClonerFn() // expected-error {{member 'veryBadClonerFn' cannot be used on value of protocol type 'Clonable'; use a generic constraint instead}}
378378

379379
}
380+
381+
382+
// rdar://problem/50099849
383+
384+
protocol Trivial {
385+
associatedtype T
386+
}
387+
388+
func rdar_50099849() {
389+
struct A : Trivial {
390+
typealias T = A
391+
}
392+
393+
struct B<C : Trivial> : Trivial { // expected-note {{'C' declared as parameter to type 'B'}}
394+
typealias T = C.T
395+
}
396+
397+
struct C<W: Trivial, Z: Trivial> : Trivial where W.T == Z.T {
398+
typealias T = W.T
399+
}
400+
401+
let _ = C<A, B>() // expected-error {{generic parameter 'C' could not be inferred}}
402+
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<<#C: Trivial#>>}}
403+
}

0 commit comments

Comments
 (0)