Skip to content

Commit d1a5bb0

Browse files
authored
Merge pull request #10203 from dotty-staging/fix-#10137
Fix #10137: Emit a warning if generated main class conflicts
2 parents f21504a + 8c1c318 commit d1a5bb0

File tree

6 files changed

+47
-6
lines changed

6 files changed

+47
-6
lines changed

compiler/src/dotty/tools/dotc/ast/MainProxies.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ object MainProxies {
3939
mainMethods(stats).flatMap(mainProxy)
4040
}
4141

42+
private def checkNoShadowing(mainFun: Symbol)(using Context) =
43+
val cls = ctx.typer.findRef(mainFun.name.toTypeName, WildcardType, EmptyFlags, mainFun).typeSymbol
44+
if cls.exists && cls.owner != ctx.owner then
45+
report.warning(
46+
i"""The class `${ctx.printer.fullNameString(mainFun)}` generated from `@main` will shadow the existing ${cls.showLocated}.
47+
|The existing definition might no longer be found on recompile.""", mainFun)
48+
4249
import untpd._
4350
def mainProxy(mainFun: Symbol)(using Context): List[TypeDef] = {
4451
val mainAnnotSpan = mainFun.getAnnotation(defn.MainAnnot).get.tree.span
@@ -86,6 +93,7 @@ object MainProxies {
8693
case _ =>
8794
report.error(s"@main can only annotate a method", pos)
8895
}
96+
checkNoShadowing(mainFun)
8997
val errVar = Ident(nme.error)
9098
val handler = CaseDef(
9199
Typed(errVar, TypeTree(defn.CLP_ParseError.typeRef)),

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
8484
nameString(if (ctx.property(XprintMode).isEmpty) sym.initial.name else sym.name)
8585

8686
override def fullNameString(sym: Symbol): String =
87-
if (isEmptyPrefix(sym.maybeOwner)) nameString(sym)
87+
if !sym.exists || isEmptyPrefix(sym.effectiveOwner) then nameString(sym)
8888
else super.fullNameString(sym)
8989

9090
override protected def fullNameOwner(sym: Symbol): Symbol = {

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,11 +2248,12 @@ class Typer extends Namer
22482248
val pkg = pid1.symbol
22492249
pid1 match
22502250
case pid1: RefTree if pkg.is(Package) =>
2251-
val packageCtx = ctx.packageContext(tree, pkg)
2252-
var stats1 = typedStats(tree.stats, pkg.moduleClass)(using packageCtx)._1
2253-
if (!ctx.isAfterTyper)
2254-
stats1 = stats1 ++ typedBlockStats(MainProxies.mainProxies(stats1))(using packageCtx)._1
2255-
cpy.PackageDef(tree)(pid1, stats1).withType(pkg.termRef)
2251+
inContext(ctx.packageContext(tree, pkg)) {
2252+
var stats1 = typedStats(tree.stats, pkg.moduleClass)._1
2253+
if (!ctx.isAfterTyper)
2254+
stats1 = stats1 ++ typedBlockStats(MainProxies.mainProxies(stats1))._1
2255+
cpy.PackageDef(tree)(pid1, stats1).withType(pkg.termRef)
2256+
}
22562257
case _ =>
22572258
// Package will not exist if a duplicate type has already been entered, see `tests/neg/1708.scala`
22582259
errorTree(tree,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Error: tests/neg-custom-args/fatal-warnings/i10137.scala:2:12 -------------------------------------------------------
2+
2 | @main def main(): Unit = println("Hello, World!") // error
3+
| ^
4+
| The class `foo.main` generated from `@main` will shadow the existing class main in package scala.
5+
| The existing definition might no longer be found on recompile.
6+
-- Error: tests/neg-custom-args/fatal-warnings/i10137.scala:4:10 -------------------------------------------------------
7+
4 |@main def List(): Unit = println("List") // error
8+
| ^
9+
| The class `List` generated from `@main` will shadow the existing type List in package scala.
10+
| The existing definition might no longer be found on recompile.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package foo:
2+
@main def main(): Unit = println("Hello, World!") // error
3+
4+
@main def List(): Unit = println("List") // error

tests/pending/pos/i10161.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
object Incompat2 {
2+
trait Context { type Out }
3+
4+
object Context {
5+
def foo(implicit ctx: Context): Option[ctx.Out] = ???
6+
7+
def bar(implicit ctx: Context): (Option[ctx.Out], String) = (foo, "foo")
8+
}
9+
}
10+
object Incompat3 {
11+
trait Context { type Out }
12+
13+
object Context {
14+
given foo(using ctx: Context) as Option[ctx.Out] = ???
15+
16+
given bar(using ctx: Context) as (Option[ctx.Out], String) = (foo, "foo")
17+
}
18+
}

0 commit comments

Comments
 (0)