@@ -436,7 +436,7 @@ extension PackageInfo.Target {
436436 /// A namespace for target-specific build settings.
437437 public enum TargetBuildSettingDescription {
438438 /// The tool for which a build setting is declared.
439- public enum Tool : String , Codable , Hashable , CaseIterable {
439+ public enum Tool : String , Codable , Hashable , CaseIterable , Sendable {
440440 case c
441441 case cxx
442442 case swift
@@ -455,6 +455,7 @@ extension PackageInfo.Target {
455455 case enableExperimentalFeature
456456 case interoperabilityMode
457457 case defaultIsolation
458+ case strictMemorySafety
458459 }
459460
460461 /// An individual build setting.
@@ -506,6 +507,26 @@ extension PackageInfo.Target {
506507 case enableExperimentalFeature( String )
507508 case interoperabilityMode( String )
508509 case defaultIsolation( String )
510+ case strictMemorySafety( String )
511+ }
512+
513+ enum SettingDecodingError : LocalizedError {
514+ case missingRequiredKeys( tool: Tool , availableKeys: [ String ] , codingPath: [ CodingKey ] )
515+
516+ var errorDescription : String ? {
517+ switch self {
518+ case let . missingRequiredKeys( tool, availableKeys, codingPath) :
519+ let path = codingPath. map ( \. stringValue) . joined ( separator: " . " )
520+ return """
521+ Failed to decode target build setting at ' \( path) '.
522+ Expected either 'kind' (Xcode 14+ format) or 'name' (legacy format) key, but neither was found.
523+ Tool: \( tool)
524+ Available keys: \( availableKeys. joined ( separator: " , " ) )
525+
526+ This usually indicates a malformed Package.swift manifest or an unsupported Swift Package Manager version.
527+ """
528+ }
529+ }
509530 }
510531
511532 public init ( from decoder: Decoder ) throws {
@@ -545,10 +566,24 @@ extension PackageInfo.Target {
545566 case let . defaultIsolation( value) :
546567 name = . defaultIsolation
547568 self . value = [ value]
569+ case let . strictMemorySafety( value) :
570+ name = . strictMemorySafety
571+ self . value = [ value]
548572 }
549573 } else {
550- name = try container. decode ( SettingName . self, forKey: . name)
551- value = try container. decode ( [ String ] . self, forKey: . value)
574+ // Legacy format - try to decode name
575+ do {
576+ name = try container. decode ( SettingName . self, forKey: . name)
577+ value = try container. decode ( [ String ] . self, forKey: . value)
578+ } catch {
579+ // Neither 'kind' nor 'name' was found - provide helpful error
580+ let availableKeys = container. allKeys. map ( \. stringValue)
581+ throw SettingDecodingError . missingRequiredKeys (
582+ tool: tool,
583+ availableKeys: availableKeys,
584+ codingPath: decoder. codingPath
585+ )
586+ }
552587 }
553588 }
554589
@@ -578,6 +613,8 @@ extension PackageInfo.Target {
578613 try container. encode ( Kind . swiftLanguageMode ( value. first!) , forKey: . kind)
579614 case . defaultIsolation:
580615 try container. encode ( Kind . defaultIsolation ( value. first!) , forKey: . kind)
616+ case . strictMemorySafety:
617+ try container. encode ( Kind . strictMemorySafety ( value. first!) , forKey: . kind)
581618 }
582619 }
583620 }
0 commit comments