Automatic Mutable Pointer Conversion

To clarify, I am not concerned about type checker performance for this specific implicit conversion.

I don't necessarily think this is the main problem for a general feature, but it is a problem that could prevent a very attractive design from being feasible. We're not even at the point where we know what a design would look like, which is why I said that is a big discussion and it shouldn't hold up this pitch.

When working in the constraint system, it's very easy to have a narrow of a view of the piece of code you're working on, and miss the implications on the larger system. Speaking from experience :slightly_smiling_face:

Most (or all?) implicit conversions today don't actually introduce new disjunctions, so it might seem like the implicit conversion won't have an impact on existing code. For a particular overload that doesn't need the implicit conversion, that's true. But for some other overload that already exists that today fails immediately in the solver, the implicit conversion could actually make the expression type-check using that overload. Implicit conversions expand the search space even if they don't themselves introduce disjunctions, because they make other existing possibilities well-formed. This is also what leads to ambiguities. Maybe only one overload worked before, but now several overloads are valid, and the solver has to find all of them and determine which one is best. If the solution scores are the same and none of the overloads are more "specialized" than the others, that then becomes an ambiguity error.

After this explanation, you might think that the solver should short-circuit disjunctions if it has already found a solution. The solver already does this in some cases today in an attempt to improve performance, but it's a hack, and it leads to incorrect behavior and sometimes prevents valid code from compiling because the solver will miss a solution that ends up having a better score.

This is already how implicit conversions work today:

extension Optional {
  func someMethod() {}
}

func test(a: Int?, b: Int) {
  a.someMethod()
  b.someMethod() // error: Value of type 'Int' has no member 'someMethod'
  (b as Optional).someMethod() // okay
}
2 Likes