-
Notifications
You must be signed in to change notification settings - Fork 21
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
implicit search + type inference is order-dependent #8341
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8341?orig=1 |
@adriaanm said (edited on Feb 26, 2014 8:29:46 AM UTC): +| | | |-- convertGenTraversableOnceToCombinable BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local OrSpec> in OrSpec) implicits disabled
+| | | | [adapt] [G, ERR, TRAVONCE[+e] <: scala.collection.GenTraversableO... adapted to [G, ERR, TRAVONCE[+e] <: scala.collection.GenTraversableO...
+| | | | \-> (xs: TRAVONCE[Or[G,Every[ERR]]])(implicit cbf: scala.collection.generic.CanBuildFrom[TRAVONCE[Or[G,Every[ERR]]],G,TRAVONCE[G]])Combinable[G,ERR,TRAVONCE]
+| | | solving for (G: ?G, ERR: ?ERR, TRAVONCE: ?TRAVONCE)
| | | |-- convertGenSetToCombinable BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local OrSpec> in OrSpec) implicits disabled
| | | | [adapt] [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... adapted to [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET...
| | | | \-> (xs: SET[X with Or[G,Every[ERR]]])(implicit cbf: scala.collection.generic.CanBuildFrom[SET[X with Or[G,Every[ERR]]],G,SET[G]])Combinable[G,ERR,SET]
@@ -50,22 +40,28 @@
| | | [adapt] [A]=> scala.collection.generic.CanBuildFrom[scala.collect... adapted to [A]=> scala.collection.generic.CanBuildFrom[scala.collect... based on pt scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[Bad[Nothing,One[String]] with Or[G,Every[String]]],G,scala.collection.immutable.Set[G]]
| | | solving for (G: ?G)
| | | [adapt] convertGenSetToCombinable adapted to [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... based on pt scala.collection.immutable.Set[Bad[Nothing,One[String]]] => ?{def combined: ?}
-| | | solving for (G: ?G, ERR: ?ERR, TRAVONCE: ?TRAVONCE)
-| | | solving for (G: ?G, ERR: ?ERR, X: ?X, SET: ?SET)
-| | | |-- convertGenTraversableOnceToCombinable BYVALmode-EXPRmode-FUNmode-POLYmode (silent solving: type G: value <local OrSpec> in OrSpec) implicits disabled
-| | | | [adapt] [G, ERR, TRAVONCE[+e] <: scala.collection.GenTraversableO... adapted to [G, ERR, TRAVONCE[+e] <: scala.collection.GenTraversableO...
-| | | | \-> (xs: TRAVONCE[Or[G,Every[ERR]]])(implicit cbf: scala.collection.generic.CanBuildFrom[TRAVONCE[Or[G,Every[ERR]]],G,TRAVONCE[G]])Combinable[G,ERR,TRAVONCE]
-| | | solving for (G: ?G, G: ?G, ERR: ?ERR, TRAVONCE: ?TRAVONCE)
-| | | |-- [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... EXPRmode-POLYmode-QUALmode (silent: value <local OrSpec> in OrSpec)
+| | | |-- [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... EXPRmode-POLYmode-QUALmode (silent solving: type G: value <local OrSpec> in OrSpec)
+| | | | solving for (G: ?G)
+| | | | solving for (G: ?G)
| | | | solving for (A: ?A)
| | | | [adapt] [A]=> scala.collection.generic.CanBuildFrom[scala.collect... adapted to [A]=> scala.collection.generic.CanBuildFrom[scala.collect... based on pt scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[Bad[Nothing,One[String]] with Or[G,Every[String]]],G,scala.collection.immutable.Set[G]]
-| | | | |-- [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... EXPRmode-POLYmode-QUALmode (silent: value <local OrSpec> in OrSpec)
+| | | | solving for (G: ?G)
+| | | | |-- [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... EXPRmode-POLYmode-QUALmode (silent solving: type G: value <local OrSpec> in OrSpec)
+| | | | | solving for (G: ?G)
| | | | | \-> Combinable[G,String,scala.collection.immutable.Set]
| | | | [adapt] [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET... adapted to [G, ERR, X, SET[e] <: scala.collection.GenSet[e]](xs: SET...
| | | | \-> Combinable[G,String,scala.collection.immutable.Set]
-| | | |-- OrSpec.this.convertGenSetToCombinable[G, String, Bad[Noth... BYVALmode-EXPRmode (site: value <local OrSpec> in OrSpec)
-| | | | \-> Or[scala.collection.immutable.Set[G],Every[String]]
-| | | \-> Or[scala.collection.immutable.Set[G],Every[String]]
+/Users/adriaan/Desktop/bugs/t8341_nok.scala:43: error: type mismatch;
+ found : scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set.Coll,Nothing,scala.collection.immutable.Set[Nothing]]
+ (which expands to) scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[_],Nothing,scala.collection.immutable.Set[Nothing]]
+ required: scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[Bad[Nothing,One[String]] with Or[G,Every[String]]],G,scala.collection.immutable.Set[G]]
+ Set(Bad(One("oops"))).combined
+ ^
+/Users/adriaan/Desktop/bugs/t8341_nok.scala:43: error: value combined is not a member of scala.collection.immutable.Set[Bad[Nothing,One[String]]]
+ Set(Bad(One("oops"))).combined
+ ^
+| | | solving for (G: ?G)
+| | | \-> <error> |
Chua Chee Seng (cheeseng) said: git clone https://github.com/cheeseng/scalatest.git cd scalatest git checkout test-2.11-RC1 sbt test I'll keep the branch around until this issue is fixed. :) |
Chua Chee Seng (cheeseng) said: git clone https://github.com/cheeseng/scalatest.git |
@adriaanm said: I don't think we'll be able to fix this in 2.11.0 anymore. To be honest, I forgot to set the fix version on this one. My bad. Too much context-switching going on these last couple of weeks.... I'll hold off pushing RC2 to maven until my Tuesday morning, but the tag has already been pushed... |
@adriaanm said: |
@adriaanm said: |
@adriaanm said: |
@retronym said: OrSpec.this.convertGenTraversableOnceToCombinable[Int, String, Iterator](immutable.this.List.apply[Product with Serializable with Or[Int,One[String]]](Good.apply[Int, Nothing](3), Bad.apply[Nothing, One[String]](One.apply[String]("oops"))).iterator)(collection.this.Iterator.IteratorCanBuildFrom[Int]).combined;
OrSpec.this.convertGenTraversableOnceToCombinable[Int, ERR, Iterator](immutable.this.List.apply[Good[Int,Nothing]](Good.apply[Int, Nothing](3)).iterator)(collection.this.Iterator.IteratorCanBuildFrom[Int]).combined;
OrSpec.this.convertGenSetToCombinable[G, String, Bad[Nothing,One[String]], scala.collection.immutable.Set](scala.this.Predef.Set.apply[Bad[Nothing,One[String]]](Bad.apply[Nothing, One[String]](One.apply[String]("oops"))))(immutable.this.Set.canBuildFrom[G]).combined;
OrSpec.this.convertGenSetToCombinable[G, String, Bad[Nothing,One[String]], scala.collection.immutable.Set](scala.this.Predef.Set.apply[Bad[Nothing,One[String]]](Bad.apply[Nothing, One[String]](One.apply[String]("darn")), Bad.apply[Nothing, One[String]](One.apply[String]("oops"))))(immutable.this.Set.canBuildFrom[G]).combined
^
|_ undetermined! The |
@retronym said: This patch disables the sorting:
The test then happens to pass unconditionally. But if you invert the declaration order of the two implicits, it then fails on all four. So two key questions here:
|
@retronym said: trait Combinable[A] {
def combined = 9
}
trait Trav0[+A]
trait Set0[A] extends T[A @annotation.unchecked.uncheckedVariance]
trait CB[-Elem, +To]
trait List[+A]
object O {
implicit def listCB[A]: CB[A, List[A]] = ???
implicit def CovariantMCombinable[G, M[+e]] (xs: M[Option[G]]): Combinable[G] = ???
implicit def Set0Combinable[G] (xs: Set0[_ <: Option[G]])(implicit cbf: CB[G, List[Any]]): Combinable[G] = ???
}
class T1 {
import O.listCB
import O.CovariantMCombinable
import O.Set0Combinable
val s: Set0[Option[Nothing]] = ???
s.combined // okay
}
class T2 {
import O.listCB
import O.Set0Combinable
import O.CovariantMCombinable
val s: Set0[Option[Nothing]] = ???
s.combined // fails
} |
@retronym said: |
@retronym said (edited on Mar 18, 2014 10:35:27 AM UTC): trait Covariant[+A]
trait Invariant[A] extends Covariant[A @annotation.unchecked.uncheckedVariance]
trait Combinable[G] {
def combined = 0
}
trait CanBuildFrom[+C]
object C {
implicit def convert1[G, TRAVONCE[+e] <: Covariant[e]]
(xs: TRAVONCE[G]): Combinable[G] = ???
implicit def convert2[G, SET[e] <: Invariant[e]]
(xs: SET[_ <: G])
(implicit cbf: CanBuildFrom[SET[G]]): Combinable[G] = ???
implicit def cbf[A]: CanBuildFrom[Invariant[A]] = ???
}
class Test1 {
import C.{cbf, convert1, convert2}
val s: Invariant[Nothing] = ???
s.combined // fail
}
class Test2 {
import C.{cbf, convert2, convert1}
val s: Invariant[Nothing] = ???
s.combined // okay
}
class Test3 {
import C.{cbf, convert1, convert2}
val s: Invariant[Null] = ???
s.combined // okay
}
class Test4 {
import C.{cbf, convert2, convert1}
val s: Invariant[Null] = ???
s.combined // okay
} Running that with the patch above to remove usage-count-based implicit sorting:
|
@retronym said: |
@retronym said: |
@adriaanm said: |
Chua Chee Seng (cheeseng) said: |
@adriaanm said: |
Chua Chee Seng (cheeseng) said: |
@adriaanm said: |
Chua Chee Seng (cheeseng) said: |
@adriaanm said: |
@bvenners said: |
@retronym said (edited on Mar 19, 2014 12:55:55 PM UTC): implicit def convertGenSetToCombinableNothing[ERR, X, SET[e] <: GenSet[e]]
(xs: SET[X with (Nothing Or Every[ERR])])
(implicit cbf: CanBuildFrom[SET[X with (Nothing Or Every[ERR])], Nothing, SET[Nothing]]): Combinable[Nothing, ERR, SET] =
new Combinable[Nothing, ERR, SET] { def combined: SET[Nothing] Or Every[ERR] = ??? } Makes things compile again. Background: In uses like: Set(Bad(One("oops"))).combined The inferred type is So even the explicit call to that converter fails: convertGenSetToCombinable(Set(Bad(One("oops")))).combined After our patch, the implicit view fails in the same way as the explicit way in all cases. |
@bvenners said: Unfortunately adding that implicit didn't seem to solve our type errors in the real ScalaTest. I put the build that exhibits the problem in this branch: https://github.com/scalatest/scalatest/tree/problem-in-2.11.0-RC3 I updated the ant build, not yet the sbt one, so to reproduce the problem just checkout the problem-in-2.11.0-RC3 branch, cd into it, and type: ant test You'll get 22 compiler errors. I will keep investigating, but since this is holding up the show I thought I'd share it with you in case you can more quickly see the way to a solution. |
@bvenners said (edited on Mar 20, 2014 12:11:43 AM UTC): Sorry I didn't have time to look carefully early today. 10 of the errors were because I merged a pull request into master instead of 2.1.x. I removed unused BeanProperty imports and that zapped 10 of the errors. The problem-in-2.11.0-RC3 branch is down to the 12 that are really caused by the implicit resolution issue. ... And now that I look at the remaining errors they are not about Set. I'll try the same trick for GenTraversable... Bill |
@adriaanm said: implicit def convertGenTraversableOnceToCombinableNothing[ERR, EVERY[b] <: Every[b], TRAVONCE[+e] <: GenTraversableOnce[e]](xs: TRAVONCE[Nothing Or EVERY[ERR]])(implicit cbf: CanBuildFrom[TRAVONCE[Nothing Or EVERY[ERR]], Nothing, TRAVONCE[Nothing]]): Combinable[Nothing, ERR, TRAVONCE] = convertGenTraversableOnceToCombinable[Nothing, ERR, EVERY, TRAVONCE](xs)(cbf)
implicit def convertGenSetToCombinableNothing[ERR, X, EVERY[b] <: Every[b], SET[e] <: GenSet[e]](xs: SET[X with (Nothing Or EVERY[ERR])])(implicit cbf: CanBuildFrom[SET[X with (Nothing Or EVERY[ERR])], Nothing, SET[Nothing]]): Combinable[Nothing, ERR, SET] = convertGenSetToCombinable[Nothing, ERR, X, EVERY, SET](xs)(cbf)
implicit def convertEveryToCombinableNothing[ERR](oneToMany: Every[Nothing Or Every[ERR]]): Combinable[Nothing, ERR, Every] = convertEveryToCombinable[Nothing, ERR](oneToMany)
implicit def convertOptionToCombinableNothing[ERR](option: Option[Nothing Or Every[ERR]]): Combinable[Nothing, ERR, Option] = convertOptionToCombinable[Nothing, ERR](option) did it for me |
@bvenners said: Bill |
Minimized from scalatest:
The text was updated successfully, but these errors were encountered: