Skip to content

Commit 8be7635

Browse files
committed
Allow experimental erased in experimental scopes
Closes #13392
1 parent a38ae20 commit 8be7635

File tree

6 files changed

+68
-2
lines changed

6 files changed

+68
-2
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3115,7 +3115,7 @@ object Parsers {
31153115
case Some(prefix) =>
31163116
in.languageImportContext = in.languageImportContext.importContext(imp, NoSymbol)
31173117
if prefix == nme.experimental
3118-
&& selectors.exists(sel => Feature.experimental(sel.name) != Feature.scala2macros)
3118+
&& selectors.exists(sel => Feature.experimental(sel.name) != Feature.scala2macros && Feature.experimental(sel.name) != Feature.erasedDefinitions)
31193119
then
31203120
Feature.checkExperimentalFeature("features", imp.srcPos)
31213121
for

compiler/src/dotty/tools/dotc/transform/PruneErasedDefs.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import typer.RefChecks
1212
import MegaPhase.MiniPhase
1313
import StdNames.nme
1414
import ast.tpd
15+
import SymUtils._
16+
import config.Feature
1517

1618
/** This phase makes all erased term members of classes private so that they cannot
1719
* conflict with non-erased members. This is needed so that subsequent phases like
@@ -39,13 +41,22 @@ class PruneErasedDefs extends MiniPhase with SymTransformer { thisTransform =>
3941
else cpy.Apply(tree)(tree.fun, tree.args.map(trivialErasedTree))
4042

4143
override def transformValDef(tree: ValDef)(using Context): Tree =
44+
checkErasedInExperimental(tree.symbol)
4245
if !tree.symbol.isEffectivelyErased || tree.rhs.isEmpty then tree
4346
else cpy.ValDef(tree)(rhs = trivialErasedTree(tree.rhs))
4447

4548
override def transformDefDef(tree: DefDef)(using Context): Tree =
49+
checkErasedInExperimental(tree.symbol)
4650
if !tree.symbol.isEffectivelyErased || tree.rhs.isEmpty then tree
4751
else cpy.DefDef(tree)(rhs = trivialErasedTree(tree.rhs))
4852

53+
override def transformTypeDef(tree: TypeDef)(using Context): Tree =
54+
checkErasedInExperimental(tree.symbol)
55+
tree
56+
57+
def checkErasedInExperimental(sym: Symbol)(using Context): Unit =
58+
if sym.is(Erased) && sym != defn.Compiletime_erasedValue && !sym.isInExperimentalScope then
59+
Feature.checkExperimentalFeature("erased", sym.sourcePos)
4960
}
5061

5162
object PruneErasedDefs {

tests/neg-custom-args/no-experimental/experimental.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class Test0 {
77
}
88

99
class Test1 {
10-
import scala.language.experimental.erasedDefinitions // error
10+
import scala.language.experimental.erasedDefinitions
1111
import scala.compiletime.erasedValue
1212
type UnivEq[A]
1313
object UnivEq:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import language.experimental.erasedDefinitions
2+
import annotation.experimental
3+
4+
@experimental
5+
erased class Foo
6+
7+
erased class Bar // error
8+
9+
@experimental
10+
erased def foo = 2
11+
12+
erased def bar = 2 // error
13+
14+
@experimental
15+
erased val foo2 = 2
16+
17+
erased val bar2 = 2 // error
18+
19+
@experimental
20+
def foo3(erased a: Int) = 2
21+
22+
def bar3(erased a: Int) = 2 // error

tests/pos/experimentalErased.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import language.experimental.erasedDefinitions
2+
import annotation.experimental
3+
4+
@experimental
5+
erased class Foo
6+
7+
erased class Bar
8+
9+
@experimental
10+
erased def foo = 2
11+
12+
erased def bar = 2
13+
14+
@experimental
15+
erased val foo2 = 2
16+
17+
erased val bar2 = 2
18+
19+
@experimental
20+
def foo3(erased a: Int) = 2
21+
22+
def bar3(erased a: Int) = 2

tests/pos/i13392.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package scala
2+
import language.experimental.erasedDefinitions
3+
import annotation.{implicitNotFound, experimental}
4+
5+
@experimental
6+
@implicitNotFound("The capability to throw exception ${E} is missing.\nThe capability can be provided by one of the following:\n - A using clause `(using CanThrow[${E}])`\n - A `throws` clause in a result type such as `X throws ${E}`\n - an enclosing `try` that catches ${E}")
7+
erased class CanThrow[-E <: Exception]
8+
9+
@experimental
10+
object unsafeExceptions:
11+
given canThrowAny: CanThrow[Exception] = ???

0 commit comments

Comments
 (0)