Skip to content

Commit 194ad8e

Browse files
committed
Fix #19019: Always type self ValDefs in their outer context.
1 parent 637ed88 commit 194ad8e

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

compiler/src/dotty/tools/dotc/core/ContextOps.scala

+11-4
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,19 @@ object ContextOps:
8080
}
8181

8282
/** A fresh local context with given tree and owner.
83-
* Owner might not exist (can happen for self valdefs), in which case
84-
* no owner is set in result context
85-
*/
83+
*
84+
* #19019 Self valdefs must always keep their enclosing ctx.owner. They
85+
* can be NoSymbol or having a symbol with the SelfName flag, depending on
86+
* whether they have an explicit name or not. In either case, we avoid
87+
* `setOwner`.
88+
*
89+
* The owner might also not exist for other kinds of trees, such as
90+
* `LambdaTypeTree` and `TermLambdaTypeTree`. In these cases, we also
91+
* keep the enclosing owner.
92+
*/
8693
def localContext(tree: untpd.Tree, owner: Symbol): FreshContext = inContext(ctx) {
8794
val freshCtx = ctx.fresh.setTree(tree)
88-
if owner.exists then freshCtx.setOwner(owner) else freshCtx
95+
if owner.exists && !owner.is(SelfName) then freshCtx.setOwner(owner) else freshCtx
8996
}
9097

9198
/** Context where `sym` is defined, assuming we are in a nested context. */

tests/printing/i19019.check

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[[syntax trees at end of typer]] // tests/printing/i19019.scala
2+
package <empty> {
3+
final lazy module val ObjectWithSelf: ObjectWithSelf = new ObjectWithSelf()
4+
final module class ObjectWithSelf() extends Object() {
5+
this: ObjectWithSelf.type =>
6+
final lazy module val StaticObjectNoSelf: ObjectWithSelf.StaticObjectNoSelf
7+
= new ObjectWithSelf.StaticObjectNoSelf()
8+
final module class StaticObjectNoSelf() extends Object() {
9+
this: ObjectWithSelf.StaticObjectNoSelf.type =>
10+
def foo: Any = this
11+
}
12+
final lazy module val StaticObjectWithSelf:
13+
ObjectWithSelf.StaticObjectWithSelf =
14+
new ObjectWithSelf.StaticObjectWithSelf()
15+
final module class StaticObjectWithSelf() extends Object() {
16+
self: ObjectWithSelf.StaticObjectWithSelf.type =>
17+
def foo: Any = self
18+
}
19+
class Container() extends Object() {
20+
final lazy module val NonStaticObjectNoSelf:
21+
Container.this.NonStaticObjectNoSelf =
22+
new Container.this.NonStaticObjectNoSelf()
23+
final module class NonStaticObjectNoSelf() extends Object() {
24+
this: Container.this.NonStaticObjectNoSelf.type =>
25+
def foo: Any = this
26+
}
27+
final lazy module val NonStaticObjectWithSelf:
28+
Container.this.NonStaticObjectWithSelf =
29+
new Container.this.NonStaticObjectWithSelf()
30+
final module class NonStaticObjectWithSelf() extends Object() {
31+
self: Container.this.NonStaticObjectWithSelf.type =>
32+
def foo: Any = self
33+
}
34+
}
35+
}
36+
}
37+

tests/printing/i19019.scala

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
object ObjectWithSelf:
2+
object StaticObjectNoSelf:
3+
def foo: Any = this
4+
end StaticObjectNoSelf
5+
6+
object StaticObjectWithSelf:
7+
self =>
8+
9+
def foo: Any = self
10+
end StaticObjectWithSelf
11+
12+
class Container:
13+
object NonStaticObjectNoSelf:
14+
def foo: Any = this
15+
end NonStaticObjectNoSelf
16+
17+
object NonStaticObjectWithSelf:
18+
self =>
19+
20+
def foo: Any = self
21+
end NonStaticObjectWithSelf
22+
end Container
23+
end ObjectWithSelf

0 commit comments

Comments
 (0)