[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.
This commit is contained in:
Hamish Knight
2025-10-08 21:16:02 +01:00
parent f7e459a9b5
commit 71841bdbd5
3 changed files with 26 additions and 4 deletions

View File

@@ -1156,6 +1156,15 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
getOrCreateRequirementEnvironment(reqEnvCache, dc, reqSig, proto,
covariantSelf, conformance);
auto reqSubMap = reqEnvironment.getRequirementToWitnessThunkSubs();
Type selfTy = proto->getSelfInterfaceType().subst(reqSubMap);
if (selfTy->hasError()) {
return RequirementMatch(witness, MatchKind::WitnessInvalid,
witnessType, reqEnvironment,
/*optionalAdjustments*/ {});
}
// Set up the constraint system for matching.
auto setup =
[&]() -> std::tuple<std::optional<RequirementMatch>, Type, Type, Type, Type> {
@@ -1163,10 +1172,6 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
// the required type and the witness type.
cs.emplace(dc, ConstraintSystemFlags::AllowFixes);
auto reqSubMap = reqEnvironment.getRequirementToWitnessThunkSubs();
Type selfTy = proto->getSelfInterfaceType().subst(reqSubMap);
// Open up the type of the requirement.
reqLocator =
cs->getConstraintLocator(req, ConstraintLocator::ProtocolRequirement);

View File

@@ -235,6 +235,13 @@ Type TypeResolution::resolveDependentMemberType(
// Record the type we found.
repr->setValue(nestedType, nullptr);
} else {
// If we have a concrete equivalence to an error type, avoid diagnosing the
// missing member.
if (auto concreteBase = genericSig->getConcreteType(baseTy)) {
if (concreteBase->hasError())
return ErrorType::get(baseTy);
}
// Resolve the base to a potential archetype.
// Perform typo correction.
TypoCorrectionResults corrections(repr->getNameRef(), repr->getNameLoc());

View File

@@ -154,3 +154,13 @@ func errorMessageVariants(x: X<Int>, x2: X<Bool> = X<Int>()) -> X<Bool> {
let _: X<Int>.Foo = X<Bool>.Foo() // expected-error {{cannot convert parent type 'X<Bool>' to expected type 'X<Int>'}}
return x // expected-error {{cannot convert return expression of type 'X<Int>' to return type 'X<Bool>'}}
}
protocol P2 {
func foo()
}
// Make sure we don't diagnose the conformance failure or 'T.K'.
struct HasInvalidSameType<T>: P2 where T == Undefined, T.K == Int {
// expected-error@-1 {{cannot find type 'Undefined' in scope}}
func foo() {}
}