summaryrefslogtreecommitdiff
path: root/test/files/neg/t7289.check
Commit message (Collapse)AuthorAgeFilesLines
* SI-7289 Less strict type application for TypeVar.Adriaan Moors2013-04-081-0/+4
When a type constructor variable is applied to the wrong number of arguments, return a new type variable whose instance is `ErrorType`. Dissection of the reported test case by @retronym: Define the first implicit: scala> trait Schtroumpf[T] defined trait Schtroumpf scala> implicit def schtroumpf[T, U <: Coll[T], Coll[X] <: Traversable[X]] | (implicit minorSchtroumpf: Schtroumpf[T]): Schtroumpf[U] = ??? schtroumpf: [T, U <: Coll[T], Coll[X] <: Traversable[X]](implicit minorSchtroumpf: Schtroumpf[T])Schtroumpf[U] Call it explicitly => kind error during type inference reported. scala> schtroumpf(null): Schtroumpf[Int] <console>:10: error: inferred kinds of the type arguments (Nothing,Int,Int) do not conform to the expected kinds of the type parameters (type T,type U,type Coll). Int's type parameters do not match type Coll's expected parameters: class Int has no type parameters, but type Coll has one schtroumpf(null): Schtroumpf[Int] ^ <console>:10: error: type mismatch; found : Schtroumpf[U] required: Schtroumpf[Int] schtroumpf(null): Schtroumpf[Int] ^ Add another implicit, and let implicit search weigh them up. scala> implicitly[Schtroumpf[Int]] <console>:10: error: diverging implicit expansion for type Schtroumpf[Int] starting with method schtroumpf implicitly[Schtroumpf[Int]] ^ scala> implicit val qoo = new Schtroumpf[Int]{} qoo: Schtroumpf[Int] = $anon$1@c1b9b03 scala> implicitly[Schtroumpf[Int]] <crash> Implicit search compares the two in-scope implicits in `isStrictlyMoreSpecific`, which constructs an existential type: type ET = Schtroumpf[U] forSome { type T; type U <: Coll[T]; type Coll[_] <: Traversable[_] } A subsequent subtype check `ET <:< Schtroumpf[Int]` gets to `withTypeVars`, which replaces the quantified types with type variables, checks conformance of that substitued underlying type against `Schtroumpf[Int]`, and then tries to solve the collected type constraints. The type var trace looks like: [ create] ?T ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ create] ?U ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ create] ?Coll ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ setInst] Nothing ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], T=Nothing ) [ setInst] scala.collection.immutable.Nil.type( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], U=scala.collection.immutable.Nil.type ) [ setInst] =?scala.collection.immutable.Nil.type( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], Coll==?scala.collection.immutable.Nil.type ) [ create] ?T ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ setInst] Int ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], T=Int ) [ create] ?T ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ create] ?U ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ create] ?Coll ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]] ) [ setInst] Nothing ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], T=Nothing ) [ setInst] Int ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], U=Int ) [ setInst] =?Int ( In Test#schtroumpf[T,U <: Coll[T],Coll[_] <: Traversable[_]], Coll==?Int ) The problematic part is when `?Int` (the type var originated from `U`) is registered as a lower bound for `Coll`. That happens in `solveOne`: for (tparam2 <- tparams) tparam2.info.bounds.hi.dealias match { case TypeRef(_, `tparam`, _) => log(s"$tvar addLoBound $tparam2.tpeHK.instantiateTypeParams($tparams, $tvars)") tvar addLoBound tparam2.tpeHK.instantiateTypeParams(tparams, tvars) case _ => }