Skip to content

Overloaded extension methods with varargs used as infix operator failed the compilation #16125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
guofengzh opened this issue Sep 30, 2022 · 2 comments
Labels
itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label

Comments

@guofengzh
Copy link

guofengzh commented Sep 30, 2022

Compiler version

3.2.0

Minimized code

Change the code in #12133, add 'infix'. it works. but if the extension clause has more than one method defintion, it fails the compilation.

class B

class A:
  infix def foo(b: B) = ???
  infix def foo(str: String) = ???

extension (x: A) 
  infix def foo(s: Int*) = s.size
  infix def foo(l: Boolean) = ???

val a = new A

val res = a foo (1, 2)  // ERROR!!

The error message is

None of the overloaded alternatives of method foo in class A with types
 (str: String): Nothing
 (b: sample.B): Nothing
match arguments ((Int, Int))

if I moved all methods in A to the extension clause, that is

extension (x: A) 
  infix def foo(b: B) = ???
  infix def foo(str: String) = ???
  infix def foo(s: Int*) = s.size
  infix def foo(l: Boolean) = ???

the messages changed to

value foo is not a member of sample.A.
An extension method was tried, but could not be fully constructed:

    sample.foo()    failed with

        value foo: <overloaded sample.foo> does not take parameters

In these two cases, if the dot selection is used for the function application, the codes pass the compilation.

Output

N/A

Expectation

Is it a bug of the Scala 3 compiler, or is there any syntax limition with the infix modifier?

@guofengzh guofengzh added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Sep 30, 2022
@som-snytt
Copy link
Contributor

Sample "multiarg infix" limitation having to do with += at #14418

Note that (1, 2) is a tuple, and autountupling must kick in for a foo (1, 2) to applicable.

@odersky
Copy link
Contributor

odersky commented Sep 30, 2022

It's because infix defs don't take varargs. If foo is declared infix then

   a foo (1, 2)

is treated as

   a foo ((1, 2))

An infix def is a binary operator, so varargs don't make sense. There is a special case to keep the old behavior but that only kicks in if the method is not overloaded.

I don't think it's worth fixing anything here compiler-side, except accelerating the transition to the new behavior where we reject infix defs with varargs whether they are overloaded or not.

@odersky odersky closed this as completed Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label
Projects
None yet
Development

No branches or pull requests

3 participants