@@ -485,10 +485,14 @@ private class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
485
485
// Note that 'MacroExpansionExpr'/'MacroExpansionExprDecl' at code item
486
486
// position are handled by 'visit(_:CodeBlockItemListSyntax)'.
487
487
// Only expression expansions inside other syntax nodes is handled here.
488
- if let expanded = expandExpr ( node: node) {
488
+ switch expandExpr ( node: node) {
489
+ case . success( let expanded) :
489
490
return Syntax ( visit ( expanded) )
491
+ case . failure:
492
+ return Syntax ( node)
493
+ case . notAMacro:
494
+ break
490
495
}
491
-
492
496
if let declSyntax = node. as ( DeclSyntax . self) ,
493
497
let attributedNode = node. asProtocol ( WithAttributesSyntax . self) ,
494
498
!attributedNode. attributes. isEmpty
@@ -510,16 +514,21 @@ private class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
510
514
var newItems : [ CodeBlockItemSyntax ] = [ ]
511
515
func addResult( _ node: CodeBlockItemSyntax ) {
512
516
// Expand freestanding macro.
513
- if let expanded = expandCodeBlockItem ( node: node) {
517
+ switch expandCodeBlockItem ( node: node) {
518
+ case . success( let expanded) :
514
519
for item in expanded {
515
520
addResult ( item)
516
521
}
517
522
return
523
+ case . failure:
524
+ // Expanding the macro threw an error. We don't have an expanded source.
525
+ // Retain the macro node as-is.
526
+ newItems. append ( node)
527
+ case . notAMacro:
528
+ // Recurse on the child node
529
+ newItems. append ( visit ( node) )
518
530
}
519
531
520
- // Recurse on the child node
521
- newItems. append ( visit ( node) )
522
-
523
532
// Expand any peer macro on this item.
524
533
if case . decl( let decl) = node. item {
525
534
for peer in expandCodeBlockPeers ( of: decl) {
@@ -552,16 +561,19 @@ private class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
552
561
553
562
func addResult( _ node: MemberBlockItemSyntax ) {
554
563
// Expand freestanding macro.
555
- if let expanded = expandMemberDecl ( node: node) {
564
+ switch expandMemberDecl ( node: node) {
565
+ case . success( let expanded) :
556
566
for item in expanded {
557
567
addResult ( item)
558
568
}
559
569
return
570
+ case . failure:
571
+ newItems. append ( node)
572
+ case . notAMacro:
573
+ // Recurse on the child node.
574
+ newItems. append ( visit ( node) )
560
575
}
561
576
562
- // Recurse on the child node.
563
- newItems. append ( visit ( node) )
564
-
565
577
// Expand any peer macro on this member.
566
578
for peer in expandMemberDeclPeers ( of: node. decl) {
567
579
addResult ( peer)
@@ -846,20 +858,36 @@ extension MacroApplication {
846
858
// MARK: Freestanding macro expansion
847
859
848
860
extension MacroApplication {
861
+ enum MacroExpansionResult < ResultType> {
862
+ /// Expansion of the macro succeeded.
863
+ case success( ResultType )
864
+
865
+ /// Macro system found the macro to expand but running the expansion threw
866
+ /// an error and thus no expansion result exists.
867
+ case failure
868
+
869
+ /// The node that should be expanded was not a macro known to the macro system.
870
+ case notAMacro
871
+ }
872
+
849
873
private func expandFreestandingMacro< ExpandedMacroType: SyntaxProtocol > (
850
874
_ node: ( any FreestandingMacroExpansionSyntax ) ? ,
851
875
expandMacro: ( _ macro: Macro . Type , _ node: any FreestandingMacroExpansionSyntax ) throws -> ExpandedMacroType ?
852
- ) -> ExpandedMacroType ? {
876
+ ) -> MacroExpansionResult < ExpandedMacroType > {
853
877
guard let node,
854
878
let macro = macroSystem. lookup ( node. macroName. text)
855
879
else {
856
- return nil
880
+ return . notAMacro
857
881
}
858
882
do {
859
- return try expandMacro ( macro, node)
883
+ if let expanded = try expandMacro ( macro, node) {
884
+ return . success( expanded)
885
+ } else {
886
+ return . failure
887
+ }
860
888
} catch {
861
889
context. addDiagnostics ( from: error, node: node)
862
- return nil
890
+ return . failure
863
891
}
864
892
}
865
893
@@ -871,7 +899,7 @@ extension MacroApplication {
871
899
/// #foo
872
900
/// }
873
901
/// ```
874
- func expandCodeBlockItem( node: CodeBlockItemSyntax ) -> CodeBlockItemListSyntax ? {
902
+ func expandCodeBlockItem( node: CodeBlockItemSyntax ) -> MacroExpansionResult < CodeBlockItemListSyntax > {
875
903
return expandFreestandingMacro ( node. item. asProtocol ( FreestandingMacroExpansionSyntax . self) ) { macro, node in
876
904
return try expandFreestandingCodeItemList (
877
905
definition: macro,
@@ -890,7 +918,7 @@ extension MacroApplication {
890
918
/// #foo
891
919
/// }
892
920
/// ```
893
- func expandMemberDecl( node: MemberBlockItemSyntax ) -> MemberBlockItemListSyntax ? {
921
+ func expandMemberDecl( node: MemberBlockItemSyntax ) -> MacroExpansionResult < MemberBlockItemListSyntax > {
894
922
return expandFreestandingMacro ( node. decl. as ( MacroExpansionDeclSyntax . self) ) { macro, node in
895
923
return try expandFreestandingMemberDeclList (
896
924
definition: macro,
@@ -908,7 +936,7 @@ extension MacroApplication {
908
936
/// ```swift
909
937
/// let a = #foo
910
938
/// ```
911
- func expandExpr( node: Syntax ) -> ExprSyntax ? {
939
+ func expandExpr( node: Syntax ) -> MacroExpansionResult < ExprSyntax > {
912
940
return expandFreestandingMacro ( node. as ( MacroExpansionExprSyntax . self) ) { macro, node in
913
941
return try expandFreestandingExpr (
914
942
definition: macro,
0 commit comments