-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improvements for implicit searches with top-level type variables (#16001
) Two improvements for implicit searches involving type variables. 1. We now always add a comment when an implicit search is rejected due to the "too unspecific" criterion of #13886, commit [Refine checking for underspecified implicit queries](db5956b). There have been quite a few regressions that hit that problem, so it is good to know immediately what the issue is. 2. There is now a better wildcard approximation of higher-kinded type applications. This makes several programs (including original #15998) compile, which were classified as not specific enough before. Fixes #15998 Fixes #15820 Fixes #15670 Fixes #15160 Fixes #13986
- Loading branch information
Showing
12 changed files
with
144 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
-- [E007] Type Mismatch Error: tests/neg/i15998.scala:6:12 ------------------------------------------------------------- | ||
6 |val _ = foo(1) // error | ||
| ^ | ||
| Found: (1 : Int) | ||
| Required: CC[A] | ||
| | ||
| where: A is a type variable | ||
| CC is a type variable with constraint <: [B] =>> Any | ||
| | ||
| Note that implicit conversions were not tried because the result of an implicit conversion | ||
| must be more specific than CC[A] | ||
| | ||
| longer explanation available when compiling with `-explain` | ||
-- Error: tests/neg/i15998.scala:11:11 --------------------------------------------------------------------------------- | ||
11 |val _ = bar // error | ||
| ^ | ||
| No implicit search was attempted for parameter x of method bar | ||
| since the expected type X is not specific enough | ||
| | ||
| where: X is a type variable |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
given split: Conversion[Int, List[Int]] = ??? | ||
|
||
def foo[A, CC[B]](ring: CC[A]): Unit = () | ||
|
||
val _ = foo(1) // error | ||
|
||
|
||
def bar[X](using x: X): X = x | ||
|
||
val _ = bar // error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
trait Eq[A] { | ||
def eqv(a1: A, a2: A): Boolean | ||
} | ||
|
||
given stringEq: Eq[String] with { | ||
def eqv(a1: String, a2: String) = a1 == a2 | ||
} | ||
|
||
abstract class Newtype[Src] { | ||
opaque type Type = Src | ||
|
||
protected final def derive[F[_]](using ev: F[Src]): F[Type] = ev | ||
} | ||
|
||
object Sample extends Newtype[String] { | ||
given eq: Eq[Type] = derive | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
trait JsonRowEntry { | ||
def readAs[E](implicit c: Read[E]): Option[E] = ??? | ||
} | ||
trait Read[T] | ||
trait Codec[T] extends Read[T] | ||
trait CodecTypeProjection[C[_]] | ||
object JsonTransform { | ||
given SetCodec[T, C[_]: CodecTypeProjection]: scala.Conversion[C[T], C[Set[T]]] = ??? | ||
given SetCodecExp[T, C[_]: CodecTypeProjection](using codec: C[T]): C[Set[T]] = codec | ||
given Codec[String] = ??? | ||
given CodecTypeProjection[Read] = ??? | ||
} | ||
|
||
@main def Test() = { | ||
import JsonTransform.given | ||
val tree = new JsonRowEntry {} | ||
tree.readAs[Set[String]] | ||
} | ||
|
||
trait Box[E] | ||
|
||
trait Domain | ||
|
||
def fun[E, D[_] <: Domain](box: Box[E])(implicit domain: D[E]): Unit = { | ||
|
||
val newBox: Box[E] = ??? | ||
|
||
fun(newBox) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
sealed trait Domain[E] | ||
|
||
final def splitBounds[E, D[X] <: Domain[X]]( | ||
bounds: Seq[E], | ||
)( using domain: D[E]): Seq[E] = | ||
val newBounds: Seq[E] = ??? | ||
splitBounds(newBounds) // does not compile | ||
splitBounds[E,D](newBounds) // does compile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
sealed trait Xa[T] | ||
sealed trait Mu[T] extends Xa[T] | ||
object Xa { | ||
implicit def convertMu[X[x] <: Xa[x], A, B](implicit t: X[A]): X[B] = t.asInstanceOf[X[B]] | ||
} | ||
object Mu { | ||
implicit def mu: Mu[Int] = new Mu[Int] { | ||
override def toString = "mu" | ||
} | ||
} | ||
|
||
object Test extends App { | ||
def constrain(a: Mu[Long]): Unit = println(a) | ||
constrain(Xa.convertMu) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import scala.collection.SeqOps | ||
|
||
trait ComparingOps: | ||
extension[A, CC[B] <: SeqOps[B, CC, CC[B]]](ring: CC[A]) | ||
def isRotationOf(that: CC[A]): Boolean = true | ||
|
||
object RingSeq extends ComparingOps | ||
import RingSeq.* | ||
|
||
@main def Test = | ||
RingSeq.isRotationOf("DAB") // error | ||
"ABCD".isRotationOf("DAB") // error | ||
|
||
// workaround | ||
RingSeq.isRotationOf[Char, IndexedSeq]("DAB") | ||
RingSeq.isRotationOf(wrapString("DAB")) | ||
wrapString("ABCD").isRotationOf("DAB") |