Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macros seem to be expanded in their own sub-scope #73707

Open
tmcdonell opened this issue May 17, 2024 · 4 comments
Open

Macros seem to be expanded in their own sub-scope #73707

tmcdonell opened this issue May 17, 2024 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels

Comments

@tmcdonell
Copy link

tmcdonell commented May 17, 2024

Description

Code item macros seem to be expanded in their own scope, rather than into the surrounding scope they were called in. This means that operations such as defer will be executed immediately, rather than at the end of the enclosing scope as one would expect (and as described in the official example here).

Reproduction

Minimal reproducer is here: https://github.com/tmcdonell/swift-issue-73707-example

The macro adds a defer { print( ... ) } statement that should be printed right before the function exits.

> swift run
Building for debugging...
[7/7] Applying DeferClient
Build of product 'DeferClient' complete! (0.46s)
=== Expected ===
hello, sailor
exiting function expected()
=== Actual ===
exiting function actual()
hello, sailor

Expected behavior

The deferred print statement should be executed at the end of the function scope.

Environment

Tested with:

  • Apple Swift version 6.0-dev (LLVM cef183591317ec7, Swift 66e3110)
  • Apple Swift version 6.0-dev (LLVM 5b202efbc95a8bf, Swift a17d360)
  • Apple Swift version 5.10-dev (LLVM 57d4e30156f5d21, Swift c05dd0b)
  • Apple Swift version 5.10 (swift-5.10-RELEASE)
  • Apple Swift version 5.9 (swift-5.9-RELEASE)

Target: arm64-apple-macosx14.0

Additional information

Tangentially related: #72307 Since 5.10 it is (correctly) no longer possible to work around this using a declaration macro

@tmcdonell tmcdonell added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels May 17, 2024
@tmcdonell
Copy link
Author

tmcdonell commented May 21, 2024

Correction, it seems like using a freestanding declaration method never worked either. I just tested the example from #72307 and that also executes the defer statement immediately (swift-5.9-release). Same as if I change this example to a declaration macro.

@i2h3 if I just add some print statements to your example I get the following:

> swift run
Building for debugging...
[8/8] Linking SignpostClient
Build complete! (1.49s)
Signpost begin: sayHello()
Signpost defer: sayHello()
Hello!

Did you also encounter this behaviour (in your larger application)?

Edit: For completeness, here is the diff:

diff --git a/Sources/SignpostMacros/SignpostMacro.swift b/Sources/SignpostMacros/SignpostMacro.swift
index c5fb8a8..b9a3677 100644
--- a/Sources/SignpostMacros/SignpostMacro.swift
+++ b/Sources/SignpostMacros/SignpostMacro.swift
@@ -10,9 +10,11 @@ public struct SignpostMacro: DeclarationMacro {
                 stringLiteral: """
                 let signpostID = signposter.makeSignpostID()
                 let signpostIntervalState = signposter.beginInterval(#function, id: signpostID)
+                print("Signpost begin: \\(#function)")
 
                 defer {
                     signposter.endInterval(#function, signpostIntervalState)
+                    print("Signpost defer: \\(#function)")
                 }
                 """
             ),

@tmcdonell
Copy link
Author

According to the description of how macros are expanded, it seems that point (3) is not accurate; the compiler does not replace the macro call with its expanded form, rather it puts the expansion in a sub-tree and replaces the call with that. The diagram above this list also seems to imply the expansion should happen inline, but that doesn't appear to be the behaviour I am observing. Or, am I just doing something wrong? Any advice?

@tmcdonell tmcdonell changed the title CodeItemMacros seem to be expanded in their own scope Macros seem to be expanded in their own sub-scope rather than directly replacing the macro call May 21, 2024
@tmcdonell tmcdonell changed the title Macros seem to be expanded in their own sub-scope rather than directly replacing the macro call Macros seem to be expanded in their own sub-scope May 21, 2024
@i2h3
Copy link

i2h3 commented May 28, 2024

Did you also encounter this behaviour (in your larger application)?

I am sorry, I did not notice it and cannot tell by now because I removed all macro-based logging from our codebase shortly after to move on.

@tmcdonell
Copy link
Author

I am sorry, I did not notice it and cannot tell by now because I removed all macro-based logging from our codebase shortly after to move on.

Okay no problem, thank you for letting me know! (:
I also had to abandon macros from our codebase to move on...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

2 participants