Description
ProtocolConformanceRef::forInvalid() currently returns a singleton — a default-constructed ref with a null Union pointer and no associated type or protocol. As a result, getType(), getProtocol(), and getRequirement() are unsafe to call on an invalid ref: getType() returns null and the others assert.
This shape forces every caller that consumes the result of substitution or associated-conformance lookup to defensively guard against an invalid conformance and synthesize a fallback type (typically ErrorType). The same workaround has been re-introduced in several places:
// lib/AST/ProtocolConformanceRef.cpp
Type ProtocolConformanceRef::getType() const {
if (isInvalid())
return Type(); // null Type — caller must handle
...
}
// include/swift/AST/ProtocolConformanceRef.h
static ProtocolConformanceRef forInvalid() {
return ProtocolConformanceRef(); // singleton, no type
}
Examples:
We should make ProtocolConformanceRef::forInvalid (and the substitution paths that produce invalid refs) carry the conforming type, even when the ref itself is invalid:
static ProtocolConformanceRef forInvalid(Type conformingType,
ProtocolDecl *protocol);
with getType() returning the stored type unconditionally (likely ErrorType for cases where no real conforming type was available, but the type slot is always populated. The two-arg shape mirrorsforAbstract(conformingType, protocol).
Additional information
No response
Description
ProtocolConformanceRef::forInvalid()currently returns a singleton — a default-constructed ref with a nullUnionpointer and no associated type or protocol. As a result,getType(),getProtocol(), andgetRequirement()are unsafe to call on an invalid ref:getType()returns null and the others assert.This shape forces every caller that consumes the result of substitution or associated-conformance lookup to defensively guard against an invalid conformance and synthesize a fallback type (typically
ErrorType). The same workaround has been re-introduced in several places:Examples:
ProtocolConformanceRef::getAssociatedType/getTypeWitness(a8ed7ba, e.g.) — both early-returnErrorType::get(ctx)whenisInvalid()to avoidasserting downstream.
PackConformance::getAssociatedConformance(issue [Swift] Crash in PackConformance::getAssociatedConformance → PackType::get when type-checking variadic generic call with deeply nested associated type pack expansion in presence of ambiguous type name #88434, fixed in AST: don't propagate null Type from invalid associated conformance #88873) — the recursive associated-conformance lookupcan return an invalid ref whose
getType()is null. The null then leaks intoPackType::get, which trips an assertion. Fix substitutesErrorTypefor thecorresponding pack element.
SubstitutionMapverification —verifyConformanceMapaccepts anallowInvalidflag so callers can opt out of the assert when an invalid ref is expected(lib/AST/SubstitutionMap.cpp:506).
We should make
ProtocolConformanceRef::forInvalid(and the substitution paths that produce invalid refs) carry the conforming type, even when the ref itself is invalid:with
getType()returning the stored type unconditionally (likelyErrorTypefor cases where no real conforming type was available, but the type slot is always populated. The two-arg shape mirrorsforAbstract(conformingType, protocol).Additional information
No response