Skip to content

this.type in function types is sometimes misinterpreted to mean "this function" instead of "this class", leading to crash with infinite recursive type #23111

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

Open
smarter opened this issue May 6, 2025 · 0 comments

Comments

@smarter
Copy link
Member

smarter commented May 6, 2025

Compiler version

3.7.1-RC1

Minimized code

This fails with a reasonable error:

trait A:
  def bar: (a: Int, b: Int) => A.this.type = x => ???
[error] ./try/foo.scala:2:46
[error] Wrong number of parameters, expected: 2
[error]   def bar: (a: Int, b: Int) => A.this.type = x => ???
[error]                                              ^^^^^^^^

... but if I replace A.this.type by this.type, things go crazy:

trait A:
  def bar: (a: Int, b: Int) => this.type = x => ???
[error] ./try/foo.scala:2:44
[error] Missing parameter type
[error]
[error] I could not infer the type of the parameter x
[error] Expected type for the whole anonymous function:
[error]   {z1 => (a: Int, b: Int) =>
[error]   (z1 :
[error]     {z2 => (a: Int, b: Int) =>
[error]       (z1 :
[error]         {z3 => (a: Int, b: Int) =>
[error]           (z1 :
[error]             {z4 => (a: Int, b: Int) =>
[error]               (z1 :
[error]                 {z5 => (a: Int, b: Int) =>
[error]                   (z1 :
[error]                     {z6 => (a: Int, b: Int) =>
[error]                       (z1 :
[error]                         {z7 => (a: Int, b: Int) =>
[error]                           (z1 :
[error]                             {z8 => (a: Int, b: Int) =>
[error]                               (z1 :
[error]                                 {z9 => (a: Int, b: Int) =>
[error]                                   (z1 :
[error]                                     {z10 => (a: Int, b: Int) =>
[error]                                       (z1 :
[error]                                         {z11 => (a: Int, b: Int) =>
[error]                                           (z1 :
[error]                                             {z12 => (a: Int, b: Int) =>
[error]                                               (z1 :
[error]                                                 {z13 => (a: Int, b: Int) =>
[error]                                                   (z1 :
[error]                                                     {z14 => (a: Int, b: Int) =>
[error]                                                       (z1 :
[error]                                                         {z15 => (a: Int, b: Int
[error]                                                           ) =>
[error]                                                           (z1 :
[error]                                                             {z16 => (a: Int, b:
[error]                                                               Int) =>
[error]                                                               (z1 :
[error]                                                                 {z17 => (
[error]                                                                   a: Int, b: Int
[error]                                                                   ) =>
[error]                                                                   (z1 :
[error]                                                                     {z18 => (
[error]                                                                       a: Int, b
[error]                                                                       : Int) =>
[error]                                                                       (z1 :
[error]                                                                         {z19 =>
[error]                                                                           (
[error]                                                                           a: Int
[error]                                                                             ,
[error]                                                                         b: Int)
[error]                                                                           =>
[error]                                                                           (z1 :
[error]                                                                             {z20
[error]                                                                                =>
[error]                                                                               (
[error]                                                                               a
[error]                                                                                 :
[error]                                                                                 ...
[error]                                                                                 ,
[error]                                                                               b
[error]                                                                               :
[error]                                                                               ...
[error]                                                                               )
[error]                                                                               =>
[error]
[error]                                                                               (
[error]                                                                                 ...
[error]                                                                                  :
[error]                                                                                 ...
[error]                                                                                 )
[error]                                                                               }
[error]                                                                           )
[error]                                                                         }
[error]                                                                       )
[error]                                                                     }
[error]                                                                   )
[error]                                                                 }
[error]                                                               )
[error]                                                             }
[error]                                                           )
[error]                                                         }
[error]                                                       )
[error]                                                     }
[error]                                                   )
[error]                                                 }
[error]                                               )
[error]                                             }
[error]                                           )
[error]                                         }
[error]                                       )
[error]                                     }
[error]                                   )
[error]                                 }
[error]                               )
[error]                             }
[error]                           )
[error]                         }
[error]                       )
[error]                     }
[error]                   )
[error]                 }
[error]               )
[error]             }
[error]           )
[error]         }
[error]       )
[error]     }
[error]   )
[error] }
[error]   def bar: (a: Int, b: Int) => this.type = x => ???
[error]                                            ^

Expectation

Clearly this.type refers to A.this.type here, so the two pieces of code should behave in the same way, and not attempt to create an infinitely recursive type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant