diff --git a/Sources/SwiftExtract/SwiftTypes/SwiftType.swift b/Sources/SwiftExtract/SwiftTypes/SwiftType.swift index 0cb2fedf0..89dc2baf0 100644 --- a/Sources/SwiftExtract/SwiftTypes/SwiftType.swift +++ b/Sources/SwiftExtract/SwiftTypes/SwiftType.swift @@ -521,7 +521,7 @@ extension SwiftType { if someOrAntType.someOrAnySpecifier.tokenKind == .keyword(.some) { self = .opaque(try SwiftType(someOrAntType.constraint, lookupContext: lookupContext)) } else { - self = .opaque(try SwiftType(someOrAntType.constraint, lookupContext: lookupContext)) + self = .existential(try SwiftType(someOrAntType.constraint, lookupContext: lookupContext)) } case .compositionType(let compositeType): diff --git a/Tests/SwiftExtractTests/AnalysisResultTests.swift b/Tests/SwiftExtractTests/AnalysisResultTests.swift index 2fc1abd25..e734fe176 100644 --- a/Tests/SwiftExtractTests/AnalysisResultTests.swift +++ b/Tests/SwiftExtractTests/AnalysisResultTests.swift @@ -393,6 +393,39 @@ struct AnalysisResultSuite { #expect(unresolvable.functionSignature.thrownTypedError == nil) } + @Test + func someAndAnyProduceOpaqueAndExistentialTypes() throws { + let result = try analyze( + sources: [ + ( + "/fake/Source.swift", + """ + public protocol Swimmer {} + public func trainOpaque(_ swimmer: some Swimmer) {} + public func trainExistential(_ swimmer: any Swimmer) {} + """ + ) + ], + moduleName: "Aquarium" + ) + + let byName = Dictionary(uniqueKeysWithValues: result.extractedGlobalFuncs.map { ($0.name, $0) }) + + let opaque = try #require(byName["trainOpaque"]?.functionSignature.parameters.first?.type) + guard case .opaque = opaque else { + Issue.record("expected .opaque, got \(opaque)") + return + } + #expect(opaque.description == "some Swimmer") + + let existential = try #require(byName["trainExistential"]?.functionSignature.parameters.first?.type) + guard case .existential = existential else { + Issue.record("expected .existential, got \(existential)") + return + } + #expect(existential.description == "any Swimmer") + } + @Test func typedThrowsOnInitializers() throws { let result = try analyze(