swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
66.85k stars 10.3k forks source link

Declaration macros can’t introduce local variables #72968

Open ahoppen opened 3 months ago

ahoppen commented 3 months ago

When a declaration macro contantIntValue declares let intValue = 0, the following fails to compile

func demo() {
    #constantIntValue
    intValue // error: Cannot find 'intValue' in scope
}

Using the macro to declare a member of a struct works.

Originally reported in https://forums.swift.org/t/constant-declaration-generated-from-swift-macro-not-available-in-scope/71188

See attached project.

MyMacro.zip

ahoppen commented 2 months ago

Declaration macros not being able to introduce local variables is intended, as described here: https://github.com/apple/swift-evolution/blob/main/proposals/0389-attached-macros.md#visibility-of-names-used-and-introduced-by-macros

Therefore, a macro used within a closure or function body can only introduce declarations using names produced by createUniqueName . This maintains the two-phase of checking macros where type checking and inference is performed without expanding the macro, then the macro is expanded and its result type-checked independently, with no ability to influence type inference further.

We should probably offer a better diagnostic here, ideally an error on #constantIntValue that says something like: '#constantIntValue' can’t introduce local variable 'intValue'.