Permalink
Browse files

Fixes #SI-5578.

ResetAttrs shouldn't be side-effecting on the original tree,
since it can lead to NPEs in erroneous trees (or maybe even for valid ones?).
Review by @odersky

(Patch by plocinic, applied without his complicity by extempore)
  • Loading branch information...
paulp committed May 2, 2012
1 parent 15e05a4 commit ae5ff6628bb74c16d871a2ada0664cdd5d2399a5
Showing with 53 additions and 8 deletions.
  1. +10 −8 src/compiler/scala/tools/nsc/ast/Trees.scala
  2. +4 −0 test/files/neg/t5578.check
  3. +39 −0 test/files/neg/t5578.scala
@@ -321,24 +321,26 @@ trait Trees extends reflect.internal.Trees { self: Global =>
super.transform {
tree match {
case tpt: TypeTree =>
if (tpt.original != null) {
if (tpt.original != null)
transform(tpt.original)
} else {
if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol))))
tpt.tpe = null
tree
else if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol)))) {
val dupl = tpt.duplicate
dupl.tpe = null
dupl
}
else tree
case TypeApply(fn, args) if args map transform exists (_.isEmpty) =>
transform(fn)
case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
tree
case EmptyTree =>
tree
case _ =>
val dupl = tree.duplicate
if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel))
tree.symbol = NoSymbol
tree.tpe = null
tree
dupl.symbol = NoSymbol
dupl.tpe = null
dupl
}
}
}
@@ -0,0 +1,4 @@
t5578.scala:33: error: No Manifest available for T.
def plus[T: Numeric](x: Rep[T], y: Rep[T]): Rep[T] = Plus[T](x,y)
^
one error found
View
@@ -0,0 +1,39 @@
trait Base {
type Rep[T]
}
trait Expressions {
// constants/symbols (atomic)
abstract class Exp[T]
// ...
case class Sym[T](n: Int) extends Exp[T]
// operations (composite, defined in subtraits)
abstract class Def[T]
// additional members for managing encountered definitions
def findOrCreateDefinition[T](rhs: Def[T]): Sym[T]
implicit def toExp[T:Manifest](d: Def[T]): Exp[T] = findOrCreateDefinition(d)
}
trait BaseExp extends Base with Expressions {
type Rep[T] = Exp[T]
def findOrCreateDefinition[T](rhs: Def[T]): Sym[T] = null // stub
}
trait NumericOps extends Base {
def plus[T](x: Rep[T], y: Rep[T]): Rep[T]
}
trait NumericOpsExp extends BaseExp {
case class Plus[T:Numeric](x: Rep[T], y: Rep[T])
extends Def[T]
def plus[T: Numeric](x: Rep[T], y: Rep[T]): Rep[T] = Plus[T](x,y)
// Possible solutions:
// def plus[T: Numeric: Manifest](x: Rep[T], y: Rep[T]): Rep[T] = Plus[T](x, y)
// def plus[T](x: Rep[T], y: Rep[T])(implicit num: Numeric[T], man: Manifest[T]): Rep[T] = Plus(x,y)
}

0 comments on commit ae5ff66

Please sign in to comment.