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

Subtractable nightmare on array loops in 2.12 #10151

Open
scabug opened this issue Jan 16, 2017 · 12 comments
Open

Subtractable nightmare on array loops in 2.12 #10151

scabug opened this issue Jan 16, 2017 · 12 comments

Comments

@scabug
Copy link

scabug commented Jan 16, 2017

I am constantly having things like:

[error] /home/antonkulaga/denigma/processors/main/src/main/scala/org/clulab/swirl2/Reader.scala:173: type arguments [?,Iterable[Any] with Int => Any with scala.collection.generic.Subtractable[_ >: (Int, Int, String) with Int, Iterable[Any] with Int => Any with scala.collection.generic.Subtractable[_ >: (Int, Int, String) with Int, Equals]]{def seq: Iterable[Any] with Int => Any}] do not conform to trait Subtractable's type parameter bounds [A,+Repr <: scala.collection.generic.Subtractable[A,Repr]]
[error]     for(modifier <- tokens.indices) {

(note the code is from https://github.com/antonkulaga/processors that I try to port to 2.12.1)
with java array loops in Scala 2.12.1 (same code works well on Scala 2.11.8).

@scabug
Copy link
Author

scabug commented Jan 16, 2017

Imported From: https://issues.scala-lang.org/browse/SI-10151?orig=1
Reporter: Anton Kulaga (antonkulaga)
Affected Versions: 2.12.1

@scabug
Copy link
Author

scabug commented Jan 16, 2017

@som-snytt said:
Reducedly,

package badindices

import scala.collection.mutable
import scala.collection.mutable.{ArrayBuffer, ListBuffer}

case class DirectedGraph[A](a: A)

class Reader {
  class CoNLLToken(
    val word:String,
    val pos:String,
    val lemma:String,
    val dep:(Int, String), // head, label
    val pred:Int,
    val frameBits:Array[String]) {
    override def toString:String = word + "/" + pos + "/" + dep._1 + "/" + dep._2 + "/" + pred
  }

  def toDirectedGraph(tokens:Array[CoNLLToken]):DirectedGraph[String] = {
    val edges = new mutable.ListBuffer[(Int, Int, String)] // head, modifier, label
    val roots = new mutable.HashSet[Int]()
    for(modifier <- tokens.indices) {
      val head = tokens(modifier).dep._1
      if(head >= 0)
        edges += new Tuple3(head, modifier, tokens(modifier).dep._2)
      else
        roots += modifier
    }
    DirectedGraph[String]("hi")
  }
}

with the challenging inference

      scala.Predef.refArrayOps[Reader.this.CoNLLToken](tokens).indices.foreach[scala.collection.mutable.Iterable[_ >: (Int, Int, String) with Int] with scala.collection.AbstractIterable[Any] with scala.collection.mutable.Cloneable[scala.collection.mutable.Iterable[_ >: (Int, Int, String) with Int] with scala.collection.mutable.Cloneable[scala.collection.mutable.Iterable[_ >: (Int, Int, String) with Int] with scala.collection.mutable.Cloneable[Cloneable with Mutable with Equals] with Int => Any{def seq: Cloneable with Mutable with Equals}] with Int => Any] with scala.collection.mutable.Builder[(Int, Int, String) with Int,Iterable[Any] with Int => Any{def seq: Iterable[Any] with Int => Any}] with Int => Any with Serializable with scala.collection.generic.Shrinkable[(Int, Int, String) with Int] with scala.collection.generic.Subtractable[_ >: (Int, Int, String) with Int, Iterable[Any] with Int => Any with scala.collection.generic.Subtractable[_ >: (Int, Int, String) with Int, Iterable[Any] with Int => Any with scala.collection.generic.Subtractable[_ >: (Int, Int, String) with Int, Equals]]{def seq: Iterable[Any] with Int => Any}] with scala.collection.script.Scriptable[_ >: (Int, Int, String) with Int]](((modifier: Int) => {
        val head: Int = tokens.apply(modifier).dep._1;
        if (head.>=(0))
          edges.+=(new (Int, Int, String)(head, modifier, tokens.apply(modifier).dep._2))
        else
          roots.+=(modifier)
      }));

@scabug
Copy link
Author

scabug commented Jan 16, 2017

@som-snytt said:
The workaround is to add a unit value after the if/else and avoid the inference.

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@stuhood
Copy link

stuhood commented Jun 6, 2017

Encountered this one today... pretty awkward.

@mbryzek
Copy link

mbryzek commented Jul 27, 2017

Here is another example of how to reproduce (note the example is a bit contrived as we reduced to remove unnecessary logic)

case class Country(name: String)

object Countries {
  def find(name: String): Option[Country] = None
}

import scala.collection.mutable

object Main extends App {

  val data: Seq[(String, String)] = Nil

  val invalid = mutable.Set[String]()
  val countries = mutable.ListBuffer[Country]()

  data.foreach { case (label, code) =>
    Countries.find(code) match {
      case None => invalid
      case Some(c) => countries
    }
  }

}

sbt compile results in:

[error] /web/foo/Main.scala:16: type arguments [?,Iterable[java.io.Serializable] with String with Int => Any with scala.collection.generic.Subtractable[_ >: String with Country <: java.io.Serializable, Iterable[java.io.Serializable] with String with Int => Any with scala.collection.generic.Subtractable[_ >: String with Country <: java.io.Serializable, Equals]]{def seq: Iterable[java.io.Serializable] with String with Int => Any}] do not conform to trait Subtractable's type parameter bounds [A,+Repr <: scala.collection.generic.Subtractable[A,Repr]]
[error]   data.foreach { case (label, code) =>
[error]        ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 5 s, completed Jul 27, 2017 4:06:22 PM

@SethTisue
Copy link
Member

#10359 has a nice short reproduction (of what at least seems to be the same issue, investigation would be needed to confirm)

@SethTisue SethTisue modified the milestones: Backlog, 2.13.0-M4 Mar 12, 2018
@SethTisue
Copy link
Member

SethTisue commented Mar 12, 2018

I'm putting this on the 2.13.0-M4 milestone because I think we should at least check whether any of these reproducers still fail after new collections land. (If they stop failing, it won't mean the real inference issue is fixed, but it will lower the significance of the bug.)

@joroKr21
Copy link
Member

joroKr21 commented Mar 12, 2018

There are other type inference issues related to F-bounded types (I assume this is the case here) like #3528. The problem is in glb/lub of such types.

@SethTisue SethTisue added the lub label Mar 12, 2018
@lrytz lrytz modified the milestones: 2.13.0-M4, 2.13.0-M5 Apr 19, 2018
masda70 added a commit to thymeflow/thymeflow-back that referenced this issue Apr 21, 2018
@julienrf
Copy link

I’ve tried compiling the code of #10151 (comment) in 2.13.x branch and there is no error anymore (note that we have removed Subtractable in the new collections)

@SethTisue SethTisue modified the milestones: 2.13.0-M5, Backlog Jun 25, 2018
@SethTisue
Copy link
Member

Can someone suggest a more informative title for this ticket?

@nivekastoreth
Copy link

I've created a gist displaying what I believe is the same bug but with a workaround that is slightly different than the samples shown above:
https://gist.github.com/nivekastoreth/5c0e005c986a3827aa29a17a9274fb40

Because these are specs2 tests and not some unit loop, the workaround mentioned previously in this ticket wasn't applicable.

@som-snytt
Copy link

For the title, I like "Subtractable nightmare", especially as it is almost Halloween and I haven't decided on a costume yet, but I'm also partial to the linked ticket "Perfectly reasonable code doesn't compile", which has better jokes in the comments.

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

No branches or pull requests

9 participants