rxwei
(Richard Wei)
1
If you call a top-level math function in an extension for a ElementaryFunction-conforming type, there's type checking ambiguity:
import Foundation
extension Float {
func foo() {
_ = sin(self)
}
}
test.swift:5:13: error: static member 'sin' cannot be used on instance of type 'Float'
_ = sin(self)
^~~
Float.
Maybe users rarely define extensions for Float, but it could be a usability issue for types that a user often wants to extend, e.g. vector types and Tensor. When I tried conforming TensorFlow's Tensor type to ElementaryFunctions, it broke a lot of existing code that called top-level math functions in extensions.
@scanon, any thoughts or suggestions?
2 Likes
I run into this all the time. It would be nice if the compiler could simply keep looking and discover that a global function matches better than the type method.
In the meantime I usually end up defining a forwarding instance method just to make the inconveniences go away:
extension Float {
func sin(_ angle: Float) -> Float {
return Float.sin(angle)
}
func foo() {
_ = sin(self) // ✓
}
}
scanon
(Steve Canon)
3
Fundamentally, this is a typechecker bug, which unfortunately no one has had bandwidth to tackle. I discussed it with the core team at some length in the context of SE-0246, and the conclusion was that this was an annoyance that we're willing to live with in the short term in order to get generic math function support into the stdlib. The earlier proposal with the Math pseudonamespace would have avoided the problem, but ultimately it was decided that this was the less annoying solution.
If someone wants to try fixing the underlying typechecker bug in the near term, have at it.
1 Like
rxwei
(Richard Wei)
4
Is there a JIRA bug for this?
scanon
(Steve Canon)
5
Nevin
6
I think this might be the same as SR–456 “Confusing build error when calling 'max' function within 'extension Int'”
1 Like
rxwei
(Richard Wei)
7