Avoiding underscores in compiler error messages with generic functions

Hello! I've been playing around with generic functions in Swift, and have run into a number of cases where the compiler gives less-than-helpful error messages. Specifically, I see error messages that go something like cannot convert value of type .... to expected argument type '(_) -> _'. Here's a minimal example:

func add2(_ x: Int) -> Int {
	return x + 2
}

func intToString(_ x: Int) -> String {
	return String(x)
}

func doubleToString(_ x: Double) -> String {
	return String(x)
}

func pipe<A, B, C>(_ f1: (A) -> B, _ f2: (B) -> (C)) -> ((A) -> C) {
	return { x in
		f2(f1(x))
	}
}

// This works:
let a = pipe(add2, intToString)

// This does not work, but unfortunately Swift gives a less-than-helpful message:
// error: cannot convert value of type '(Int) -> Int' to expected argument type '(_) -> _' 
let b = pipe(add2, doubleToString)

Sometimes the error is immediately obvious upon further inspection, but many times it's not, and the error messages don't help much. Are there any tricks to make these error messages more helpful? Is this a fundamental limitation of the language or am I "holding it wrong"?

This is a limitation of the current compiler. More specifically, the type checker is failing to infer the generic parameters of pipe, so it has a hard time determining intent and producing a good error message (_ essentially means 'unknown type'). The good news is there's a lot of ongoing work porting type checking errors over to a new diagnostics system to better handle cases like this one. Unfortunately, there's not much you can do in the meantime to get better information, except maybe adding type annotations. Personally I'm not sure that would be worth the effort though.

1 Like

Thanks for your response @owenv! It’s comforting to hear that the situation may be improved in the future. Is there any way to watch some of the ongoing work that you mentioned (any relevant PRs/commits/discussions) to observe and learn?

Searching the GitHub repo for "new diagnostics framework" seems to pull up most of the relevant PRs, and many related issues are tracked under the DiagnosticsQoI label on the bug tracker. Not everything at those links is 100% relevant, but hopefully they're a good starting point. If you'd like to take a look at the implementation, the best starting point would probably be CSDiagnostics. Others who have more experience might have better suggestions though!

1 Like

Thanks @owenv!