Skip to content

Commit

Permalink
Add tests for error conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Feb 17, 2022
1 parent 004c4f6 commit 8e529b1
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 6 deletions.
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,7 @@ class Namer { typer: Typer =>
else if sym.isAllOf(JavaModule) then
Skip
else if pathMethod.exists && mbr.isType then
No("cannot be exported as extension method")
No("is a type, so it cannot be exported as extension method")
else
Yes
}
Expand Down Expand Up @@ -1296,7 +1296,8 @@ class Namer { typer: Typer =>
process(stats1)(using ctx.importContext(stat, symbolOfTree(stat)))
case (stat: ExtMethods) :: stats1 =>
for case exp: Export <- stat.methods do
processExport(exp, exportPathSym(exp.expr, stat))
val pathSym = exportPathSym(exp.expr, stat)
if pathSym.exists then processExport(exp, pathSym)
process(stats1)
case stat :: stats1 =>
process(stats1)
Expand Down
11 changes: 7 additions & 4 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2565,10 +2565,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val selectors1 = typedSelectors(imp.selectors)
assignType(cpy.Import(imp)(expr1, selectors1), sym)

def typedExport(exp: untpd.Export)(using Context): Export =
val expr1 = exp.expr.removeAttachment(TypedAhead).getOrElse(EmptyTree)
val selectors1 = typedSelectors(exp.selectors)
assignType(cpy.Export(exp)(expr1, selectors1))
def typedExport(exp: untpd.Export)(using Context): Tree =
exp.expr.removeAttachment(TypedAhead) match
case Some(expr1) =>
val selectors1 = typedSelectors(exp.selectors)
assignType(cpy.Export(exp)(expr1, selectors1))
case _ =>
errorTree(exp, em"exports are only allowed from objects and classes")

def typedPackageDef(tree: untpd.PackageDef)(using Context): Tree =
val pid1 = withMode(Mode.InPackageClauseName)(typedExpr(tree.pid, AnySelectionProto))
Expand Down
29 changes: 29 additions & 0 deletions tests/neg/export-in-extension.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- Error: tests/neg/export-in-extension.scala:14:13 --------------------------------------------------------------------
14 | export c1.* // error
| ^^
| export qualifier c1 is not a parameterless companion extension method
-- Error: tests/neg/export-in-extension.scala:19:22 --------------------------------------------------------------------
19 | export cm.{bar, D} // error
| ^
| no eligible member D at O.O2.cm
| O.O2.cm.D cannot be exported because it is a type, so it cannot be exported as extension method
-- Error: tests/neg/export-in-extension.scala:20:18 --------------------------------------------------------------------
20 | export this.cm.baz // error
| ^^^^^^^
| export qualifier must be a simple reference to a companion extension method
-- Error: tests/neg/export-in-extension.scala:24:13 --------------------------------------------------------------------
24 | export missing.* // error
| ^^^^^^^
| export qualifier missing is not a parameterless companion extension method
-- Error: tests/neg/export-in-extension.scala:28:13 --------------------------------------------------------------------
28 | export cm.* // error
| ^^
| export qualifier cm is not a parameterless companion extension method
-- Error: tests/neg/export-in-extension.scala:33:13 --------------------------------------------------------------------
33 | export cm.* // error
| ^^
| export qualifier cm is not a parameterless companion extension method
-- Error: tests/neg/export-in-extension.scala:38:13 --------------------------------------------------------------------
38 | export cm.* // error
| ^^^^^^^^^^^
| exports are only allowed from objects and classes
40 changes: 40 additions & 0 deletions tests/neg/export-in-extension.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
object O:

class C(x: Int):
def bar = x
def baz(y: Int) = x + y
val bam = x * x
def :: (y: Int) = x - y
class D

val c1 = C(1)

object O1:
extension (x: Int)
export c1.* // error

object O2:
extension (x: Int)
private def cm = new C(x)
export cm.{bar, D} // error
export this.cm.baz // error

object O3:
extension (x: Int)
export missing.* // error

object O4:
extension (x: Int)
export cm.* // error

object O5:
extension (x: Int)
private def cm(y: C) = C
export cm.* // error

{
extension (x: Int)
private def cm = new C(x)
export cm.* // error
}

9 changes: 9 additions & 0 deletions tests/run/export-in-extension.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ object O:
def succ2: Int = succ + 1
def ::: (y: Int) = x - y

object O2:
import O.C
extension (x: Int)
private def cm = new C(x)
export cm.{bar, baz, bam, ::}
def succ: Int = x + 1
def succ2: Int = succ + 1
def ::: (y: Int) = x - y

@main def Test =
import O.*
assert(3.succ2 == 5)
Expand Down

0 comments on commit 8e529b1

Please sign in to comment.