Disallow passing expression pattern inout to the match function

At the moment, the following code is legal:

func ~= (pattern: inout Int, value: Int) -> Bool {
  pattern = value
  return true

var x = 0

switch 49 {
case x:

print(x) // 49

I have an implementation ready to fix this bug (SR-11488) by discarding match (~=) functions which take the expression pattern inout. However, I wanted to discuss this in the forums because there's another way to fix this - diagnosing such functions and providing a fix-it to remove inout.

I went with the first solution because it is the simplest and easiest thing to do, but is it better to diagnose with an error (or warning) + fix-it instead? What does everyone think? I don't think anyone's actually writing code like above (couldn't find anything on GitHub at least) so maybe we can get away with simply discarding the inout implementation when looking up match functions? cc @xedin


@Douglas_Gregor Is ~= operator supposed to only be used implicitly in pattern matching context?

1 Like

No, I think it should be considered a generally usable operator that also happens to be used by pattern matching.


1 Like

Perhaps pattern-matching should only use non-inout versions of the ~= operator?

1 Like

It will always be possible to change state of the patten if that pattern is a class instance, and I think one could come up with at least not entirely unreasonable use-cases for that (caching results of an expensive test, maybe even something crazy like a matcher that will only accept the first n matching values it is fed).

Why is an exception to the language necessary to disallow this just for non-class-types?

I also can't see this doing much harm. A beginner might be confused, but then again a beginner won't write an overload of ~= with an inout argument in all likelihood.

1 Like

I wonder if it would make sense to document expected behavior (what ever it is) in the proposal to avoid future confusion. I personally don't see much harm from allowing ~= with inout parameters to be found in pattern-matching context if ~= operator is intended for general use, that's one fewer special cases to keep in mind while working with it.