Swift 5.8 / Xcode 14.3: Ambiguous use of 'init()' for `Rest()`
Jeehut opened this issue · 5 comments
I just upgraded to Xcode 14.3 RC 2 which ships with Swift 5.8 and my project no longer builds, it was building just fine in Xcode 14.2 (Swift 5.7).
The compiler reports Ambiguous use of 'init()'
for the line Skip { Rest() }
in my code. Here's the full function:
public static func parseKnownLanguages(_ input: Substring) throws -> [Language] {
let listOfKnownRegions: Substring = try Parse {
Skip {
PrefixThrough("knownRegions")
Whitespaces()
"="
Whitespaces()
"("
}
PrefixUpTo(");")
Skip { Rest() } // <-- ERROR: Ambiguous use of 'init()
}
.parse(input)
// ...
}
Looks like there was a change in Swift 5.8 which causes an ambiguity. Not sure what goes wrong with how simple the initializer of Rest
looks (simply @inlinable public init() {}
), but something seems to be off. Maybe the usage @_disfavoredOverload
is the culprit? I'm on the latest release 0.11.0
.
As a workaround, I could explicitly specify the generic, so instead of Rest()
if I write Rest<Substring>()
it compiles. So I'm good for now, but I think others might run into this issue as well.
Ok, here's another parser that fails compiling now (see comment towards end):
/// Consumes a specific start-tag with a given name, e.g. `<key>` and two attribute, e.g. `<img src="hogwarts.png" title="School">`. Outputs the attributes values.
struct DoubleAttributes: Parser {
typealias Values = (firstValue: Substring, secondValue: Substring)
/// The name of the tag. E.g. `key` for `</key>`.
let name: String
/// The first attribute to be parsed. E.g. `src="hogwarts.png"`.
let firstAttribute: NamedAttribute
/// The second attribute to be parsed. E.g. `title="School"`.
let secondAttribute: NamedAttribute
func parse(_ input: inout Substring) throws -> Values {
try Parse {
"<"
self.name
Parse {
Whitespaces(minCharacters: 1)
firstAttribute
}
Parse {
Whitespaces(minCharacters: 1)
secondAttribute
}
Skip {
Optionally {
PrefixUpTo(">")
}
}
">"
}
.parse(&input) // <-- ERROR: Type of expression is ambiguous without more context
}
}
UPDATE: Okay, this one might not be related to swift-parsing at all. It seems that automatic mapping of (Substring, Substring)
to my custom (firstValue: Substring, secondValue: Substring)
no longer worked. But when I store the result of try Parse { ... }.parse(&input)
into a variable and then return that on the next line, it works again:
func parse(_ input: inout Substring) throws -> Values {
let values = try Parse {
"<"
self.name
Parse {
Whitespaces(minCharacters: 1)
firstAttribute
}
Parse {
Whitespaces(minCharacters: 1)
secondAttribute
}
Skip {
Optionally {
PrefixUpTo(">")
}
}
">"
}
.parse(&input)
return values
}
Alright, there sure are many problems after upgrading to Swift 5.8, here's another one:
try Parse {
"%"
Optionally {
UInt.parser() // <-- ERROR: Ambiguous use of 'parser(of:radix:)'
"$"
}
// ...
}
UPDATE: The workaround was to replace UInt.parser()
with UInt.parser(of: Substring.self)
.
I am getting the same error when using Whitespace
:
lazy var openingTagParser = Parse {
"<"
Not { "/" }
Prefix(1...) { character in
character != ">"
}
.pipe {
tagContentParser
Whitespace(.horizontal) // <---- Ambiguous use of 'init(_:)'
Not { "/" }
}
">"
}
Other usages as well such as Whitespace(1..., .horizontal)
or just Whitespace()
.
@tgrapperon Thank you for pointing me to #290, I didn't check the Discussions tab as I expect issues to appear in the Issues tab. But I switched to the swift-5-8
branch now and things went smoothly, I just had to replace one try Parse {
call with try Parse(input: Substring.self) {
and all is building, even without the other workarounds I mentioned above.
Closing this as #289 is under way and should fix most issues.