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

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions