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