From fb1272c0b998f31db20d45ad84c53fca2f3eb5be Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Thu, 24 Apr 2025 08:36:43 +0300 Subject: [PATCH 1/3] fix #23043 --- compiler/src/dotty/tools/dotc/typer/Namer.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 89dc4cf53472..58e798f94002 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -150,13 +150,14 @@ class Namer { typer: Typer => if (preExisting.isDefinedInCurrentRun || preExisting.lastKnownDenotation.is(Package)) && (!preExisting.lastKnownDenotation.is(Private) || preExisting.owner.is(Package)) && (!preExisting.lastKnownDenotation.isPackageObject - || preExisting.associatedFile != ctx.source.file) + || preExisting.associatedFile != ctx.source.file && preExisting.associatedFile != null) // isDefinedInCurrentRun does not work correctly for package objects, because // package objects are updated to the new run earlier than normal classes, everytime // some member of the enclosing package is accessed. Therefore, we use another // test: conflict if package objects have the same name but come from different // sources. See i9252. - then conflict(preExisting) + then + conflict(preExisting) def pkgObjs(pkg: Symbol) = pkg.denot.asInstanceOf[PackageClassDenotation].packageObjs.map(_.symbol) From 36d5fbd04525e8dd66678042e7ed7fa47328eb78 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Fri, 25 Apr 2025 10:51:11 +0300 Subject: [PATCH 2/3] use other criteria for is(Package), to be symmetric with first condition --- compiler/src/dotty/tools/dotc/typer/Namer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 58e798f94002..dff6f1302b82 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -149,7 +149,7 @@ class Namer { typer: Typer => val preExisting = owner.unforcedDecls.lookup(name) if (preExisting.isDefinedInCurrentRun || preExisting.lastKnownDenotation.is(Package)) && (!preExisting.lastKnownDenotation.is(Private) || preExisting.owner.is(Package)) - && (!preExisting.lastKnownDenotation.isPackageObject + && (!preExisting.lastKnownDenotation.is(Package) || preExisting.associatedFile != ctx.source.file && preExisting.associatedFile != null) // isDefinedInCurrentRun does not work correctly for package objects, because // package objects are updated to the new run earlier than normal classes, everytime From 17a18786cfa4b5f200b7299847540e60202c2236 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Fri, 25 Apr 2025 12:50:55 +0300 Subject: [PATCH 3/3] return back check to preExisting.isPackageObject --- compiler/src/dotty/tools/dotc/typer/Namer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index dff6f1302b82..83e8df6ea83b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -149,7 +149,7 @@ class Namer { typer: Typer => val preExisting = owner.unforcedDecls.lookup(name) if (preExisting.isDefinedInCurrentRun || preExisting.lastKnownDenotation.is(Package)) && (!preExisting.lastKnownDenotation.is(Private) || preExisting.owner.is(Package)) - && (!preExisting.lastKnownDenotation.is(Package) + && (!preExisting.lastKnownDenotation.is(Package) && !preExisting.lastKnownDenotation.isPackageObject || preExisting.associatedFile != ctx.source.file && preExisting.associatedFile != null) // isDefinedInCurrentRun does not work correctly for package objects, because // package objects are updated to the new run earlier than normal classes, everytime