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

@smarter

Description

@smarter

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions