-
Notifications
You must be signed in to change notification settings - Fork 21
Using this as default argument to constructor does not refer to enclosing object #5543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Imported From: https://issues.scala-lang.org/browse/SI-5543?orig=1 |
@cvogt said: |
@som-snytt said: The problem seems to be that when default-getters for constructors are added to the companion module, the expression has the module in scope. Adding constrTyperIf(flag) before entering typedDefDef seems to work. Since there is no flag for default-getter for ctor, it does a name compare. It might be preferable to add a flag or abuse an existing flag instead. This change includes renaming init$default$ to init$$default$ to avoid collisions with default-getters for an ordinary method on the module named init. That change is not trivial, so guidance is needed. Alternatively, one could live with the possibility of name collision and just allow that there are interactions that impose limits, similar to #5366. More example: object A {
val v = 7
class B(val x: Int = v)
object B {
val v = 5
//def init(y: Int = v) = y // names collide
}
def main(args: Array[String]) {
println(new B().x) // 5
}
}
|
@som-snytt said: |
@lrytz said: object T {
override def toString = "T"
// here, `this` should refer to T. That's what was fixed
class C(val x: Any = this) {
override def toString() = "C"
}
class D(val x: Any) {
override def toString() = "D"
// here, `this` should refer to the D instance, but after the fix it also
// refers to T.
def this(a: Int, b: Int, c: Any = this) { this(c) }
}
}
println((new T.C()).x) // prints "T", correct
println((new T.D(0,0)).x) // prints "T", should print "D" |
@lrytz said: class C { type T; def this(x: T) { this() } } // gives `not found: type T`
class C(x: Int) { def this(a: Int, b: Int = x) { this(b) } } // gives `not found: value x`
class C { val x = 0; def this(a: Int = x) { this() } } // also `not found: value x` spec 5.3.1: The signature and the self constructor invocation of a constructor definition are type-checked and evaluated in the scope which is in effect at the point of the enclosing class definition, augmented by any type parameters of the enclosing class and by any early definitions of the enclosing template. The rest of the constructor expression is type-checked and evaluated as a function body in the current class. |
@retronym said: |
@lrytz said: |
@adriaanm said: object Foo {
case class Foo(x: String = this.toString)
} Let's reboot the discussion. |
@adriaanm said: |
@som-snytt said: |
@som-snytt said: |
@som-snytt said: In the U.S., you get three years to amend a tax return and three years to amend a community contribution.
However, that should have read:
|
@som-snytt said: |
In the following code, the default argument to Bar is object Bar instead of object Main.
However, scalac requires that both Main and Bar conform to the parameter type.
I'd expect Main.this to be in scope, even though the expression is evaluated by Bar$.
Reproduce Code
Expected result
Actual Result
The text was updated successfully, but these errors were encountered: