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

Open
@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

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions