Skip to content

[Macros] Apply nonisolated conformances transform to macro-expanded code #81260

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions lib/ASTGen/Sources/MacroEvaluation/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,32 @@ func makeExpansionOutputResult(
return 0
}

/// Adjust the expanded source code with any transformations that the compiler
/// needs to apply.
///
/// At present, this is only used to apply transformations that we want the
/// compiler plugin to perform, but if it doesn't know how, we do it here.
/// The only transformation in this category is the inference of nonisolated
/// on protocol conformances.
fileprivate func adjustExpandedSource(
_ expandedSource: String?,
plugin: CompilerPlugin
) -> String? {
guard let expandedSource else {
return nil
}

// If the plugin can infer nonisolated conformances, we don't have to.
if let capability = plugin.capability,
capability.features.contains(.inferNonisolatedConformances) {
return expandedSource
}

// Infer nonisolated conformances.
let sourceFile = Parser.parse(source: expandedSource)
return sourceFile.inferNonisolatedConformances().description
}

@_cdecl("swift_Macros_expandFreestandingMacro")
@usableFromInline
func expandFreestandingMacro(
Expand Down Expand Up @@ -534,8 +560,8 @@ func expandFreestandingMacroImpl(
diagEngine.add(exportedSourceFile: sourceFilePtr)
diagEngine.emit(diagnostics, messageSuffix: " (from macro '\(macroName)')")
}
return expandedSource

return adjustExpandedSource(expandedSource, plugin: macro.plugin)
} catch let error {
let srcMgr = SourceManager(cxxDiagnosticEngine: diagEnginePtr)
srcMgr.insert(sourceFilePtr)
Expand Down Expand Up @@ -767,8 +793,8 @@ func expandAttachedMacroImpl(
}
diagEngine.emit(diagnostics, messageSuffix: " (from macro '\(macroName)')")
}
return expandedSource

return adjustExpandedSource(expandedSource, plugin: macro.plugin)
} catch let error {
let srcMgr = SourceManager(cxxDiagnosticEngine: diagEnginePtr)
srcMgr.insert(customAttrSourceFilePtr)
Expand Down
1 change: 1 addition & 0 deletions lib/ASTGen/Sources/MacroEvaluation/PluginHost.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ struct CompilerPlugin {
struct Capability {
enum Feature: String {
case loadPluginLibrary = "load-plugin-library"
case inferNonisolatedConformances = "infer-nonisolated-conformances"
}

var protocolVersion: Int
Expand Down
4 changes: 2 additions & 2 deletions test/Macros/macro_plugin_server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
// CHECK-DIAGS: loaded macro implementation module 'MacroDefinition' from compiler plugin server

// CHECK: ->(plugin:[[#PID1:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION:]]}}}
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library","infer-nonisolated-conformances"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}MacroDefinition.{{dylib|so|dll}}","moduleName":"MacroDefinition"}}
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros.{{dylib|so|dll}}","moduleName":"EvilMacros"}}
Expand All @@ -77,7 +77,7 @@
// ^ This crashes the plugin server.

// CHECK: ->(plugin:[[#PID2:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library","infer-nonisolated-conformances"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}MacroDefinition.{{dylib|so|dll}}","moduleName":"MacroDefinition"}}
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros.{{dylib|so|dll}}","moduleName":"EvilMacros"}}
Expand Down
6 changes: 3 additions & 3 deletions test/Macros/macro_plugin_server_mod.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@
// RUN: %FileCheck -strict-whitespace %s < %t/macro-expansions.txt

// CHECK: ->(plugin:[[#PID1:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION:]]}}}
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library","infer-nonisolated-conformances"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}CrashOnLoad.{{.*}}","moduleName":"CrashOnLoad"}}

// CHECK-NEXT: ->(plugin:[[#PID2:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library","infer-nonisolated-conformances"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros{{.*}},"moduleName":"EvilMacros"}}
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"{{.*}}","lexicalContext":{{.*}},"macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"}{{.*}}

// CHECK-NEXT: ->(plugin:[[#PID3:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID3]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: <-(plugin:[[#PID3]]) {"getCapabilityResult":{"capability":{"features":["load-plugin-library","infer-nonisolated-conformances"],"protocolVersion":[[#PROTOCOL_VERSION]]}}}
// CHECK-NEXT: ->(plugin:[[#PID3]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros{{.*}}","moduleName":"EvilMacros"}}
// CHECK-NEXT: <-(plugin:[[#PID3]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
// CHECK-NEXT: ->(plugin:[[#PID3]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}MacroDefinition{{.*}}","moduleName":"MacroDefinition"}}
Expand Down