diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 56b460f7f19b8..d88b894dd6e6e 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -5577,6 +5577,18 @@ namespace { E->setMacroRef(macroRef); E->setType(expandedType); + auto fnType = + simplifyType(overload.adjustedOpenedType)->castTo(); + + auto newArgs = coerceCallArguments( + E->getArgs(), fnType, macroRef, /*applyExpr=*/nullptr, + cs.getConstraintLocator(E, ConstraintLocator::ApplyArgument), + solution.getAppliedPropertyWrappers(E)); + if (!newArgs) + return nullptr; + + E->setArgs(newArgs); + // FIXME: Expansion should be lazy. // i.e. 'ExpandMacroExpansionExprRequest' should be sinked into // 'getRewritten()', and performed on-demand. Unfortunately that requires diff --git a/test/Macros/macro_expand.swift b/test/Macros/macro_expand.swift index f52394d6a297e..554560efcb2d3 100644 --- a/test/Macros/macro_expand.swift +++ b/test/Macros/macro_expand.swift @@ -659,6 +659,28 @@ func testLocalAccessorMacroWithAutoclosure() { takesAutoclosure(1) } +@propertyWrapper +struct SomePropertyWrapper { + var wrappedValue: T + init(wrappedValue: T) { + self.wrappedValue = wrappedValue + } + init(projectedValue: Self) { + self = projectedValue + } + var projectedValue: Self { self } +} + +// Property wrappers on macros probably aren't all that useful, but make sure +// we don't crash. +@freestanding(expression) +macro hasPropertyWrapperParam(@SomePropertyWrapper x: Int) = #externalMacro(module: "MacroDefinition", type: "GenericToVoidMacro") + +func testPropertyWrapperMacro() { + #hasPropertyWrapperParam(x: 0) + #hasPropertyWrapperParam($x: .init(wrappedValue: 0)) +} + #if TEST_DIAGNOSTICS @freestanding(expression) macro missingMacro() = #externalMacro(module: "MacroDefinition", type: "BluhBlah") diff --git a/test/Macros/macro_misc_diags.swift b/test/Macros/macro_misc_diags.swift index 3bd8fd8035b4b..4201c04639621 100644 --- a/test/Macros/macro_misc_diags.swift +++ b/test/Macros/macro_misc_diags.swift @@ -36,6 +36,32 @@ public struct TrailingClosureMacro: ExpressionMacro { } } +public struct CallClosureMacro: ExpressionMacro { + public static func expansion( + of macro: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> ExprSyntax { + guard let argument = macro.trailingClosure else { + fatalError() + } + return "\(argument)()" + } +} + +public struct AddFunctionThatCallsClosureMacro: PeerMacro { + public static func expansion( + of node: AttributeSyntax, + providingPeersOf declaration: some DeclSyntaxProtocol, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + guard case .argumentList(let args) = node.arguments else { + fatalError() + } + let arg = args.first! + return ["func qux() { \(arg)() }"] + } +} + public struct MakeBinding : DeclarationMacro { static public func expansion( of node: some FreestandingMacroExpansionSyntax, @@ -64,6 +90,12 @@ macro identity(_ x: T) -> T = #externalMacro(module: "MacroPlugin", type: "Id @freestanding(expression) macro trailingClosure(_ x: T) -> T = #externalMacro(module: "MacroPlugin", type: "TrailingClosureMacro") +@freestanding(expression) +macro takesNonEscapingClosure(_ x: () -> Void) = #externalMacro(module: "MacroPlugin", type: "CallClosureMacro") + +@attached(peer, names: named(qux)) +macro AddFunctionThatCallsClosure(_ fn: () -> T) = #externalMacro(module: "MacroPlugin", type: "AddFunctionThatCallsClosureMacro") + @freestanding(declaration, names: named(x)) macro makeBinding(_ x: T) = #externalMacro(module: "MacroPlugin", type: "MakeBinding") @@ -160,3 +192,29 @@ class rdar138997009_Class { } } } + +// https://github.com/swiftlang/swift/issues/80561 +class TestNonEscaping { + func foo() {} + func bar() { + _ = #takesNonEscapingClosure { + foo() + } + _ = { + _ = #takesNonEscapingClosure { + foo() + // CHECK-DIAG: @__swiftmacro_6Client0017Clientswift_yEEFcfMX[[@LINE-3]]{{.*}}takesNonEscapingClosurefMf_.swift:2:9: error: call to method 'foo' in closure requires explicit use of 'self' to make capture semantics explicit + // CHECK-DIAG: Client.swift:[[@LINE-2]]:9: warning: call to method 'foo' in closure requires explicit use of 'self' to make capture semantics explicit; this will be an error in a future Swift language mode + } + } + + @AddFunctionThatCallsClosure({ foo() }) + func baz() {} + } + func qux() { + @AddFunctionThatCallsClosure({ _ = { foo() } }) + func baz() {} + // CHECK-DIAG: Client.swift:[[@LINE-2]]:42: warning: call to method 'foo' in closure requires explicit use of 'self' to make capture semantics explicit; this will be an error in a future Swift language mode + // CHECK-DIAG: @__swiftmacro_6Client15TestNonEscapingC3quxyyF7baz_$l{{.*}}AddFunctionThatCallsClosurefMp_.swift:4:13: error: call to method 'foo' in closure requires explicit use of 'self' to make capture semantics explicit + } +}