From b2a52ff036dd30e37378306cc6a7fbb4fd1c5838 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Fri, 9 Jun 2023 10:33:24 -0700 Subject: [PATCH 01/17] [move-only] Do not attempt to lazily deserialize the moveonly deinit table in IRGen. SIL Functions are serialized in canonical SIL before they have their final ABI adjusted for large function arguments. Large function argument ABI is adjusted to be indirect as part of the transition from canonical SIL to lowered SIL. This means that if we deserialize a function from another module in canonical SIL and attempt to call it in IRGen we will call it with the wrong ABI implying if we reference any fields of the type in the deinit we will most likely crash (among other potential issues). This patch fixes the issue by changing IRGen to not lazily deserialize the moveonly deinit table and its associated functions. Instead if we do not have our table already deserialized, we just call the function's deinit via the destroy value deinit table. rdar://110496872 --- lib/IRGen/GenType.cpp | 6 +- .../moveonly_split_module_source_input.swift | 66 +++++++++++++++---- .../moveonly_deinit_separate_library.swift | 54 +++++++++++++++ .../moveonly_split_module_source_deinit.swift | 17 +++-- ...dule_source_deinit_library_evolution.swift | 17 ----- 5 files changed, 124 insertions(+), 36 deletions(-) create mode 100644 test/Interpreter/moveonly_deinit_separate_library.swift delete mode 100644 test/Interpreter/moveonly_split_module_source_deinit_library_evolution.swift diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 0eb7def337d8f..82f31d8923ac2 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2897,9 +2897,11 @@ static bool tryEmitDeinitCall(IRGenFunction &IGF, return false; } - auto deinitTable = IGF.getSILModule().lookUpMoveOnlyDeinit(nominal); + auto deinitTable = IGF.getSILModule().lookUpMoveOnlyDeinit( + nominal, false /*deserialize lazily*/); - // If we do not have a deinit table, call the value witness instead. + // If we do not have a deinit table already deserialized, call the value + // witness instead. if (!deinitTable) { irgen::emitDestroyCall(IGF, T, indirect()); indirectCleanup(); diff --git a/test/Interpreter/Inputs/moveonly_split_module_source_input.swift b/test/Interpreter/Inputs/moveonly_split_module_source_input.swift index ab9859bebc5e4..4e38c17c29838 100644 --- a/test/Interpreter/Inputs/moveonly_split_module_source_input.swift +++ b/test/Interpreter/Inputs/moveonly_split_module_source_input.swift @@ -1,19 +1,61 @@ -#if TEST_LIBRARY_EVOLUTION +#if TEST_LIBRARY_WITH_LIBRARY_EVOLUTION public struct MoveOnly : ~Copyable { - var name = "John" - public init() {} - deinit { - print("==> I am in the deinit resiliently!") - print("==> My name is: \(name)!") - } +#if MAKE_LARGE + var x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, + x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0, + x16 = 0, x17 = 0, x18 = 0, x19 = 0, x20 = 0, x21 = 0, x22 = 0, + x23 = 0, x24 = 0, x25 = 0, x26 = 0, x27 = 0, x28 = 0, x29 = 0, + x30 = 0, x31 = 0, x32 = 0, x33 = 0, x34 = 0, x35 = 0, x36 = 0, + x37 = 0, x38 = 0 +#endif + var name = "John" + + public init() {} + deinit { + print("==> LIBRARY_EVOLUTION: I am in the deinit!") + print("==> My name is: \(name)!") + } +} +#else + +#if TEST_LIBRARY_WITHOUT_LIBRARY_EVOLUTION + +public struct MoveOnly : ~Copyable { +#if MAKE_LARGE + var x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, + x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0, + x16 = 0, x17 = 0, x18 = 0, x19 = 0, x20 = 0, x21 = 0, x22 = 0, + x23 = 0, x24 = 0, x25 = 0, x26 = 0, x27 = 0, x28 = 0, x29 = 0, + x30 = 0, x31 = 0, x32 = 0, x33 = 0, x34 = 0, x35 = 0, x36 = 0, + x37 = 0, x38 = 0 +#endif + var name = "John" + public init() {} + deinit { + print("==> LIBRARY: I am in the deinit!") + print("==> My name is: \(name)!") + } } + #else + struct MoveOnly : ~Copyable { - var name = "John" - deinit { - print("==> I am in the deinit!") - print("==> My name is: \(name)!") - } +#if MAKE_LARGE + var x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, + x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0, + x16 = 0, x17 = 0, x18 = 0, x19 = 0, x20 = 0, x21 = 0, x22 = 0, + x23 = 0, x24 = 0, x25 = 0, x26 = 0, x27 = 0, x28 = 0, x29 = 0, + x30 = 0, x31 = 0, x32 = 0, x33 = 0, x34 = 0, x35 = 0, x36 = 0, + x37 = 0, x38 = 0 +#endif + + var name = "John" + deinit { + print("==> I am in the deinit!") + print("==> My name is: \(name)!") + } } + +#endif #endif diff --git a/test/Interpreter/moveonly_deinit_separate_library.swift b/test/Interpreter/moveonly_deinit_separate_library.swift new file mode 100644 index 0000000000000..f2687bd904268 --- /dev/null +++ b/test/Interpreter/moveonly_deinit_separate_library.swift @@ -0,0 +1,54 @@ +// Normal test + +// RUN: %empty-directory(%t/normal) +// RUN: %target-build-swift-dylib(%t/normal/%target-library-name(MoveOnlySplit)) %S/Inputs/moveonly_split_module_source_input.swift -emit-module -emit-module-path %t/normal/MoveOnlySplit.swiftmodule -module-name MoveOnlySplit -DTEST_LIBRARY_WITHOUT_LIBRARY_EVOLUTION +// RUN: %target-codesign %t/normal/%target-library-name(MoveOnlySplit) + +// RUN: %target-build-swift %s -lMoveOnlySplit -I %t/normal -L %t/normal -o %t/normal/main %target-rpath(%t/normal) +// RUN: %target-codesign %t/normal/main +// RUN: %target-run %t/normal/main %t/normal/%target-library-name(MoveOnlySplit) | %FileCheck %s + +// Normal large + +// RUN: %empty-directory(%t/normal_large) +// RUN: %target-build-swift-dylib(%t/normal_large/%target-library-name(MoveOnlySplit)) %S/Inputs/moveonly_split_module_source_input.swift -emit-module -emit-module-path %t/normal_large/MoveOnlySplit.swiftmodule -module-name MoveOnlySplit -DTEST_LIBRARY_WITHOUT_LIBRARY_EVOLUTION -DMAKE_LARGE +// RUN: %target-codesign %t/normal_large/%target-library-name(MoveOnlySplit) + +// RUN: %target-build-swift %s -lMoveOnlySplit -I %t/normal_large -L %t/normal_large -o %t/normal_large/main %target-rpath(%t/normal_large) +// RUN: %target-codesign %t/normal_large/main +// RUN: %target-run %t/normal_large/main %t/normal_large/%target-library-name(MoveOnlySplit) | %FileCheck %s + +// Library evolution test + +// RUN: %empty-directory(%t/library_evolution) +// RUN: %target-build-swift-dylib(%t/library_evolution/%target-library-name(MoveOnlySplit)) %S/Inputs/moveonly_split_module_source_input.swift -emit-module -emit-module-path %t/library_evolution/MoveOnlySplit.swiftmodule -module-name MoveOnlySplit -DTEST_LIBRARY_WITH_LIBRARY_EVOLUTION +// RUN: %target-codesign %t/library_evolution/%target-library-name(MoveOnlySplit) + +// RUN: %target-build-swift %s -lMoveOnlySplit -I %t/library_evolution -L %t/library_evolution -o %t/library_evolution/main %target-rpath(%t/library_evolution) +// RUN: %target-codesign %t/library_evolution/main +// RUN: %target-run %t/library_evolution/main %t/library_evolution/%target-library-name(MoveOnlySplit) | %FileCheck -check-prefix=CHECK-LIBRARY-EVOLUTION %s + +// Library evolution large + +// RUN: %empty-directory(%t/library_evolution_large) +// RUN: %target-build-swift-dylib(%t/library_evolution_large/%target-library-name(MoveOnlySplit)) %S/Inputs/moveonly_split_module_source_input.swift -emit-module -emit-module-path %t/library_evolution_large/MoveOnlySplit.swiftmodule -module-name MoveOnlySplit -DTEST_LIBRARY_WITH_LIBRARY_EVOLUTION -DMAKE_LARGE +// RUN: %target-codesign %t/library_evolution_large/%target-library-name(MoveOnlySplit) + +// RUN: %target-build-swift %s -lMoveOnlySplit -I %t/library_evolution_large -L %t/library_evolution_large -o %t/library_evolution_large/main %target-rpath(%t/library_evolution_large) +// RUN: %target-codesign %t/library_evolution_large/main +// RUN: %target-run %t/library_evolution_large/main %t/library_evolution_large/%target-library-name(MoveOnlySplit) | %FileCheck -check-prefix=CHECK-LIBRARY-EVOLUTION %s + + +// REQUIRES: executable_test + +import MoveOnlySplit + +func main() { + // CHECK: ==> LIBRARY: I am in the deinit! + // CHECK: ==> My name is: John! + // CHECK-LIBRARY-EVOLUTION: ==> LIBRARY_EVOLUTION: I am in the deinit! + // CHECK-LIBRARY-EVOLUTION: ==> My name is: John! + let server = MoveOnly() +} + +main() diff --git a/test/Interpreter/moveonly_split_module_source_deinit.swift b/test/Interpreter/moveonly_split_module_source_deinit.swift index a6a073680019d..31637772171b1 100644 --- a/test/Interpreter/moveonly_split_module_source_deinit.swift +++ b/test/Interpreter/moveonly_split_module_source_deinit.swift @@ -1,10 +1,17 @@ + // Normal test. +// RUN: %empty-directory(%t/normal) +// RUN: %target-swiftc_driver -emit-module -module-name server -emit-module-path %t/normal/server.swiftmodule %s %S/Inputs/moveonly_split_module_source_input.swift +// RUN: %target-swiftc_driver -emit-executable -module-name server -emit-module-path %t/normal/server.swiftmodule %s %S/Inputs/moveonly_split_module_source_input.swift -o %t/normal/server +// RUN: %target-codesign %t/normal/server +// RUN: %target-run %t/normal/server | %FileCheck %s -// RUN: %empty-directory(%t) -// RUN: %target-swiftc_driver -emit-module -module-name server -emit-module-path %t/server.swiftmodule %s %S/Inputs/moveonly_split_module_source_input.swift -// RUN: %target-swiftc_driver -emit-executable -module-name server -emit-module-path %t/server.swiftmodule %s %S/Inputs/moveonly_split_module_source_input.swift -o %t/server -// RUN: %target-codesign %t/server -// RUN: %target-run %t/server | %FileCheck %s +// Large test. +// RUN: %empty-directory(%t/large) +// RUN: %target-swiftc_driver -emit-module -module-name server -emit-module-path %t/large/server.swiftmodule %s %S/Inputs/moveonly_split_module_source_input.swift -DMAKE_LARGE +// RUN: %target-swiftc_driver -emit-executable -module-name server -emit-module-path %t/large/server.swiftmodule %s %S/Inputs/moveonly_split_module_source_input.swift -o %t/large/server +// RUN: %target-codesign %t/large/server +// RUN: %target-run %t/large/server | %FileCheck %s // REQUIRES: executable_test diff --git a/test/Interpreter/moveonly_split_module_source_deinit_library_evolution.swift b/test/Interpreter/moveonly_split_module_source_deinit_library_evolution.swift deleted file mode 100644 index 45910f262f528..0000000000000 --- a/test/Interpreter/moveonly_split_module_source_deinit_library_evolution.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-build-swift-dylib(%t/%target-library-name(MoveOnlySplit)) -enable-library-evolution %S/Inputs/moveonly_split_module_source_input.swift -emit-module -emit-module-path %t/MoveOnlySplit.swiftmodule -module-name MoveOnlySplit -DTEST_LIBRARY_EVOLUTION -// RUN: %target-codesign %t/%target-library-name(MoveOnlySplit) - -// RUN: %target-build-swift %s -lMoveOnlySplit -I %t -L %t -o %t/main %target-rpath(%t) -// RUN: %target-codesign %t/main -// RUN: %target-run %t/main %t/%target-library-name(MoveOnlySplit) | %FileCheck -check-prefix=CHECK-LIBRARY-EVOLUTION %s - -// REQUIRES: executable_test - -import MoveOnlySplit - -func main() { - let server = MoveOnly() // CHECK-LIBRARY-EVOLUTION: ==> I am in the deinit resiliently! -} - -main() From 3c04cff8dd739fe3728808a092542020504065c8 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 9 Jun 2023 12:59:56 -0700 Subject: [PATCH 02/17] [Macros] Provide the freestanding macro role for expansion operations. The compiler knows (from a macro declaration) what freestanding macro role a macro implementation is expected to implement. Pass that through to the macro expansion code itself, rather than guessing based on the protocol conformances of the implementation type. We already use this approach with attached macros, so this is more of the same. Eliminates a crash and improves diagnostics when the freestanding macro role and its implementation are out of sync, fixing rdar://110418969. --- lib/ASTGen/Sources/ASTGen/Macros.swift | 21 ++++++++++++++++ .../Sources/ASTGen/PluginMessages.swift | 2 ++ lib/IDETool/SyntacticMacroExpansion.cpp | 2 +- lib/Sema/TypeCheckMacros.cpp | 13 ++++++++-- .../Inputs/syntax_macro_definitions.swift | 20 ++++++++++++++++ test/Macros/macro_expand.swift | 24 +++++++++++++++++++ test/Macros/macro_plugin_basic.swift | 4 ++-- test/Macros/macro_plugin_error.swift | 6 ++--- test/Macros/macro_plugin_server.swift | 6 ++--- 9 files changed, 87 insertions(+), 11 deletions(-) diff --git a/lib/ASTGen/Sources/ASTGen/Macros.swift b/lib/ASTGen/Sources/ASTGen/Macros.swift index f4eeb3bb30d11..9c8d5bbfe0a97 100644 --- a/lib/ASTGen/Sources/ASTGen/Macros.swift +++ b/lib/ASTGen/Sources/ASTGen/Macros.swift @@ -67,6 +67,8 @@ extension MacroRole { case 0x10: self = .member case 0x20: self = .peer case 0x40: self = .conformance + case 0x80: self = .codeItem + default: fatalError("unknown macro role") } } @@ -414,6 +416,7 @@ func expandFreestandingMacro( macroKind: UInt8, discriminatorText: UnsafePointer, discriminatorTextLength: Int, + rawMacroRole: UInt8, sourceFilePtr: UnsafeRawPointer, sourceLocationPtr: UnsafePointer?, expandedSourcePointer: UnsafeMutablePointer?>, @@ -446,11 +449,13 @@ func expandFreestandingMacro( ) let discriminator = String(decoding: discriminatorBuffer, as: UTF8.self) + let macroRole = MacroRole(rawMacroRole: rawMacroRole) let expandedSource: String? switch MacroPluginKind(rawValue: macroKind)! { case .InProcess: expandedSource = expandFreestandingMacroInProcess( macroPtr: macroPtr, + macroRole: macroRole, diagEnginePtr: diagEnginePtr, expansionSyntax: expansion, sourceFilePtr: sourceFilePtr, @@ -458,6 +463,7 @@ func expandFreestandingMacro( case .Executable: expandedSource = expandFreestandingMacroIPC( macroPtr: macroPtr, + macroRole: macroRole, diagEnginePtr: diagEnginePtr, expansionSyntax: expansion, sourceFilePtr: sourceFilePtr, @@ -485,6 +491,7 @@ func expandFreestandingMacro( func expandFreestandingMacroIPC( macroPtr: UnsafeRawPointer, + macroRole: MacroRole, diagEnginePtr: UnsafeMutablePointer, expansionSyntax: FreestandingMacroExpansionSyntax, sourceFilePtr: UnsafePointer, @@ -502,9 +509,21 @@ func expandFreestandingMacroIPC( let macro = macroPtr.assumingMemoryBound(to: ExportedExecutableMacro.self).pointee + // Map the macro role. + let pluginMacroRole: PluginMessage.MacroRole + switch macroRole { + case .accessor, .member, .memberAttribute, .peer, .conformance: + preconditionFailure("unhandled macro role for freestanding macro") + + case .expression: pluginMacroRole = .expression + case .declaration: pluginMacroRole = .freeStandingDeclaration + case .codeItem: pluginMacroRole = .codeItem + } + // Send the message. let message = HostToPluginMessage.expandFreestandingMacro( macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName), + macroRole: pluginMacroRole, discriminator: discriminator, syntax: PluginMessage.Syntax(syntax: Syntax(expansionSyntax), in: sourceFilePtr)!) do { @@ -541,6 +560,7 @@ func expandFreestandingMacroIPC( func expandFreestandingMacroInProcess( macroPtr: UnsafeRawPointer, + macroRole: MacroRole, diagEnginePtr: UnsafeMutablePointer, expansionSyntax: FreestandingMacroExpansionSyntax, sourceFilePtr: UnsafePointer, @@ -580,6 +600,7 @@ func expandFreestandingMacroInProcess( return SwiftSyntaxMacroExpansion.expandFreestandingMacro( definition: macro, + macroRole: macroRole, node: node, in: context ) diff --git a/lib/ASTGen/Sources/ASTGen/PluginMessages.swift b/lib/ASTGen/Sources/ASTGen/PluginMessages.swift index df67a178f43c3..cd058797f90f0 100644 --- a/lib/ASTGen/Sources/ASTGen/PluginMessages.swift +++ b/lib/ASTGen/Sources/ASTGen/PluginMessages.swift @@ -20,6 +20,7 @@ internal enum HostToPluginMessage: Codable { /// Expand a '@freestanding' macro. case expandFreestandingMacro( macro: PluginMessage.MacroReference, + macroRole: PluginMessage.MacroRole? = nil, discriminator: String, syntax: PluginMessage.Syntax ) @@ -91,6 +92,7 @@ internal enum PluginToHostMessage: Codable { case member case peer case conformance + case codeItem } struct SourceLocation: Codable { diff --git a/lib/IDETool/SyntacticMacroExpansion.cpp b/lib/IDETool/SyntacticMacroExpansion.cpp index afcffa672721b..e7a16e7bb62db 100644 --- a/lib/IDETool/SyntacticMacroExpansion.cpp +++ b/lib/IDETool/SyntacticMacroExpansion.cpp @@ -412,7 +412,7 @@ void SyntacticMacroExpansionInstance::expand( SourceFile *SF, const MacroExpansionSpecifier &expansion, SourceEditConsumer &consumer) { - // Find the expansion at 'expantion.offset'. + // Find the expansion at 'expansion.offset'. MacroExpansionFinder expansionFinder( SourceMgr, SourceMgr.getLocForOffset(*SF->getBufferID(), expansion.offset)); diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 6fb677cbefcc7..b6a6dacaa5d97 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -66,7 +66,8 @@ extern "C" ptrdiff_t swift_ASTGen_checkMacroDefinition( extern "C" ptrdiff_t swift_ASTGen_expandFreestandingMacro( void *diagEngine, void *macro, uint8_t externalKind, - const char *discriminator, ptrdiff_t discriminatorLength, void *sourceFile, + const char *discriminator, ptrdiff_t discriminatorLength, + uint8_t rawMacroRole, void *sourceFile, const void *sourceLocation, const char **evaluatedSource, ptrdiff_t *evaluatedSourceLength); @@ -901,6 +902,13 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion, #endif }); + // Only one freestanding macro role is permitted, so look at the roles to + // figure out which one to use. + MacroRole macroRole = + macroRoles.contains(MacroRole::Expression) ? MacroRole::Expression + : macroRoles.contains(MacroRole::Declaration) ? MacroRole::Declaration + : MacroRole::CodeItem; + auto macroDef = macro->getDefinition(); switch (macroDef.kind) { case MacroDefinition::Kind::Undefined: @@ -961,7 +969,8 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion, swift_ASTGen_expandFreestandingMacro( &ctx.Diags, externalDef->opaqueHandle, static_cast(externalDef->kind), discriminator->data(), - discriminator->size(), astGenSourceFile, + discriminator->size(), + static_cast(macroRole), astGenSourceFile, expansion->getSourceRange().Start.getOpaquePointerValue(), &evaluatedSourceAddress, &evaluatedSourceLength); if (!evaluatedSourceAddress) diff --git a/test/Macros/Inputs/syntax_macro_definitions.swift b/test/Macros/Inputs/syntax_macro_definitions.swift index 7eaa3505105c4..b01cb48da66dc 100644 --- a/test/Macros/Inputs/syntax_macro_definitions.swift +++ b/test/Macros/Inputs/syntax_macro_definitions.swift @@ -73,6 +73,26 @@ public struct StringifyMacro: ExpressionMacro { } } +public struct ExprAndDeclMacro: ExpressionMacro, DeclarationMacro { + public static func expansion( + of macro: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> ExprSyntax { + guard let argument = macro.argumentList.first?.expression else { + fatalError("boom") + } + + return "(\(argument), \(StringLiteralExprSyntax(content: argument.description)))" + } + + public static func expansion( + of macro: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> [DeclSyntax] { + return [] + } +} + public struct StringifyAndTryMacro: ExpressionMacro { public static func expansion( of macro: some FreestandingMacroExpansionSyntax, diff --git a/test/Macros/macro_expand.swift b/test/Macros/macro_expand.swift index 9067be4b3f1dd..9aca53fce374d 100644 --- a/test/Macros/macro_expand.swift +++ b/test/Macros/macro_expand.swift @@ -510,3 +510,27 @@ func testHasEqualsSelf( _ = (zP == true) _ = (wP == true) } + +// Macro whose implementation is both an expression and declaration macro. +@freestanding(declaration) +macro AsDeclMacro(_ value: T) = #externalMacro(module: "MacroDefinition", type: "ExprAndDeclMacro") + +@freestanding(expression) +macro AsExprMacro(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "ExprAndDeclMacro") + +func testExpressionAndDeclarationMacro() { + #AsExprMacro(1 + 1) // expected-warning{{expression of type '(Int, String)' is unused}} + struct Inner { + #AsDeclMacro(1 + 1) + } + #AsDeclMacro(1 + 1) +} + +// Expression macro implementation with declaration macro role +@freestanding(declaration) macro stringifyAsDeclMacro(_ value: T) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro") +func testExpressionAsDeclarationMacro() { +#if TEST_DIAGNOSTICS + #stringifyAsDeclMacro(1+1) + // expected-error@-1{{macro implementation type 'StringifyMacro' doesn't conform to required protocol 'DeclarationMacro' (from macro 'stringifyAsDeclMacro')}} +#endif +} diff --git a/test/Macros/macro_plugin_basic.swift b/test/Macros/macro_plugin_basic.swift index fbd9633f4095a..d62321f20dfab 100644 --- a/test/Macros/macro_plugin_basic.swift +++ b/test/Macros/macro_plugin_basic.swift @@ -23,9 +23,9 @@ // CHECK: ->(plugin:[[#PID:]]) {"getCapability":{}} // CHECK: <-(plugin:[[#PID]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}} -// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"testString","typeName":"TestStringMacro"},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":5,"offset":301},"source":"#testString(123)"}}} +// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"testString","typeName":"TestStringMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":5,"offset":301},"source":"#testString(123)"}}} // CHECK: <-(plugin:[[#PID]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"\"123\"\n + \"foo \""}} -// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"testStringWithError","typeName":"TestStringWithErrorMacro"},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":6,"offset":336},"source":"#testStringWithError(321)"}}} +// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"testStringWithError","typeName":"TestStringWithErrorMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":6,"offset":336},"source":"#testStringWithError(321)"}}} // CHECK: <-(plugin:[[#PID]]) {"expandFreestandingMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[],"message":"message from plugin","notes":[],"position":{"fileName":"BUILD_DIR{{.*}}test.swift","offset":336},"severity":"error"}],"expandedSource":"\"bar\""}} //--- test.swift diff --git a/test/Macros/macro_plugin_error.swift b/test/Macros/macro_plugin_error.swift index 458ec20891e0f..3f599142f7397 100644 --- a/test/Macros/macro_plugin_error.swift +++ b/test/Macros/macro_plugin_error.swift @@ -23,12 +23,12 @@ // CHECK: ->(plugin:[[#PID1:]]) {"getCapability":{}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":6,"offset":[[#]]},"source":"#fooMacro(1)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":6,"offset":[[#]]},"source":"#fooMacro(1)"}}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"invalidResponse":{}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":8,"offset":[[#]]},"source":"#fooMacro(2)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":8,"offset":[[#]]},"source":"#fooMacro(2)"}}} // ^ This messages causes the mock plugin exit because there's no matching expected message. -// CHECK: ->(plugin:[[#PID2:]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":10,"offset":[[#]]},"source":"#fooMacro(3)"}}} +// CHECK: ->(plugin:[[#PID2:]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"BUILD_DIR{{.+}}test.swift","line":10,"offset":[[#]]},"source":"#fooMacro(3)"}}} // CHECK-NEXT: <-(plugin:[[#PID2:]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"3.description"}} //--- test.swift diff --git a/test/Macros/macro_plugin_server.swift b/test/Macros/macro_plugin_server.swift index b4bc369b6b39d..66116d2dfdecc 100644 --- a/test/Macros/macro_plugin_server.swift +++ b/test/Macros/macro_plugin_server.swift @@ -37,16 +37,16 @@ // CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} // CHECK-NEXT: ->(plugin:[[#PID1]]) {"loadPluginLibrary":{"libraryPath":"BUILD_DIR{{.*}}plugins/libEvilMacros.dylib","moduleName":"EvilMacros"}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(a + b)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(a + b)"}}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"(a + b, \"a + b\")"}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#evil(42)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#evil(42)"}}} // ^ This crashes the plugin server. // CHECK-NEXT: ->(plugin:[[#PID2:]]) {"loadPluginLibrary":{"libraryPath":"BUILD_DIR{{.*}}plugins/libMacroDefinition.dylib","moduleName":"MacroDefinition"}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} // CHECK-NEXT: ->(plugin:[[#PID2]]) {"loadPluginLibrary":{"libraryPath":"BUILD_DIR{{.*}}plugins/libEvilMacros.dylib","moduleName":"EvilMacros"}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} -// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(b + a)"}}} +// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(b + a)"}}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"(b + a, \"b + a\")"}} @freestanding(expression) macro stringify(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro") From c5ec3892aacd6680db140ad969b7072bfcbf7c8a Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 9 Jun 2023 13:40:11 -0700 Subject: [PATCH 03/17] Diagnose macros that have multiple freestanding macro roles. Per SE-0397, a macro may only have a single freestanding macro role, otherwise we would have an ambiguity in how a particular freestanding macro would be expanded. Produce an error on such macro declarations. Fixes rdar://110178899. --- include/swift/AST/DiagnosticsSema.def | 2 ++ lib/Sema/TypeCheckDeclPrimary.cpp | 18 ++++++++++++++++++ test/Macros/macros_diagnostics.swift | 7 +++++++ test/Macros/parsing.swift | 1 + 4 files changed, 28 insertions(+) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 3e84049f014d0..7bf952557fbcb 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7109,6 +7109,8 @@ NOTE(macro_remove_result_type,none, ()) NOTE(macro_make_freestanding_expression,none, "make this macro a freestanding expression macro", ()) +ERROR(macro_multiple_freestanding_roles,none, + "macro can only have a single freestanding role", ()) ERROR(macro_expansion_missing_pound,none, "expansion of macro %0 requires leading '#'", (DeclName)) ERROR(macro_expansion_missing_arguments,none, diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 643b13afd8881..91ed49d6f040f 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2017,6 +2017,17 @@ class DeclChecker : public DeclVisitor { llvm_unreachable("should always be type-checked already"); } + /// Determine the number of bits set. + static unsigned numBitsSet(uint64_t value) { + unsigned count = 0; + for (uint64_t i : range(0, 63)) { + if (value & (uint64_t(1) << i)) + ++count; + } + + return count; + } + void visitMacroDecl(MacroDecl *MD) { TypeChecker::checkDeclAttributes(MD); checkAccessControl(MD); @@ -2077,6 +2088,13 @@ class DeclChecker : public DeclVisitor { .fixItRemove(SourceRange(MD->arrowLoc, resultTypeRepr->getEndLoc())); } } + + // A macro can only have a single freestanding macro role. + MacroRoles freestandingRolesInhabited = + MD->getMacroRoles() & getFreestandingMacroRoles(); + if (numBitsSet(freestandingRolesInhabited.toRaw()) > 1) { + MD->diagnose(diag::macro_multiple_freestanding_roles); + } } void visitMacroExpansionDecl(MacroExpansionDecl *MED) { diff --git a/test/Macros/macros_diagnostics.swift b/test/Macros/macros_diagnostics.swift index 1955d9f6a76ec..2f9b00a44716e 100644 --- a/test/Macros/macros_diagnostics.swift +++ b/test/Macros/macros_diagnostics.swift @@ -211,3 +211,10 @@ struct SomeType { @freestanding(declaration) macro nonExpressionReturnsVoid(_: T) -> Void = #externalMacro(module: "A", type: "B") // expected-warning@-1{{external macro implementation type}} + + +@freestanding(expression) +@freestanding(declaration) +macro multipleFreestandingRoles(_: T) -> Void = #externalMacro(module: "A", type: "B") +// expected-warning@-1{{external macro implementation type}} +// expected-error@-2{{macro can only have a single freestanding role}} diff --git a/test/Macros/parsing.swift b/test/Macros/parsing.swift index 1de66078abec3..f4380d1ecfd24 100644 --- a/test/Macros/parsing.swift +++ b/test/Macros/parsing.swift @@ -35,6 +35,7 @@ protocol Q { associatedtype Assoc } @freestanding(expression) @freestanding(declaration, names: named(Foo)) @attached(accessor) macro m10(_: String) = #externalMacro(module: "A", type: "M4") // expected-warning@-1{{external macro implementation type 'A.M4' could not be found for macro 'm10'}} +// expected-error@-2{{macro can only have a single freestanding role}} @attached( accessor, From e3d940eb59630a9f6a29c7427a939347d77dd933 Mon Sep 17 00:00:00 2001 From: "Kuba (Brecka) Mracek" Date: Fri, 9 Jun 2023 14:41:16 -0700 Subject: [PATCH 04/17] Move _used+_section from DECL_MODIFIER_KINDS to DECL_ATTR_KINDS in AttributeKinds.py (#66194) --- utils/gyb_syntax_support/AttributeKinds.py | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/utils/gyb_syntax_support/AttributeKinds.py b/utils/gyb_syntax_support/AttributeKinds.py index 8322bb3a449c2..7eaca69b492f5 100644 --- a/utils/gyb_syntax_support/AttributeKinds.py +++ b/utils/gyb_syntax_support/AttributeKinds.py @@ -725,7 +725,22 @@ def __init__(self, name, swift_name=None): SimpleDeclAttribute('runtimeMetadata', 'RuntimeMetadata', OnStruct, OnClass, OnEnum, ABIBreakingToAdd, ABIBreakingToRemove, APIBreakingToAdd, APIBreakingToRemove, # noqa: E501 - code=139) + code=139), + + SimpleDeclAttribute('_used', 'Used', + OnAbstractFunction, OnVar, + UserInaccessible, + ABIBreakingToAdd, ABIBreakingToRemove, + APIBreakingToAdd, APIBreakingToRemove, + code=143), + + DeclAttribute('_section', 'Section', + OnAbstractFunction, OnVar, + UserInaccessible, + ABIBreakingToAdd, ABIBreakingToRemove, + APIBreakingToAdd, APIBreakingToRemove, + code=144), + ] # Schema for declaration modifiers: @@ -931,20 +946,6 @@ def __init__(self, name, swift_name=None): code=142), DeclAttributeAlias('freestanding', 'MacroRole'), - SimpleDeclAttribute('_used', 'Used', - OnAbstractFunction, OnVar, - UserInaccessible, - ABIBreakingToAdd, ABIBreakingToRemove, - APIBreakingToAdd, APIBreakingToRemove, - code=143), - - DeclAttribute('_section', 'Section', - OnAbstractFunction, OnVar, - UserInaccessible, - ABIBreakingToAdd, ABIBreakingToRemove, - APIBreakingToAdd, APIBreakingToRemove, - code=144), - ] DEPRECATED_MODIFIER_KINDS = [ From 1957bd60658e0ecd0674c16fe1e1d0d8f38a1580 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 9 Jun 2023 10:14:12 -0400 Subject: [PATCH 05/17] Sema: Reword diagnostics to say 'without a type annotation' instead of 'without more context' --- include/swift/AST/DiagnosticsSema.def | 6 ++-- test/Constraints/closures.swift | 10 +++--- test/Constraints/construction.swift | 2 +- test/Constraints/diagnostics.swift | 2 +- test/Constraints/diagnostics_swift4.swift | 2 +- test/Constraints/if_expr.swift | 4 +-- test/Constraints/one_way_closure_params.swift | 2 +- test/Constraints/operator.swift | 2 +- .../pack-expansion-expressions.swift | 2 +- .../parameterized_existentials.swift | 2 +- test/Constraints/rdar106598067.swift | 2 +- test/Constraints/rdar107724970.swift | 2 +- test/Constraints/rdar85263844_swift6.swift | 2 +- test/Constraints/switch_expr.swift | 2 +- .../variadic_generic_constraints.swift | 2 +- .../foreign-reference/not-any-object.swift | 2 +- ...nline-namespace-function-call-broken.swift | 2 +- test/Macros/macros_diagnostics.swift | 2 +- test/Sema/diag_ambiguous_overloads.swift | 4 +-- test/Sema/discard.swift | 2 +- test/Sema/placeholder_type.swift | 36 +++++++++---------- .../property_wrapper_parameter_invalid.swift | 2 +- ...ntial_member_accesses_self_assoctype.swift | 2 +- test/decl/typealias/generic.swift | 2 +- test/decl/var/property_wrappers_invalid.swift | 6 ++-- test/expr/closure/basic.swift | 2 +- test/expr/closure/closures.swift | 2 +- test/expr/closure/multi_statement.swift | 2 +- test/expr/unary/if_expr.swift | 2 +- .../salvage-with-other-type-errors.swift | 2 +- test/expr/unary/switch_expr.swift | 2 +- .../implicit_some/opaque_parameters.swift | 2 +- test/type/opaque_parameters.swift | 2 +- 33 files changed, 60 insertions(+), 60 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index f6d6e26c7ba03..45da44a5e892d 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -275,10 +275,10 @@ ERROR(no_candidates_match_argument_type,none, (StringRef, Type, unsigned)) ERROR(cannot_infer_closure_parameter_type,none, - "unable to infer type of a closure parameter %0 in the current context", + "cannot infer type of closure parameter %0 without a type annotation", (StringRef)) ERROR(cannot_infer_closure_type,none, - "unable to infer closure type in the current context", ()) + "unable to infer closure type without a type annotation", ()) ERROR(cannot_infer_empty_closure_result_type,none, "cannot infer return type of empty closure", ()) ERROR(cannot_infer_closure_result_type,none, @@ -4126,7 +4126,7 @@ ERROR(could_not_infer_placeholder,none, "could not infer type for placeholder", ()) ERROR(type_of_expression_is_ambiguous,none, - "type of expression is ambiguous without more context", ()) + "type of expression is ambiguous without a type annotation", ()) ERROR(failed_to_produce_diagnostic,Fatal, "failed to produce diagnostic for expression; " diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 5e474a26eae3f..16c4d719be063 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -516,7 +516,7 @@ do { func set_via_closure(_ closure: (inout T, U) -> ()) {} // expected-note {{in call to function 'set_via_closure'}} set_via_closure({ $0.number1 = $1 }) // expected-error@-1 {{generic parameter 'T' could not be inferred}} - // expected-error@-2 {{unable to infer type of a closure parameter '$1' in the current context}} + // expected-error@-2 {{cannot infer type of closure parameter '$1' without a type annotation}} func f2(_ item: T, _ update: (inout T) -> Void) { var x = item @@ -1052,12 +1052,12 @@ overloaded_with_default_and_autoclosure { 42 } // Ok overloaded_with_default_and_autoclosure(42) // Ok /// https://github.com/apple/swift/issues/55261 -/// "error: type of expression is ambiguous without more context" in many cases +/// "error: type of expression is ambiguous without a type annotation" in many cases /// where methods are missing. do { let _ = { a, b in } - // expected-error@-1 {{unable to infer type of a closure parameter 'a' in the current context}} - // expected-error@-2 {{unable to infer type of a closure parameter 'b' in the current context}} + // expected-error@-1 {{cannot infer type of closure parameter 'a' without a type annotation}} + // expected-error@-2 {{cannot infer type of closure parameter 'b' without a type annotation}} _ = .a { b in } // expected-error {{cannot infer contextual base in reference to member 'a'}} @@ -1078,7 +1078,7 @@ let explicitUnboundResult2: (Array) -> Array = { } // FIXME: Should we prioritize the contextual result type and infer Array // rather than using a type variable in these cases? -// expected-error@+1 {{unable to infer closure type in the current context}} +// expected-error@+1 {{unable to infer closure type without a type annotation}} let explicitUnboundResult3: (Array) -> Array = { (arr: Array) -> Array in [true] } diff --git a/test/Constraints/construction.swift b/test/Constraints/construction.swift index 463a0de41fedb..091cdbbe00424 100644 --- a/test/Constraints/construction.swift +++ b/test/Constraints/construction.swift @@ -154,7 +154,7 @@ extension S3 { let s3b = S3(maybe: s3a) // https://github.com/apple/swift/issues/47820 -// Erroneous diagnostic: type of expression is ambiguous without more context +// Erroneous diagnostic: type of expression is ambiguous without a type annotation do { class C { struct S { diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index 2d91c054c6dae..9b701c6028974 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -297,7 +297,7 @@ func r18800223(_ i : Int) { } // Bogus "'_' can only appear in a pattern or on the left side of an assignment" is back -_ = { $0 } // expected-error {{unable to infer type of a closure parameter '$0' in the current context}} +_ = { $0 } // expected-error {{cannot infer type of closure parameter '$0' without a type annotation}} diff --git a/test/Constraints/diagnostics_swift4.swift b/test/Constraints/diagnostics_swift4.swift index c95d498418f34..f1a73c4cb0942 100644 --- a/test/Constraints/diagnostics_swift4.swift +++ b/test/Constraints/diagnostics_swift4.swift @@ -29,7 +29,7 @@ class C_45110: P_45110 { let _ = S_45110(arg: [C_45110()]) // expected-error {{extraneous argument label 'arg:' in call}} -// rdar://problem/31898542 - Swift 4: 'type of expression is ambiguous without more context' errors, without a fixit +// rdar://problem/31898542 - Swift 4: 'type of expression is ambiguous without a type annotation' errors, without a fixit enum R31898542 { case success(T) // expected-note {{'success' declared here}} diff --git a/test/Constraints/if_expr.swift b/test/Constraints/if_expr.swift index be0edebf15d51..21ef22247952e 100644 --- a/test/Constraints/if_expr.swift +++ b/test/Constraints/if_expr.swift @@ -90,7 +90,7 @@ func testNil3(_ x: Bool) { } func testNil4(_ x: Bool) { // FIXME: Bad diagnostic (#63130) - let _: _? = if x { nil } else { 42 } // expected-error {{type of expression is ambiguous without more context}} + let _: _? = if x { nil } else { 42 } // expected-error {{type of expression is ambiguous without a type annotation}} } enum F { @@ -137,7 +137,7 @@ struct SQ : Q { func testAssociatedTypeReturn1() { func fn(_ fn: (T) -> T.X) {} - fn { x in // expected-error {{unable to infer type of a closure parameter 'x' in the current context}} + fn { x in // expected-error {{cannot infer type of closure parameter 'x' without a type annotation}} if .random() { "" } else { "" } } fn { (x: SQ) in diff --git a/test/Constraints/one_way_closure_params.swift b/test/Constraints/one_way_closure_params.swift index d86c05910038f..60615ea3bd0ca 100644 --- a/test/Constraints/one_way_closure_params.swift +++ b/test/Constraints/one_way_closure_params.swift @@ -3,6 +3,6 @@ func testBasic() { let _: (Float) -> Float = { $0 + 1 } - let _ = { $0 + 1 } // expected-error{{unable to infer type of a closure parameter '$0' in the current context}} + let _ = { $0 + 1 } // expected-error{{cannot infer type of closure parameter '$0' without a type annotation}} } diff --git a/test/Constraints/operator.swift b/test/Constraints/operator.swift index b08c7caba9928..ae5490e1c4731 100644 --- a/test/Constraints/operator.swift +++ b/test/Constraints/operator.swift @@ -284,7 +284,7 @@ func rdar60727310() { // FIXME: Bad diagnostic. func f_54877(_ e: Error) { func foo(_ a: T, _ op: ((T, T) -> Bool)) {} - foo(e, ==) // expected-error {{type of expression is ambiguous without more context}} + foo(e, ==) // expected-error {{type of expression is ambiguous without a type annotation}} } // rdar://problem/62054241 - Swift compiler crashes when passing < as the sort function in sorted(by:) and the type of the array is not comparable diff --git a/test/Constraints/pack-expansion-expressions.swift b/test/Constraints/pack-expansion-expressions.swift index 37f74572930cc..b773c333cc3c5 100644 --- a/test/Constraints/pack-expansion-expressions.swift +++ b/test/Constraints/pack-expansion-expressions.swift @@ -475,7 +475,7 @@ do { } } -// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without more context` +// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without a type annotation` do { func test_correct_each(_ value: repeat each T) -> (repeat each T.A) { return (repeat (each value).makeA()) // Ok diff --git a/test/Constraints/parameterized_existentials.swift b/test/Constraints/parameterized_existentials.swift index e2165647f57ca..f8cc8a15d0040 100644 --- a/test/Constraints/parameterized_existentials.swift +++ b/test/Constraints/parameterized_existentials.swift @@ -6,7 +6,7 @@ protocol P { func f1(x: any P) -> any P { // FIXME: Bad diagnostic - return x // expected-error {{type of expression is ambiguous without more context}} + return x // expected-error {{type of expression is ambiguous without a type annotation}} } func f2(x: any P) -> any P { diff --git a/test/Constraints/rdar106598067.swift b/test/Constraints/rdar106598067.swift index 941bbae2f2a2e..0cacec43cf8b2 100644 --- a/test/Constraints/rdar106598067.swift +++ b/test/Constraints/rdar106598067.swift @@ -5,7 +5,7 @@ enum E: Error { case e } // rdar://106598067 – Make sure we don't crash. // FIXME: Bad diagnostic (the issue is that it should be written 'as', not 'as?') let fn = { - // expected-error@-1 {{unable to infer closure type in the current context}} + // expected-error@-1 {{unable to infer closure type without a type annotation}} do {} catch let x as? E {} // expected-warning@-1 {{'catch' block is unreachable because no errors are thrown in 'do' block}} } diff --git a/test/Constraints/rdar107724970.swift b/test/Constraints/rdar107724970.swift index 2008a8907b934..f12c9c84d16b2 100644 --- a/test/Constraints/rdar107724970.swift +++ b/test/Constraints/rdar107724970.swift @@ -8,7 +8,7 @@ func foo(_ x: E) { // FIXME: We need to handle pattern arguments in a bunch of places in argument // list diagnostic logic. // https://github.com/apple/swift/issues/65062 - let fn = { // expected-error {{unable to infer closure type in the current context}} + let fn = { // expected-error {{unable to infer closure type without a type annotation}} switch x { case E.e(_, _): break diff --git a/test/Constraints/rdar85263844_swift6.swift b/test/Constraints/rdar85263844_swift6.swift index b6744ed5d7054..24a3ac4461854 100644 --- a/test/Constraints/rdar85263844_swift6.swift +++ b/test/Constraints/rdar85263844_swift6.swift @@ -32,5 +32,5 @@ extension S4 where T == (outer: Int, y: Int) { public func rdar85263844_2(_ x: [Int]) -> S4<(outer: Int, y: Int)> { // FIXME: Bad error message. - S4(x.map { (inner: $0, y: $0) }) // expected-error {{type of expression is ambiguous without more context}} + S4(x.map { (inner: $0, y: $0) }) // expected-error {{type of expression is ambiguous without a type annotation}} } diff --git a/test/Constraints/switch_expr.swift b/test/Constraints/switch_expr.swift index de8e3080afe45..b1b53a8d52000 100644 --- a/test/Constraints/switch_expr.swift +++ b/test/Constraints/switch_expr.swift @@ -208,7 +208,7 @@ func testNil3(_ x: Bool) { } func testNil4(_ x: Bool) { // FIXME: Bad diagnostic (#63130) - let _: _? = switch x { case true: nil case false: 42 } // expected-error {{type of expression is ambiguous without more context}} + let _: _? = switch x { case true: nil case false: 42 } // expected-error {{type of expression is ambiguous without a type annotation}} } enum G { diff --git a/test/Constraints/variadic_generic_constraints.swift b/test/Constraints/variadic_generic_constraints.swift index 21b17a6b654a5..1748a4d9058b1 100644 --- a/test/Constraints/variadic_generic_constraints.swift +++ b/test/Constraints/variadic_generic_constraints.swift @@ -41,7 +41,7 @@ takesAnyObject() takesAnyObject(C(), C(), C()) // FIXME: Bad diagnostic -takesAnyObject(C(), S(), C()) // expected-error {{type of expression is ambiguous without more context}} +takesAnyObject(C(), S(), C()) // expected-error {{type of expression is ambiguous without a type annotation}} // Same-type requirements diff --git a/test/Interop/Cxx/foreign-reference/not-any-object.swift b/test/Interop/Cxx/foreign-reference/not-any-object.swift index 0dd58c714d4c8..c29742f5baa96 100644 --- a/test/Interop/Cxx/foreign-reference/not-any-object.swift +++ b/test/Interop/Cxx/foreign-reference/not-any-object.swift @@ -26,4 +26,4 @@ import Test; public func test(_ _: AnyObject) {} // TODO: make this a better error. -test(Empty.create()) // expected-error {{type of expression is ambiguous without more context}} +test(Empty.create()) // expected-error {{type of expression is ambiguous without a type annotation}} diff --git a/test/Interop/Cxx/namespace/inline-namespace-function-call-broken.swift b/test/Interop/Cxx/namespace/inline-namespace-function-call-broken.swift index 4c592a4ece8f9..93606f6d589f0 100644 --- a/test/Interop/Cxx/namespace/inline-namespace-function-call-broken.swift +++ b/test/Interop/Cxx/namespace/inline-namespace-function-call-broken.swift @@ -22,5 +22,5 @@ import namespaces; // Swift's typechecker currently doesn't allow calling a function from inline namespace when it's referenced through the parent namespace. func test() { - Parent.functionInInlineChild() // expected-error {{type of expression is ambiguous without more context}} + Parent.functionInInlineChild() // expected-error {{type of expression is ambiguous without a type annotation}} } diff --git a/test/Macros/macros_diagnostics.swift b/test/Macros/macros_diagnostics.swift index 429ac87f77fc5..22fc110bff78d 100644 --- a/test/Macros/macros_diagnostics.swift +++ b/test/Macros/macros_diagnostics.swift @@ -97,7 +97,7 @@ macro genericDeclMacro(_ x: T, _ y: U) func testDiags(a: Int, b: Int) { // FIXME: Bad diagnostic. - let s = #stringify(a + b) // expected-error{{type of expression is ambiguous without more context}} + let s = #stringify(a + b) // expected-error{{type of expression is ambiguous without a type annotation}} _ = #stringify() // expected-error@-1{{missing argument for parameter #1 in macro expansion}} diff --git a/test/Sema/diag_ambiguous_overloads.swift b/test/Sema/diag_ambiguous_overloads.swift index 880a06b86d6f5..ef49f64f7df42 100644 --- a/test/Sema/diag_ambiguous_overloads.swift +++ b/test/Sema/diag_ambiguous_overloads.swift @@ -16,14 +16,14 @@ fe(.nope, .nyet) // expected-error {{type 'Int' has no member 'nope'}} // expected-error@-1 {{reference to member 'nyet' cannot be resolved without a contextual type}} func fg(_ f: (T) -> T) -> Void {} -fg({x in x}) // expected-error {{unable to infer type of a closure parameter 'x' in the current context}} +fg({x in x}) // expected-error {{cannot infer type of closure parameter 'x' without a type annotation}} struct S { func f(_ i: (T) -> T, _ j: Int) -> Void {} func f(_ d: (Double) -> Double) -> Void {} func test() -> Void { - f({x in x}, 2) // expected-error {{unable to infer type of a closure parameter 'x' in the current context}} + f({x in x}, 2) // expected-error {{cannot infer type of closure parameter 'x' without a type annotation}} } func g(_ a: T, _ b: Int) -> Void {} diff --git a/test/Sema/discard.swift b/test/Sema/discard.swift index b0750dc5899fa..076a6c8af1e4c 100644 --- a/test/Sema/discard.swift +++ b/test/Sema/discard.swift @@ -97,7 +97,7 @@ enum E: Error { case err } discard (self) // expected-error {{cannot convert value of type 'File' to expected argument type 'Int'}} // FIXME: we should get an error about it being illegal to discard in a closure. - let _ = { // expected-error {{type of expression is ambiguous without more context}} + let _ = { // expected-error {{type of expression is ambiguous without a type annotation}} discard self return 0 }() diff --git a/test/Sema/placeholder_type.swift b/test/Sema/placeholder_type.swift index 953ba4fc50102..30ee41463ae98 100644 --- a/test/Sema/placeholder_type.swift +++ b/test/Sema/placeholder_type.swift @@ -147,15 +147,15 @@ let _ = [_].otherStaticMember.method() func f(x: Any, arr: [Int]) { // FIXME: Better diagnostics here. Maybe we should suggest replacing placeholders with 'Any'? - if x is _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}} - if x is [_] {} // expected-error {{type of expression is ambiguous without more context}} - if x is () -> _ {} // expected-error {{type of expression is ambiguous without more context}} - if let y = x as? _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}} - if let y = x as? [_] {} // expected-error {{type of expression is ambiguous without more context}} - if let y = x as? () -> _ {} // expected-error {{type of expression is ambiguous without more context}} - let y1 = x as! _ // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}} - let y2 = x as! [_] // expected-error {{type of expression is ambiguous without more context}} - let y3 = x as! () -> _ // expected-error {{type of expression is ambiguous without more context}} + if x is _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without a type annotation}} + if x is [_] {} // expected-error {{type of expression is ambiguous without a type annotation}} + if x is () -> _ {} // expected-error {{type of expression is ambiguous without a type annotation}} + if let y = x as? _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without a type annotation}} + if let y = x as? [_] {} // expected-error {{type of expression is ambiguous without a type annotation}} + if let y = x as? () -> _ {} // expected-error {{type of expression is ambiguous without a type annotation}} + let y1 = x as! _ // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without a type annotation}} + let y2 = x as! [_] // expected-error {{type of expression is ambiguous without a type annotation}} + let y3 = x as! () -> _ // expected-error {{type of expression is ambiguous without a type annotation}} switch x { case is _: break // expected-error {{type placeholder not allowed here}} @@ -166,15 +166,15 @@ func f(x: Any, arr: [Int]) { case let y as () -> _: break // expected-error {{type placeholder not allowed here}} } - if arr is _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}} - if arr is [_] {} // expected-error {{type of expression is ambiguous without more context}} - if arr is () -> _ {} // expected-error {{type of expression is ambiguous without more context}} - if let y = arr as? _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}} - if let y = arr as? [_] {} // expected-error {{type of expression is ambiguous without more context}} - if let y = arr as? () -> _ {} // expected-error {{type of expression is ambiguous without more context}} - let y1 = arr as! _ // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}} - let y2 = arr as! [_] // expected-error {{type of expression is ambiguous without more context}} - let y3 = arr as! () -> _ // expected-error {{type of expression is ambiguous without more context}} + if arr is _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without a type annotation}} + if arr is [_] {} // expected-error {{type of expression is ambiguous without a type annotation}} + if arr is () -> _ {} // expected-error {{type of expression is ambiguous without a type annotation}} + if let y = arr as? _ {} // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without a type annotation}} + if let y = arr as? [_] {} // expected-error {{type of expression is ambiguous without a type annotation}} + if let y = arr as? () -> _ {} // expected-error {{type of expression is ambiguous without a type annotation}} + let y1 = arr as! _ // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without a type annotation}} + let y2 = arr as! [_] // expected-error {{type of expression is ambiguous without a type annotation}} + let y3 = arr as! () -> _ // expected-error {{type of expression is ambiguous without a type annotation}} switch arr { case is _: break // expected-error {{type placeholder not allowed here}} diff --git a/test/Sema/property_wrapper_parameter_invalid.swift b/test/Sema/property_wrapper_parameter_invalid.swift index d0f739a1f17a2..c6d9484fd6348 100644 --- a/test/Sema/property_wrapper_parameter_invalid.swift +++ b/test/Sema/property_wrapper_parameter_invalid.swift @@ -271,7 +271,7 @@ func testInvalidWrapperInference() { S.test({ $value in }) func testGenericClosure(_ closure: T) {} - // expected-error@+1 {{unable to infer type of a closure parameter '$value' in the current context}} + // expected-error@+1 {{cannot infer type of closure parameter '$value' without a type annotation}} testGenericClosure { $value in } testGenericClosure { ($value: ProjectionWrapper) in } // okay diff --git a/test/decl/protocol/existential_member_accesses_self_assoctype.swift b/test/decl/protocol/existential_member_accesses_self_assoctype.swift index c5266766c6fff..280be18b7dc43 100644 --- a/test/decl/protocol/existential_member_accesses_self_assoctype.swift +++ b/test/decl/protocol/existential_member_accesses_self_assoctype.swift @@ -864,7 +864,7 @@ do { // FIXME: Should GenericSignature::getConcreteType return the null type instead // of the error type here for Self.A, despite the broken conformance? let exist: any CompositionBrokenClassConformance_b & BadConformanceClass - exist.method(false) // expected-error {{type of expression is ambiguous without more context}} + exist.method(false) // expected-error {{type of expression is ambiguous without a type annotation}} } /// Covariant Associated Type Erasure diff --git a/test/decl/typealias/generic.swift b/test/decl/typealias/generic.swift index 1935ddeed77f7..3b1e6b4143fb4 100644 --- a/test/decl/typealias/generic.swift +++ b/test/decl/typealias/generic.swift @@ -113,7 +113,7 @@ let _ : D = D(a: 1, b: 2) let _ : F = { (a : Int) -> Int in a } // Infer the types of F -let _ : F = { a in a } // expected-error {{unable to infer type of a closure parameter 'a' in the current context}} +let _ : F = { a in a } // expected-error {{cannot infer type of closure parameter 'a' without a type annotation}} _ = MyType(a: "foo", b: 42) _ = A(a: "foo", b: 42) diff --git a/test/decl/var/property_wrappers_invalid.swift b/test/decl/var/property_wrappers_invalid.swift index 61fb9811289c6..f6b351557598c 100644 --- a/test/decl/var/property_wrappers_invalid.swift +++ b/test/decl/var/property_wrappers_invalid.swift @@ -3,9 +3,9 @@ // FIXME: This should produce a diagnostic with a proper // source location. Right now, we just get three useless errors: -// :0: error: type of expression is ambiguous without more context -// :0: error: type of expression is ambiguous without more context -// :0: error: type of expression is ambiguous without more context +// :0: error: type of expression is ambiguous without a type annotation +// :0: error: type of expression is ambiguous without a type annotation +// :0: error: type of expression is ambiguous without a type annotation // The actual problem is the type of the subscript declaration is wrong. diff --git a/test/expr/closure/basic.swift b/test/expr/closure/basic.swift index 16a9c794e79dc..4f1405bc123e6 100644 --- a/test/expr/closure/basic.swift +++ b/test/expr/closure/basic.swift @@ -26,7 +26,7 @@ func variadic() { _ = f(1, 2) _ = f(1, 3) - let D = { (Ss ...) in 1 } // expected-error{{'...' cannot be applied to a subpattern which is not explicitly typed}}, expected-error{{unable to infer type of a closure parameter 'Ss' in the current context}} + let D = { (Ss ...) in 1 } // expected-error{{'...' cannot be applied to a subpattern which is not explicitly typed}}, expected-error{{cannot infer type of closure parameter 'Ss' without a type annotation}} } // Closures with attributes in the parameter list. diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift index e3dfaf0e178e4..1cb768ff913e5 100644 --- a/test/expr/closure/closures.swift +++ b/test/expr/closure/closures.swift @@ -117,7 +117,7 @@ assert(f0(1) == 1) // TODO(diagnostics): Bad diagnostic - should be `circular reference` var selfRef = { selfRef() } -// expected-error@-1 {{unable to infer closure type in the current context}} +// expected-error@-1 {{unable to infer closure type without a type annotation}} // TODO: should be an error `circular reference` but it's diagnosed via overlapped requests var nestedSelfRef = { diff --git a/test/expr/closure/multi_statement.swift b/test/expr/closure/multi_statement.swift index cded519810447..af4b1dd33c4f4 100644 --- a/test/expr/closure/multi_statement.swift +++ b/test/expr/closure/multi_statement.swift @@ -307,7 +307,7 @@ func test_pattern_matches_only_cases() { } } -// rdar://91225620 - type of expression is ambiguous without more context in closure +// rdar://91225620 - type of expression is ambiguous without a type annotation in closure func test_wrapped_var_without_initializer() { @propertyWrapper struct Wrapper { diff --git a/test/expr/unary/if_expr.swift b/test/expr/unary/if_expr.swift index 58f6f514cbac2..ab88e23a0642a 100644 --- a/test/expr/unary/if_expr.swift +++ b/test/expr/unary/if_expr.swift @@ -504,7 +504,7 @@ do { // FIXME: The type error is likely due to not solving the conjunction before attempting default type var bindings. let _ = (if .random() { Int?.none } else { 1 as Int? })?.bitWidth // expected-error@-1 {{'if' may only be used as expression in return, throw, or as the source of an assignment}} - // expected-error@-2 {{type of expression is ambiguous without more context}} + // expected-error@-2 {{type of expression is ambiguous without a type annotation}} } do { let _ = if .random() { Int?.none } else { 1 as Int? }! diff --git a/test/expr/unary/keypath/salvage-with-other-type-errors.swift b/test/expr/unary/keypath/salvage-with-other-type-errors.swift index 7018e9a93bd87..8c7e5c6872f4d 100644 --- a/test/expr/unary/keypath/salvage-with-other-type-errors.swift +++ b/test/expr/unary/keypath/salvage-with-other-type-errors.swift @@ -44,7 +44,7 @@ struct B { } } func f3() { - B(v: "").f1(block: { _ in }).f2(keyPath: \B.v) // expected-error{{unable to infer type of a closure parameter '_' in the current context}} + B(v: "").f1(block: { _ in }).f2(keyPath: \B.v) // expected-error{{cannot infer type of closure parameter '_' without a type annotation}} } // https://github.com/apple/swift/issues/47949 diff --git a/test/expr/unary/switch_expr.swift b/test/expr/unary/switch_expr.swift index eddb934ac3b1e..b498598375dfb 100644 --- a/test/expr/unary/switch_expr.swift +++ b/test/expr/unary/switch_expr.swift @@ -662,7 +662,7 @@ do { // FIXME: The type error is likely due to not solving the conjunction before attempting default type var bindings. let _ = (switch Bool.random() { case true: Int?.none case false: 1 })?.bitWidth // expected-error@-1 {{'switch' may only be used as expression in return, throw, or as the source of an assignment}} - // expected-error@-2 {{type of expression is ambiguous without more context}} + // expected-error@-2 {{type of expression is ambiguous without a type annotation}} } do { let _ = switch Bool.random() { case true: Int?.none case false: 1 }! diff --git a/test/type/implicit_some/opaque_parameters.swift b/test/type/implicit_some/opaque_parameters.swift index 21bc7e6cfe591..70c9d5556fd33 100644 --- a/test/type/implicit_some/opaque_parameters.swift +++ b/test/type/implicit_some/opaque_parameters.swift @@ -86,5 +86,5 @@ func testPrimaries( takePrimaryCollections(setOfStrings, setOfInts) takePrimaryCollections(setOfStrings, arrayOfInts) _ = takeMatchedPrimaryCollections(arrayOfInts, setOfInts) - _ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without more context}} + _ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without a type annotation}} } diff --git a/test/type/opaque_parameters.swift b/test/type/opaque_parameters.swift index eccbb74445555..824b9d23463b6 100644 --- a/test/type/opaque_parameters.swift +++ b/test/type/opaque_parameters.swift @@ -106,7 +106,7 @@ func testPrimaries( takePrimaryCollections(setOfStrings, setOfInts) takePrimaryCollections(setOfStrings, arrayOfInts) _ = takeMatchedPrimaryCollections(arrayOfInts, setOfInts) - _ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without more context}} + _ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without a type annotation}} } From 4d1d8a9de5ebc132a17aee9fc267461facf89bf8 Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Fri, 9 Jun 2023 15:15:39 -0700 Subject: [PATCH 06/17] [Observation] Add property definite initialization support (#65984) * [Observation] Transition to peer macros instead of arbitrary members * [Observation] Lift the initializer requirement by utilizing init accessors for fully formed definite initialization * [Observation] Gate enabling of peer macros by flag * [Observation] Enable feature for InitAccessors in the observation tests * [Observation] Add tests to validate memberwise and definite initialization --- .../ObservationMacros/ObservableMacro.swift | 28 +++++++++++-------- .../Sources/Observation/Observable.swift | 8 +++++- test/stdlib/Observation/Observable.swift | 20 ++++++++++++- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift b/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift index be1bf85a327e0..60708957d43f7 100644 --- a/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift +++ b/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift @@ -202,17 +202,15 @@ extension ObservableMacro: MemberMacro { declaration.addIfNeeded(ObservableMacro.registrarVariable(observableType), to: &declarations) declaration.addIfNeeded(ObservableMacro.accessFunction(observableType), to: &declarations) declaration.addIfNeeded(ObservableMacro.withMutationFunction(observableType), to: &declarations) - + +#if !OBSERVATION_SUPPORTS_PEER_MACROS let storedInstanceVariables = declaration.definedVariables.filter { $0.isValidForObservation } for property in storedInstanceVariables { - if property.hasMacroApplication(ObservableMacro.ignoredMacroName) { continue } - if property.initializer == nil { - context.addDiagnostics(from: DiagnosticsError(syntax: property, message: "@Observable requires property '\(property.identifier?.text ?? "")' to have an initial value", id: .missingInitializer), node: property) - } - let storage = DeclSyntax(property.privatePrefixed("_", addingAttribute: ObservableMacro.ignoredAttribute)) - declaration.addIfNeeded(storage, to: &declarations) - + if property.hasMacroApplication(ObservableMacro.ignoredMacroName) { continue } + let storage = DeclSyntax(property.privatePrefixed("_", addingAttribute: ObservableMacro.ignoredAttribute)) + declaration.addIfNeeded(storage, to: &declarations) } +#endif return declarations } @@ -293,6 +291,13 @@ public struct ObservationTrackedMacro: AccessorMacro { return [] } + let initAccessor: AccessorDeclSyntax = + """ + init(initialValue) initializes(_\(identifier)) { + _\(identifier) = initialValue + } + """ + let getAccessor: AccessorDeclSyntax = """ get { @@ -310,7 +315,7 @@ public struct ObservationTrackedMacro: AccessorMacro { } """ - return [getAccessor, setAccessor] + return [initAccessor, getAccessor, setAccessor] } } @@ -327,8 +332,9 @@ extension ObservationTrackedMacro: PeerMacro { property.isValidForObservation else { return [] } - - if property.hasMacroApplication(ObservableMacro.ignoredMacroName) { + + if property.hasMacroApplication(ObservableMacro.ignoredMacroName) || + property.hasMacroApplication(ObservableMacro.trackedMacroName) { return [] } diff --git a/stdlib/public/Observation/Sources/Observation/Observable.swift b/stdlib/public/Observation/Sources/Observation/Observable.swift index 19a4012f93a1d..a2f837af85db3 100644 --- a/stdlib/public/Observation/Sources/Observation/Observable.swift +++ b/stdlib/public/Observation/Sources/Observation/Observable.swift @@ -16,7 +16,11 @@ #if $Macros && hasAttribute(attached) @available(SwiftStdlib 5.9, *) +#if OBSERVATION_SUPPORTS_PEER_MACROS +@attached(member, names: named(_$observationRegistrar), named(access), named(withMutation)) +#else @attached(member, names: named(_$observationRegistrar), named(access), named(withMutation), arbitrary) +#endif @attached(memberAttribute) @attached(conformance) public macro Observable() = @@ -24,7 +28,9 @@ public macro Observable() = @available(SwiftStdlib 5.9, *) @attached(accessor) -// @attached(peer, names: prefixed(_)) +#if OBSERVATION_SUPPORTS_PEER_MACROS +@attached(peer, names: prefixed(_)) +#endif public macro ObservationTracked() = #externalMacro(module: "ObservationMacros", type: "ObservationTrackedMacro") diff --git a/test/stdlib/Observation/Observable.swift b/test/stdlib/Observation/Observable.swift index 886bbf15a19de..1fef61087f849 100644 --- a/test/stdlib/Observation/Observable.swift +++ b/test/stdlib/Observation/Observable.swift @@ -1,6 +1,6 @@ // REQUIRES: swift_swift_parser, executable_test -// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library -enable-experimental-feature Macros -Xfrontend -plugin-path -Xfrontend %swift-host-lib-dir/plugins) +// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library -enable-experimental-feature InitAccessors -enable-experimental-feature Macros -Xfrontend -plugin-path -Xfrontend %swift-host-lib-dir/plugins) // REQUIRES: observation // REQUIRES: concurrency @@ -23,6 +23,24 @@ struct Structure { var field: Int = 0 } +@Observable +struct MemberwiseInitializers { + var field: Int +} + +func validateMemberwiseInitializers() { + _ = MemberwiseInitializers(field: 3) +} + +@Observable +struct DefiniteInitialization { + var field: Int + + init(field: Int) { + self.field = field + } +} + @Observable class ContainsWeak { weak var obj: AnyObject? = nil From 04ecc35d35ce064441ccd64b6574780eecb65314 Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Fri, 9 Jun 2023 19:21:08 -0700 Subject: [PATCH 07/17] [Observation] Ensure type access is qualified to the module name (#66364) --- .../ObservationMacros/ObservableMacro.swift | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift b/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift index 60708957d43f7..8ed72c34d369d 100644 --- a/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift +++ b/lib/Macros/Sources/ObservationMacros/ObservableMacro.swift @@ -17,6 +17,22 @@ import SwiftSyntaxMacros @_implementationOnly import SwiftSyntaxBuilder public struct ObservableMacro { + static let moduleName = "_Observation" + + static let conformanceName = "Observable" + static var qualifiedConformanceName: String { + return "\(moduleName).\(conformanceName)" + } + + static var observableConformanceType: TypeSyntax { + "\(raw: qualifiedConformanceName)" + } + + static let registrarTypeName = "ObservationRegistrar" + static var qualifiedRegistrarTypeName: String { + return "\(moduleName).\(registrarTypeName)" + } + static let trackedMacroName = "ObservationTracked" static let ignoredMacroName = "ObservationIgnored" @@ -25,7 +41,7 @@ public struct ObservableMacro { static func registrarVariable(_ observableType: TokenSyntax) -> DeclSyntax { return """ - @\(raw: ignoredMacroName) private let \(raw: registrarVariableName) = ObservationRegistrar() + @\(raw: ignoredMacroName) private let \(raw: registrarVariableName) = \(raw: qualifiedRegistrarTypeName)() """ } @@ -262,13 +278,13 @@ extension ObservableMacro: ConformanceMacro { if let inheritanceList { for inheritance in inheritanceList { - if inheritance.typeName.identifier == "Observable" { + if inheritance.typeName.identifier == ObservableMacro.conformanceName { return [] } } } - return [("Observable", nil)] + return [(ObservableMacro.observableConformanceType, nil)] } } From 91d547f9822339da52b3d08c0975d83d308ab517 Mon Sep 17 00:00:00 2001 From: Dario Rexin Date: Fri, 9 Jun 2023 23:02:34 -0700 Subject: [PATCH 08/17] [Runtime] Properly handle unaligned reads in readTagBytes for layout strings (#66506) --- stdlib/public/runtime/BytecodeLayouts.cpp | 24 ++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/stdlib/public/runtime/BytecodeLayouts.cpp b/stdlib/public/runtime/BytecodeLayouts.cpp index 0917e98331e58..a40cab1eb34f5 100644 --- a/stdlib/public/runtime/BytecodeLayouts.cpp +++ b/stdlib/public/runtime/BytecodeLayouts.cpp @@ -182,12 +182,21 @@ static uint64_t readTagBytes(uint8_t *addr, uint8_t byteCount) { switch (byteCount) { case 1: return addr[0]; - case 2: - return ((uint16_t *)addr)[0]; - case 4: - return ((uint32_t *)addr)[0]; - case 8: - return ((uint64_t *)addr)[0]; + case 2: { + uint16_t res = 0; + memcpy(&res, addr, sizeof(uint16_t)); + return res; + } + case 4: { + uint32_t res = 0; + memcpy(&res, addr, sizeof(uint32_t)); + return res; + } + case 8: { + uint64_t res = 0; + memcpy(&res, addr, sizeof(uint64_t)); + return res; + } default: swift_unreachable("Unsupported tag byte length."); } @@ -608,7 +617,8 @@ void swift::swift_resolve_resilientAccessors(uint8_t *layoutStr, writeBytes(layoutStr, writeOffset, getEnumTag); size_t numCases = readBytes(fieldLayoutStr, i); - size_t refCountBytes = readBytes(fieldLayoutStr, i); + // skip ref count bytes + i += sizeof(size_t); size_t casesBeginOffset = layoutStrOffset + i + (numCases * sizeof(size_t)); From 1c0aaef854dd244b6d08e31ee801b414effaf788 Mon Sep 17 00:00:00 2001 From: Evan Wilde Date: Fri, 9 Jun 2023 23:22:39 -0700 Subject: [PATCH 09/17] Updating docs with new CI triggers --- docs/ContinuousIntegration.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md index 9c4ded2463cd2..1d943d62bf362 100644 --- a/docs/ContinuousIntegration.md +++ b/docs/ContinuousIntegration.md @@ -159,6 +159,16 @@ Platform | Comment | Check Status macOS platform | @swift-ci Please Build Toolchain macOS Platform| Swift Build Toolchain macOS Platform Linux platform | @swift-ci Please Build Toolchain Linux Platform| Swift Build Toolchain Linux Platform +You can also build a toolchain for a specific Linux distribution + +Distro | Comment | Check Status +-------------- | ----------------------------------------- | ---------------------------------------------- +UBI9 | @swift-ci build toolchain UBI9 | Swift Build Toolchain UBI9 (x86_64) +CentOS 7 | @swift-ci build toolchain CentOS 7 | Swift Build Toolchain CentOS 7 (x86_64) +Ubuntu 18.04 | @swift-ci build toolchain Ubuntu 18.04 | Swift Build Toolchain Ubuntu 18.04 (x86_64) +Ubuntu 22.04 | @swift-ci build toolchain Ubuntu 22.04 | Swift Build Toolchain Ubuntu 22.04 (x86_64) +Amazon Linux 2 | @swift-ci build toolchain Amazon Linux 2 | Swift Build Toolchain Amazon Linux 2 (x86_64) + ### Build and Test Stdlib against Snapshot Toolchain To test/build the stdlib for a branch that changes only the stdlib using a last known good snapshot toolchain: From c78afdc6d15f05ade0c42bdddf098d3b676345f5 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 9 Jun 2023 21:51:26 -0700 Subject: [PATCH 10/17] [Macros] Tighten restriction on non-expression macros not having return types There is no reason to special-case `Void` to permit it. Rather, make this a syntactic rule. Thanks to Alex Hoppen for the suggestion. --- lib/Sema/TypeCheckDeclPrimary.cpp | 5 ++--- test/Macros/attached_macros_diags.swift | 6 +++--- test/Macros/macros_diagnostics.swift | 3 +++ test/Macros/parsing.swift | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 91ed49d6f040f..d707b376d61b6 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2072,11 +2072,10 @@ class DeclChecker : public DeclVisitor { } } - // If the macro has a (non-Void) result type, it must have the freestanding + // If the macro has a result type, it must have the freestanding // expression role. Other roles cannot have result types. if (auto resultTypeRepr = MD->getResultTypeRepr()) { - if (!MD->getMacroRoles().contains(MacroRole::Expression) && - !MD->getResultInterfaceType()->isEqual(Ctx.getVoidType())) { + if (!MD->getMacroRoles().contains(MacroRole::Expression)) { auto resultType = MD->getResultInterfaceType(); Ctx.Diags.diagnose( MD->arrowLoc, diag::macro_result_type_cannot_be_used, resultType) diff --git a/test/Macros/attached_macros_diags.swift b/test/Macros/attached_macros_diags.swift index bc592ed27bd86..636d8deb07476 100644 --- a/test/Macros/attached_macros_diags.swift +++ b/test/Macros/attached_macros_diags.swift @@ -6,17 +6,17 @@ // expected-warning@-1{{external macro implementation type 'MyMacros.Macro1' could not be found for macro 'm1()'}} // expected-note@-2{{'m1()' declared here}} -@attached(accessor) macro m2(_: Int) -> Void = #externalMacro(module: "MyMacros", type: "Macro2") +@attached(accessor) macro m2(_: Int) = #externalMacro(module: "MyMacros", type: "Macro2") // expected-warning@-1{{external macro implementation type 'MyMacros.Macro2' could not be found for macro 'm2'}} // expected-note@-2{{candidate has partially matching parameter list (Int)}} // expected-note@-3{{candidate expects value of type 'Int' for parameter #1 (got 'String')}} -@attached(accessor) macro m2(_: Double) -> Void = #externalMacro(module: "MyMacros", type: "Macro2") +@attached(accessor) macro m2(_: Double) = #externalMacro(module: "MyMacros", type: "Macro2") // expected-warning@-1{{external macro implementation type 'MyMacros.Macro2' could not be found for macro 'm2'}} // expected-note@-2{{candidate has partially matching parameter list (Double)}} // expected-note@-3{{candidate expects value of type 'Double' for parameter #1 (got 'String')}} -@attached(accessor) macro m3(message: String) -> Void = #externalMacro(module: "MyMacros", type: "Macro3") +@attached(accessor) macro m3(message: String) = #externalMacro(module: "MyMacros", type: "Macro3") // expected-warning@-1{{external macro implementation type 'MyMacros.Macro3' could not be found for macro 'm3(message:)'}} @freestanding(expression) macro stringify(_ value: T) -> (T, String) = #externalMacro(module: "MyMacros", type: "StringifyMacro") diff --git a/test/Macros/macros_diagnostics.swift b/test/Macros/macros_diagnostics.swift index 2f9b00a44716e..21acc484a0b44 100644 --- a/test/Macros/macros_diagnostics.swift +++ b/test/Macros/macros_diagnostics.swift @@ -211,6 +211,9 @@ struct SomeType { @freestanding(declaration) macro nonExpressionReturnsVoid(_: T) -> Void = #externalMacro(module: "A", type: "B") // expected-warning@-1{{external macro implementation type}} +// expected-error@-2{{only a freestanding expression macro can produce a result of type 'Void'}} +// expected-note@-3{{make this macro a freestanding expression macro}}{{1-1=@freestanding(expression)\n}} +// expected-note@-4{{remove the result type if the macro does not produce a value}}{{68-76=}} @freestanding(expression) diff --git a/test/Macros/parsing.swift b/test/Macros/parsing.swift index f4380d1ecfd24..ffc039386d8d7 100644 --- a/test/Macros/parsing.swift +++ b/test/Macros/parsing.swift @@ -51,7 +51,7 @@ macro am1() named, // expected-error{{introduced name kind 'named' requires a single argument '(name)'}} arbitrary(a) // expected-error{{introduced name kind 'arbitrary' must not have an argument}} ) -macro am2() -> Void +macro am2() // expected-error@-1{{macro 'am2()' requires a definition}} #m1 + 1 From 7fb1ba9798696ced0c7e245c89d9db88ff2cae42 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 9 Jun 2023 23:16:57 -0700 Subject: [PATCH 11/17] [AST printer] Stop printing `-> ()` types on all macro declarations. --- lib/AST/ASTPrinter.cpp | 8 +++----- test/ModuleInterface/macros.swift | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 15b4c7a67a6e1..bff08aa14dd7c 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4811,16 +4811,14 @@ void PrintAST::visitMacroDecl(MacroDecl *decl) { } ); - { + if (decl->resultType.getTypeRepr() || + !decl->getResultInterfaceType()->isVoid()) { Printer.printStructurePre(PrintStructureKind::DeclResultTypeClause); SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::DeclResultTypeClause); }; - if (decl->parameterList) - Printer << " -> "; - else - Printer << ": "; + Printer << " -> "; TypeLoc resultTypeLoc( decl->resultType.getTypeRepr(), decl->getResultInterfaceType()); diff --git a/test/ModuleInterface/macros.swift b/test/ModuleInterface/macros.swift index 57af7ecbafbfa..63ea8332a7ad3 100644 --- a/test/ModuleInterface/macros.swift +++ b/test/ModuleInterface/macros.swift @@ -30,14 +30,14 @@ @freestanding(expression) public macro publicLine() -> T = #externalMacro(module: "SomeModule", type: "Line") // CHECK: #if compiler(>=5.3) && $Macros -// CHECK: @attached(accessor) public macro myWrapper() -> () = #externalMacro(module: "SomeModule", type: "Wrapper") +// CHECK: @attached(accessor) public macro myWrapper() = #externalMacro(module: "SomeModule", type: "Wrapper") // CHECK-NEXT: #endif @attached(accessor) public macro myWrapper() = #externalMacro(module: "SomeModule", type: "Wrapper") // CHECK: #if compiler(>=5.3) && $Macros && $AttachedMacros -// CHECK: @attached(member, names: named(`init`), prefixed(`$`)) public macro MemberwiseInit() -> () = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro") +// CHECK: @attached(member, names: named(`init`), prefixed(`$`)) public macro MemberwiseInit() = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro") // CHECK-NEXT: #endif -@attached(member, names: named(init), prefixed(`$`)) public macro MemberwiseInit() -> () = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro") +@attached(member, names: named(init), prefixed(`$`)) public macro MemberwiseInit() = #externalMacro(module: "SomeModule", type: "MemberwiseInitMacro") // CHECK-NOT: internalStringify @freestanding(expression) macro internalStringify(_ value: T) -> (T, String) = #externalMacro(module: "SomeModule", type: "StringifyMacro") From f7de3a3590711569ffd93e081eb25f228829416c Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 9 Jun 2023 23:22:09 -0700 Subject: [PATCH 12/17] [Macros] Downgrade "void return for non-expression macro" error in interfaces This allows us to continue to accept Swift interface files created with older versions of the Swift 5.9 compiler that emitted a spurious `-> ()` on non-expression macro declarations. --- lib/Sema/TypeCheckDeclPrimary.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index d707b376d61b6..a0ecff79ba60c 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2076,10 +2076,21 @@ class DeclChecker : public DeclVisitor { // expression role. Other roles cannot have result types. if (auto resultTypeRepr = MD->getResultTypeRepr()) { if (!MD->getMacroRoles().contains(MacroRole::Expression)) { - auto resultType = MD->getResultInterfaceType(); - Ctx.Diags.diagnose( - MD->arrowLoc, diag::macro_result_type_cannot_be_used, resultType) - .highlight(resultTypeRepr->getSourceRange()); + auto resultType = MD->getResultInterfaceType(); { + auto diag = Ctx.Diags.diagnose( + MD->arrowLoc, diag::macro_result_type_cannot_be_used, resultType); + diag.highlight(resultTypeRepr->getSourceRange()); + + // In a .swiftinterface file, downgrade this diagnostic to a warning. + // This allows the compiler to process existing .swiftinterface + // files that contain this issue. + if (resultType->isVoid()) { + if (auto sourceFile = MD->getParentSourceFile()) + if (sourceFile->Kind == SourceFileKind::Interface) + diag.limitBehavior(DiagnosticBehavior::Warning); + } + } + Ctx.Diags.diagnose(MD->arrowLoc, diag::macro_make_freestanding_expression) .fixItInsert(MD->getAttributeInsertionLoc(false), "@freestanding(expression)\n"); From 0bd1c51c85828d35476d4e9275938eb31c4f4df4 Mon Sep 17 00:00:00 2001 From: Mishal Shah Date: Fri, 9 Jun 2023 23:52:53 -0700 Subject: [PATCH 13/17] Update the trigger for Ubuntu 22.04 --- docs/ContinuousIntegration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md index 1d943d62bf362..f949c72670226 100644 --- a/docs/ContinuousIntegration.md +++ b/docs/ContinuousIntegration.md @@ -157,7 +157,7 @@ macOS platform | @swift-ci Please Sourcekit Stress test | Swift Sourcekit Stress Platform | Comment | Check Status ------------ | ------- | ------------ macOS platform | @swift-ci Please Build Toolchain macOS Platform| Swift Build Toolchain macOS Platform -Linux platform | @swift-ci Please Build Toolchain Linux Platform| Swift Build Toolchain Linux Platform +Linux platform | @swift-ci Please Build Toolchain Linux Platform| Swift Build Toolchain Ubuntu 22.04 (x86_64) You can also build a toolchain for a specific Linux distribution @@ -166,6 +166,7 @@ Distro | Comment | Check Status UBI9 | @swift-ci build toolchain UBI9 | Swift Build Toolchain UBI9 (x86_64) CentOS 7 | @swift-ci build toolchain CentOS 7 | Swift Build Toolchain CentOS 7 (x86_64) Ubuntu 18.04 | @swift-ci build toolchain Ubuntu 18.04 | Swift Build Toolchain Ubuntu 18.04 (x86_64) +Ubuntu 20.04 | @swift-ci build toolchain Ubuntu 20.04 | Swift Build Toolchain Ubuntu 20.04 (x86_64) Ubuntu 22.04 | @swift-ci build toolchain Ubuntu 22.04 | Swift Build Toolchain Ubuntu 22.04 (x86_64) Amazon Linux 2 | @swift-ci build toolchain Amazon Linux 2 | Swift Build Toolchain Amazon Linux 2 (x86_64) From 51c2af639ed428caa12baecab78fd1fd24bca130 Mon Sep 17 00:00:00 2001 From: Mishal Shah Date: Fri, 9 Jun 2023 23:56:27 -0700 Subject: [PATCH 14/17] Update the build toolchain to `Please Build Toolchain` --- docs/ContinuousIntegration.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md index f949c72670226..364be5f0a35ce 100644 --- a/docs/ContinuousIntegration.md +++ b/docs/ContinuousIntegration.md @@ -161,14 +161,14 @@ Linux platform | @swift-ci Please Build Toolchain Linux Platform| Swift Build To You can also build a toolchain for a specific Linux distribution -Distro | Comment | Check Status --------------- | ----------------------------------------- | ---------------------------------------------- -UBI9 | @swift-ci build toolchain UBI9 | Swift Build Toolchain UBI9 (x86_64) -CentOS 7 | @swift-ci build toolchain CentOS 7 | Swift Build Toolchain CentOS 7 (x86_64) -Ubuntu 18.04 | @swift-ci build toolchain Ubuntu 18.04 | Swift Build Toolchain Ubuntu 18.04 (x86_64) -Ubuntu 20.04 | @swift-ci build toolchain Ubuntu 20.04 | Swift Build Toolchain Ubuntu 20.04 (x86_64) -Ubuntu 22.04 | @swift-ci build toolchain Ubuntu 22.04 | Swift Build Toolchain Ubuntu 22.04 (x86_64) -Amazon Linux 2 | @swift-ci build toolchain Amazon Linux 2 | Swift Build Toolchain Amazon Linux 2 (x86_64) +Distro | Comment | Check Status +-------------- | ------------------------------------------------ | ---------------------------------------------- +UBI9 | @swift-ci Please Build Toolchain UBI9 | Swift Build Toolchain UBI9 (x86_64) +CentOS 7 | @swift-ci Please Build Toolchain CentOS 7 | Swift Build Toolchain CentOS 7 (x86_64) +Ubuntu 18.04 | @swift-ci Please Build Toolchain Ubuntu 18.04 | Swift Build Toolchain Ubuntu 18.04 (x86_64) +Ubuntu 20.04 | @swift-ci Please Build Toolchain Ubuntu 20.04 | Swift Build Toolchain Ubuntu 20.04 (x86_64) +Ubuntu 22.04 | @swift-ci Please Build Toolchain Ubuntu 22.04 | Swift Build Toolchain Ubuntu 22.04 (x86_64) +Amazon Linux 2 | @swift-ci Please Build Toolchain Amazon Linux 2 | Swift Build Toolchain Amazon Linux 2 (x86_64) ### Build and Test Stdlib against Snapshot Toolchain From 330af0b8d1ec37107699022da580c80569f937a2 Mon Sep 17 00:00:00 2001 From: Mishal Shah Date: Sat, 10 Jun 2023 00:00:00 -0700 Subject: [PATCH 15/17] Remove out of date triggers --- docs/ContinuousIntegration.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md index 364be5f0a35ce..14c858974dc55 100644 --- a/docs/ContinuousIntegration.md +++ b/docs/ContinuousIntegration.md @@ -286,9 +286,6 @@ Currently, supported pull request testing triggers: Platform | Comment | Check Status ------------ | ------- | ------------ Windows | @swift-ci Please test Windows platform | Swift Test Windows Platform -Linux | @swift-ci Please test Tensorflow Linux platform | Swift Test Linux Platform (TensorFlow) -Linux (GPU) | @swift-ci Please test Tensorflow Linux GPU platform |Swift Test Linux Platform with GPU (TensorFlow) -macOS | @swift-ci Please test Tensorflow macOS platform | Swift Test macOS Platform (TensorFlow) ## ci.swift.org bots From 3198412db00b03e9131dcf3cbdfbe889a8665fd7 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 10 Jun 2023 10:00:19 +0000 Subject: [PATCH 16/17] [wasm][stdlib] Fix return-address strategy selection __GNUC__ can be defined on Wasm targets as well, so we need to check __wasm__ first. --- stdlib/public/runtime/Exclusivity.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/public/runtime/Exclusivity.cpp b/stdlib/public/runtime/Exclusivity.cpp index e0cb4902c49b2..39a14d7329848 100644 --- a/stdlib/public/runtime/Exclusivity.cpp +++ b/stdlib/public/runtime/Exclusivity.cpp @@ -37,14 +37,14 @@ #include // Pick a return-address strategy -#if __GNUC__ +#if defined(__wasm__) +// Wasm can't access call frame for security purposes +#define get_return_address() ((void*) 0) +#elif __GNUC__ #define get_return_address() __builtin_return_address(0) #elif _MSC_VER #include #define get_return_address() _ReturnAddress() -#elif defined(__wasm__) -// Wasm can't access call frame for security purposes -#define get_return_address() ((void*) 0) #else #error missing implementation for get_return_address #define get_return_address() ((void*) 0) From 792196feebdf44ee21383cb10d4f94904ccdbdca Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 10 Jun 2023 10:05:11 +0000 Subject: [PATCH 17/17] [wasm][stdlib] Add -D_WASI_EMULATED_PROCESS_CLOCKS to CFLAGS Stubs.cpp includes which requires the emulation in wasi-libc --- stdlib/cmake/modules/AddSwiftStdlib.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/cmake/modules/AddSwiftStdlib.cmake b/stdlib/cmake/modules/AddSwiftStdlib.cmake index 9fc316537a211..d1e5053b8f267 100644 --- a/stdlib/cmake/modules/AddSwiftStdlib.cmake +++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake @@ -323,7 +323,7 @@ function(_add_target_variant_c_compile_flags) endif() if("${CFLAGS_SDK}" STREQUAL "WASI") - list(APPEND result "-D_WASI_EMULATED_MMAN") + list(APPEND result "-D_WASI_EMULATED_MMAN" "-D_WASI_EMULATED_PROCESS_CLOCKS") endif() if(NOT SWIFT_STDLIB_ENABLE_OBJC_INTEROP)