Skip to content

Commit 71841bd

Browse files
committed
[Sema] Avoid a couple of downstream diags with invalid same-type reqs
Avoid conformance failures and member lookup errors for generic signatures with invalid same-type requirements.
1 parent f7e459a commit 71841bd

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,17 +1156,22 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
11561156
getOrCreateRequirementEnvironment(reqEnvCache, dc, reqSig, proto,
11571157
covariantSelf, conformance);
11581158

1159+
auto reqSubMap = reqEnvironment.getRequirementToWitnessThunkSubs();
1160+
1161+
Type selfTy = proto->getSelfInterfaceType().subst(reqSubMap);
1162+
if (selfTy->hasError()) {
1163+
return RequirementMatch(witness, MatchKind::WitnessInvalid,
1164+
witnessType, reqEnvironment,
1165+
/*optionalAdjustments*/ {});
1166+
}
1167+
11591168
// Set up the constraint system for matching.
11601169
auto setup =
11611170
[&]() -> std::tuple<std::optional<RequirementMatch>, Type, Type, Type, Type> {
11621171
// Construct a constraint system to use to solve the equality between
11631172
// the required type and the witness type.
11641173
cs.emplace(dc, ConstraintSystemFlags::AllowFixes);
11651174

1166-
auto reqSubMap = reqEnvironment.getRequirementToWitnessThunkSubs();
1167-
1168-
Type selfTy = proto->getSelfInterfaceType().subst(reqSubMap);
1169-
11701175
// Open up the type of the requirement.
11711176
reqLocator =
11721177
cs->getConstraintLocator(req, ConstraintLocator::ProtocolRequirement);

lib/Sema/TypeCheckType.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,13 @@ Type TypeResolution::resolveDependentMemberType(
235235
// Record the type we found.
236236
repr->setValue(nestedType, nullptr);
237237
} else {
238+
// If we have a concrete equivalence to an error type, avoid diagnosing the
239+
// missing member.
240+
if (auto concreteBase = genericSig->getConcreteType(baseTy)) {
241+
if (concreteBase->hasError())
242+
return ErrorType::get(baseTy);
243+
}
244+
238245
// Resolve the base to a potential archetype.
239246
// Perform typo correction.
240247
TypoCorrectionResults corrections(repr->getNameRef(), repr->getNameLoc());

test/Generics/invalid.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,13 @@ func errorMessageVariants(x: X<Int>, x2: X<Bool> = X<Int>()) -> X<Bool> {
154154
let _: X<Int>.Foo = X<Bool>.Foo() // expected-error {{cannot convert parent type 'X<Bool>' to expected type 'X<Int>'}}
155155
return x // expected-error {{cannot convert return expression of type 'X<Int>' to return type 'X<Bool>'}}
156156
}
157+
158+
protocol P2 {
159+
func foo()
160+
}
161+
162+
// Make sure we don't diagnose the conformance failure or 'T.K'.
163+
struct HasInvalidSameType<T>: P2 where T == Undefined, T.K == Int {
164+
// expected-error@-1 {{cannot find type 'Undefined' in scope}}
165+
func foo() {}
166+
}

0 commit comments

Comments
 (0)