Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
minOf(exprPurity(expr), bindings.map(statPurity))
case NamedArg(_, expr) =>
exprPurity(expr)
case Assign(v, rhs) =>
exprPurity(v) `min` exprPurity(rhs)
case _ =>
Impure
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,14 @@ object Erasure {
super.typedValDef(untpd.cpy.ValDef(vdef)(
tpt = untpd.TypedSplice(TypeTree(sym.info).withSpan(vdef.tpt.span))), sym)

/** Type check assignments, erasing those to erased variables. */
override def typedAssign(tree: untpd.Assign, pt: Type)(using Context): Tree =
val untpd.Assign(lhs, rhs) = tree
if lhs.symbol.is(Flags.Erased) then
checkPureErased(rhs, isArgument = false)
EmptyTree
else super.typedAssign(tree, pt)

/** Besides normal typing, this function also compacts anonymous functions
* with more than `MaxImplementedFunctionArity` parameters to use a single
* parameter of type `[]Object`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,10 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
tree

case tree: Assign =>
// only transform the rhs
cpy.Assign(tree)(tree.lhs, transform(tree.rhs))
if tree.lhs.symbol.is(Erased) then tree
else
// only transform the rhs
cpy.Assign(tree)(tree.lhs, transform(tree.rhs))

case tree: Return =>
// only transform the expr, because `from` is a "pointer"
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,8 @@ object Checking {
end checkScala2Implicit

def checkErasedOK(sym: Symbol)(using Context): Unit =
if sym.is(Method, butNot = Macro)
|| sym.isOneOf(Mutable | Lazy)
if sym.is(Method, butNot = Macro | Accessor)
|| sym.isOneOf(Lazy)
|| sym.isType
then report.error(IllegalErasedDef(sym), sym.srcPos)

Expand Down
10 changes: 7 additions & 3 deletions tests/neg/erased-var.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//> using options -language:experimental.erasedDefinitions

object Test {
erased var i: Int = 1 // error
}
case class Ev(i: Int)

object A:
var ev = Ev(0)
erased val m: Unit = { // error
ev = Ev(1)
}
11 changes: 11 additions & 0 deletions tests/pos/erased-var.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//> using options -language:experimental.erasedDefinitions

case class Ev(i: Int)

def foo(x: Int)(erased ev: Ev): Int = x + 1

object A:
erased var ev = Ev(0)
ev = Ev(1)
foo(1)(ev)

Loading