E177: Constructor Proxy Shadows

This error occurs when a reference to a constructor proxy for an inner class shadows an outer reference with the same name, such as a method or object.

In Scala 3, constructor proxies are automatically generated for classes, allowing you to create instances without writing new. However, when an inner class shares a name with an outer definition (method, object, or value), the compiler cannot determine which one you intended to use.


Longer explanation:

There is an ambiguity in the meaning of the call

MyClass(...)

It could mean creating an instance of an inner class with

new MyClass(...)

Or it could mean calling an outer method/object with the same name:

MyClass(...)

To disambiguate, use an explicit new if you mean the former, or use a full prefix if you mean the latter.


Example

object Test:
  def MyClass(s: String): String = s

  class Outer:
    class MyClass(s: String)
    val x = MyClass("hello")  // ambiguous: inner class or outer method?

Error

-- [E177] Reference Error: example.scala:6:12 ----------------------------------
6 |    val x = MyClass("hello")  // ambiguous: inner class or outer method?
  |            ^^^^^^^
  |           Reference to constructor proxy for class MyClass in class Outer
  |           shadows outer reference to method MyClass in object Test
  |
  |           The instance needs to be created with an explicit `new`.
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | There is an ambiguity in the meaning of the call
  |
  |    MyClass(...)
  |
  | It could mean creating an instance of class MyClass in class Outer with
  |
  |    new MyClass(...)
  |
  | Or it could mean calling method MyClass in object Test as in
  |
  |    MyClass(...)
  |
  | To disambiguate, use an explicit `new` if you mean the former,
  | or use a full prefix for MyClass if you mean the latter.
   -----------------------------------------------------------------------------

Solution

Use explicit new if you want to create an instance of the inner class:

object Test:
  def MyClass(s: String): String = s

  class Outer:
    class MyClass(s: String)
    val x = new MyClass("hello")  // explicitly create inner class instance

Or use a full prefix to call the outer method:

object Test:
  def MyClass(s: String): String = s

  class Outer:
    class MyClass(s: String)
    val x = Test.MyClass("hello")  // explicitly call outer method