@@ -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)
@@ -842,20 +854,36 @@ extension MacroApplication {
842
854
// MARK: Freestanding macro expansion
843
855
844
856
extension MacroApplication {
857
+ enum MacroExpansionResult < ResultType> {
858
+ /// Expansion of the macro succeeded.
859
+ case success( ResultType )
860
+
861
+ /// Macro system found the macro to expand but running the expansion threw
862
+ /// an error and thus no expansion result exists.
863
+ case failure
864
+
865
+ /// The node that should be expanded was not a macro known to the macro system.
866
+ case notAMacro
867
+ }
868
+
845
869
private func expandFreestandingMacro< ExpandedMacroType: SyntaxProtocol > (
846
870
_ node: ( any FreestandingMacroExpansionSyntax ) ? ,
847
871
expandMacro: ( _ macro: Macro . Type , _ node: any FreestandingMacroExpansionSyntax ) throws -> ExpandedMacroType ?
848
- ) -> ExpandedMacroType ? {
872
+ ) -> MacroExpansionResult < ExpandedMacroType > {
849
873
guard let node,
850
874
let macro = macroSystem. lookup ( node. macro. text)
851
875
else {
852
- return nil
876
+ return . notAMacro
853
877
}
854
878
do {
855
- return try expandMacro ( macro, node)
879
+ if let expanded = try expandMacro ( macro, node) {
880
+ return . success( expanded)
881
+ } else {
882
+ return . failure
883
+ }
856
884
} catch {
857
885
context. addDiagnostics ( from: error, node: node)
858
- return nil
886
+ return . failure
859
887
}
860
888
}
861
889
@@ -867,7 +895,7 @@ extension MacroApplication {
867
895
/// #foo
868
896
/// }
869
897
/// ```
870
- func expandCodeBlockItem( node: CodeBlockItemSyntax ) -> CodeBlockItemListSyntax ? {
898
+ func expandCodeBlockItem( node: CodeBlockItemSyntax ) -> MacroExpansionResult < CodeBlockItemListSyntax > {
871
899
return expandFreestandingMacro ( node. item. asProtocol ( FreestandingMacroExpansionSyntax . self) ) { macro, node in
872
900
return try expandFreestandingCodeItemList (
873
901
definition: macro,
@@ -886,7 +914,7 @@ extension MacroApplication {
886
914
/// #foo
887
915
/// }
888
916
/// ```
889
- func expandMemberDecl( node: MemberBlockItemSyntax ) -> MemberBlockItemListSyntax ? {
917
+ func expandMemberDecl( node: MemberBlockItemSyntax ) -> MacroExpansionResult < MemberBlockItemListSyntax > {
890
918
return expandFreestandingMacro ( node. decl. as ( MacroExpansionDeclSyntax . self) ) { macro, node in
891
919
return try expandFreestandingMemberDeclList (
892
920
definition: macro,
@@ -904,7 +932,7 @@ extension MacroApplication {
904
932
/// ```swift
905
933
/// let a = #foo
906
934
/// ```
907
- func expandExpr( node: Syntax ) -> ExprSyntax ? {
935
+ func expandExpr( node: Syntax ) -> MacroExpansionResult < ExprSyntax > {
908
936
return expandFreestandingMacro ( node. as ( MacroExpansionExprSyntax . self) ) { macro, node in
909
937
return try expandFreestandingExpr (
910
938
definition: macro,
0 commit comments