Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeMap::noChangeToSymbols discards changes hidden behind symbol #8166

Open
scabug opened this issue Jan 21, 2014 · 2 comments
Open

TypeMap::noChangeToSymbols discards changes hidden behind symbol #8166

scabug opened this issue Jan 21, 2014 · 2 comments
Milestone

Comments

@scabug
Copy link

scabug commented Jan 21, 2014

In TypeMap, the following optimization is too eager:

protected def noChangeToSymbols(origSyms: List[Symbol]) =
      origSyms forall (sym => sym.info eq this(sym.info))

sym.info may still change indirectly, when
sym.info.typeSymbol.info ne this(sym.info.typeSymbol.info)

It turns out it's more than an optimization, as simply setting it to false causes other problems.

repro:

// derived from a real-world Slick app (support #3035)
// running Test should not throw a java.lang.ClassFormatError: Duplicate method name&signature in class file Test$$anonfun$1 
// workaround: uncomment type arg to list below

class AbstractTable[T] { type TableElementType }
class Table[T] extends AbstractTable[T] { type TableElementType = T }

class Query[E, U]
class TableQuery[E <: AbstractTable[_]] extends Query[E, E#TableElementType]

object Test extends App {
  object MyTable extends TableQuery[Table[Long]]

  def list[R](q: Query[_, R]): List[R] = Nil
  list/*[Long]*/(MyTable) collect { case x => x }
}
@scabug
Copy link
Author

scabug commented Jan 21, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8166?orig=1
Reporter: @adriaanm
Affected Versions: 2.10.3
See #8114
Clones #8114

@scabug
Copy link
Author

scabug commented Jan 21, 2014

@retronym said:
Here's a (contrived) TypeMap that might help this discussion. It tries, in one pass, to substitute Longs for Ints and type parameters with their upper bounds:

scala> object map extends TypeMap {
  def apply(tp: Type) = tp match {
    case TypeRef(pre, sym, args) if sym == IntClass   => LongClass.tpe
    case TypeRef(_, sym, args) if sym.isTypeParameter => mapOver(tp.bounds.hi)
    case x => mapOver(x)
  }
}
defined object map

scala> trait T { def m[A <: Int](a: A) }
defined trait T

scala> val m = typeOf[T].member(TermName("m"))
m: $r.intp.global.Symbol = method m

scala> map(m.info)
res31: $r.intp.global.Type = [A <: Long](a: Int)Unit

We could substitute tparams -> tparams1 in result before applying the TypeMap to make this work. But I'm not sure thats the right thing to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants