Related: #83788
Description
swift reproduce.swift crashes with an assertion failure isConcrete() in ProtocolConformanceRef::getConcrete at ProtocolConformanceRef.h:127 when type-checking a class D that inherits from C, where both are annotated with an @attached(member, conformances:) macro whose plugin cannot be found. When the macro plugin is missing, the conformance introduced by the macro expansion is left in a non-concrete state. The compiler then calls getConcrete() unconditionally on this non-concrete ProtocolConformanceRef during getIntroducedConformances, triggering the assertion.
Reproducer
protocol DefaultInit {
init()
}
@attached(extension, conformances: DefaultInit)
@attached(member, conformances: DefaultInit, names: named(init()), named(f()))
macro DefaultInit() = #externalMacro(module: "MacroDefinition", type: "RequiredDefaultInitMacro")
@DefaultInit
class C { }
@DefaultInit
class D: C { }
Command
Expected behavior
When the macro plugin is missing, the compiler should emit an error diagnostic and exit gracefully. It should not crash with an assertion failure. The conformance lookup path in getIntroducedConformances should guard against non-concrete conformance references before calling getConcrete().
Actual behavior
test.swift:6:7: warning: external macro implementation type
'MacroDefinition.RequiredDefaultInitMacro' could not be found for macro 'DefaultInit()'
test.swift:9:7: error: external macro implementation type
'MacroDefinition.RequiredDefaultInitMacro' could not be found for macro 'DefaultInit()'
Assertion failed: (isConcrete()), function getConcrete at ProtocolConformanceRef.h:127.
While evaluating request TypeCheckPrimaryFileRequest(source_file "reproduce.swift")
While type-checking 'D'
While evaluating request StoredPropertiesRequest(D)
While evaluating request ExpandSynthesizedMemberMacroRequest(D)
Call chain
TypeCheckPrimaryFileRequest::evaluate
→ typeCheckDecl (class D)
→ NominalTypeDecl::getStoredProperties
→ StoredPropertiesRequest::evaluate
→ ExpandSynthesizedMemberMacroRequest::evaluate
→ expandMembers
→ getIntroducedConformances
→ ConformanceLookupTable::lookupConformance
→ ConformanceLookupTable::getConformance
→ ProtocolConformanceRef::getConcrete ← assertion: !isConcrete()
This bug was found by fusion-fuzz
Related: #83788
Description
swift reproduce.swiftcrashes with an assertion failureisConcrete()inProtocolConformanceRef::getConcreteatProtocolConformanceRef.h:127when type-checking a classDthat inherits fromC, where both are annotated with an@attached(member, conformances:)macro whose plugin cannot be found. When the macro plugin is missing, the conformance introduced by the macro expansion is left in a non-concrete state. The compiler then callsgetConcrete()unconditionally on this non-concreteProtocolConformanceRefduringgetIntroducedConformances, triggering the assertion.Reproducer
Command
Expected behavior
When the macro plugin is missing, the compiler should emit an error diagnostic and exit gracefully. It should not crash with an assertion failure. The conformance lookup path in
getIntroducedConformancesshould guard against non-concrete conformance references before callinggetConcrete().Actual behavior
Call chain
This bug was found by fusion-fuzz