diff --git a/compiler/src/dotty/tools/dotc/ast/MainProxies.scala b/compiler/src/dotty/tools/dotc/ast/MainProxies.scala index 81612b8276a0..bbac310470c1 100644 --- a/compiler/src/dotty/tools/dotc/ast/MainProxies.scala +++ b/compiler/src/dotty/tools/dotc/ast/MainProxies.scala @@ -39,6 +39,13 @@ object MainProxies { mainMethods(stats).flatMap(mainProxy) } + private def checkNoShadowing(mainFun: Symbol)(using Context) = + val cls = ctx.typer.findRef(mainFun.name.toTypeName, WildcardType, EmptyFlags, mainFun).typeSymbol + if cls.exists && cls.owner != ctx.owner then + report.warning( + i"""The class `${ctx.printer.fullNameString(mainFun)}` generated from `@main` will shadow the existing ${cls.showLocated}. + |The existing definition might no longer be found on recompile.""", mainFun) + import untpd._ def mainProxy(mainFun: Symbol)(using Context): List[TypeDef] = { val mainAnnotSpan = mainFun.getAnnotation(defn.MainAnnot).get.tree.span @@ -86,6 +93,7 @@ object MainProxies { case _ => report.error(s"@main can only annotate a method", pos) } + checkNoShadowing(mainFun) val errVar = Ident(nme.error) val handler = CaseDef( Typed(errVar, TypeTree(defn.CLP_ParseError.typeRef)), diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 3da41b003adb..e214677a7b98 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -84,7 +84,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { nameString(if (ctx.property(XprintMode).isEmpty) sym.initial.name else sym.name) override def fullNameString(sym: Symbol): String = - if (isEmptyPrefix(sym.maybeOwner)) nameString(sym) + if !sym.exists || isEmptyPrefix(sym.effectiveOwner) then nameString(sym) else super.fullNameString(sym) override protected def fullNameOwner(sym: Symbol): Symbol = { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a8ae701e3a27..dac701f4d53e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2241,11 +2241,12 @@ class Typer extends Namer val pkg = pid1.symbol pid1 match case pid1: RefTree if pkg.is(Package) => - val packageCtx = ctx.packageContext(tree, pkg) - var stats1 = typedStats(tree.stats, pkg.moduleClass)(using packageCtx)._1 - if (!ctx.isAfterTyper) - stats1 = stats1 ++ typedBlockStats(MainProxies.mainProxies(stats1))(using packageCtx)._1 - cpy.PackageDef(tree)(pid1, stats1).withType(pkg.termRef) + inContext(ctx.packageContext(tree, pkg)) { + var stats1 = typedStats(tree.stats, pkg.moduleClass)._1 + if (!ctx.isAfterTyper) + stats1 = stats1 ++ typedBlockStats(MainProxies.mainProxies(stats1))._1 + cpy.PackageDef(tree)(pid1, stats1).withType(pkg.termRef) + } case _ => // Package will not exist if a duplicate type has already been entered, see `tests/neg/1708.scala` errorTree(tree, diff --git a/tests/neg-custom-args/fatal-warnings/i10137.check b/tests/neg-custom-args/fatal-warnings/i10137.check new file mode 100644 index 000000000000..15361f8dbed2 --- /dev/null +++ b/tests/neg-custom-args/fatal-warnings/i10137.check @@ -0,0 +1,10 @@ +-- Error: tests/neg-custom-args/fatal-warnings/i10137.scala:2:12 ------------------------------------------------------- +2 | @main def main(): Unit = println("Hello, World!") // error + | ^ + | The class `foo.main` generated from `@main` will shadow the existing class main in package scala. + | The existing definition might no longer be found on recompile. +-- Error: tests/neg-custom-args/fatal-warnings/i10137.scala:4:10 ------------------------------------------------------- +4 |@main def List(): Unit = println("List") // error + | ^ + | The class `List` generated from `@main` will shadow the existing type List in package scala. + | The existing definition might no longer be found on recompile. diff --git a/tests/neg-custom-args/fatal-warnings/i10137.scala b/tests/neg-custom-args/fatal-warnings/i10137.scala new file mode 100644 index 000000000000..3272c3434e07 --- /dev/null +++ b/tests/neg-custom-args/fatal-warnings/i10137.scala @@ -0,0 +1,4 @@ +package foo: + @main def main(): Unit = println("Hello, World!") // error + +@main def List(): Unit = println("List") // error diff --git a/tests/pending/pos/i10161.scala b/tests/pending/pos/i10161.scala new file mode 100644 index 000000000000..0bbc78b1b354 --- /dev/null +++ b/tests/pending/pos/i10161.scala @@ -0,0 +1,18 @@ +object Incompat2 { + trait Context { type Out } + + object Context { + def foo(implicit ctx: Context): Option[ctx.Out] = ??? + + def bar(implicit ctx: Context): (Option[ctx.Out], String) = (foo, "foo") + } +} +object Incompat3 { + trait Context { type Out } + + object Context { + given foo(using ctx: Context) as Option[ctx.Out] = ??? + + given bar(using ctx: Context) as (Option[ctx.Out], String) = (foo, "foo") + } +} \ No newline at end of file