@@ -179,6 +179,18 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
179
179
if enclClass.isContainedIn(thisClass) then thisClass
180
180
else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
181
181
182
+ def setLogicOwner (local : Symbol ) =
183
+ val encClass = local.owner.enclosingClass
184
+ val preferEncClass =
185
+ encClass.isStatic
186
+ // non-static classes can capture owners, so should be avoided
187
+ && (encClass.isProperlyContainedIn(local.topLevelClass)
188
+ // can be false for symbols which are defined in some weird combination of supercalls.
189
+ || encClass.is(ModuleClass , butNot = Package )
190
+ // needed to not cause deadlocks in classloader. see t5375.scala
191
+ )
192
+ logicOwner(sym) = if preferEncClass then encClass else local.enclosingPackageClass
193
+
182
194
tree match
183
195
case tree : Ident =>
184
196
if isLocal(sym) then
@@ -194,7 +206,7 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
194
206
case tree : This =>
195
207
narrowTo(tree.symbol.asClass)
196
208
case tree : MemberDef if isExpr(sym) && sym.owner.isTerm =>
197
- logicOwner (sym) = sym.enclosingPackageClass
209
+ setLogicOwner (sym)
198
210
// this will make methods in supercall constructors of top-level classes owned
199
211
// by the enclosing package, which means they will be static.
200
212
// On the other hand, all other methods will be indirectly owned by their
@@ -205,8 +217,8 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
205
217
// the class itself. This is done so that the constructor inherits
206
218
// the free variables of the class.
207
219
symSet(called, sym) += sym.owner
208
- case tree : TypeDef =>
209
- if sym.owner.isTerm then logicOwner (sym) = sym.topLevelClass.owner
220
+ case tree : TypeDef if sym.owner.isTerm =>
221
+ setLogicOwner (sym)
210
222
case _ =>
211
223
end process
212
224
0 commit comments