Skip to content

Commit

Permalink
Fix Applications#compare#isAsGood#isGiven to use parameter
Browse files Browse the repository at this point in the history
to apply the logic prioritizing givens over implicits as intended in scala#19300

Fix scala#21212
  • Loading branch information
EugeneFlesselle authored and WojciechMazur committed Jul 24, 2024
1 parent 879e820 commit 3577352
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1817,7 +1817,7 @@ trait Applications extends Compatibility {
}
case _ => // (3)
def isGiven(alt: TermRef) =
alt1.symbol.is(Given) && alt.symbol != defn.NotGivenClass
alt.symbol.is(Given) && alt.symbol != defn.NotGivenClass
def compareValues(tp1: Type, tp2: Type)(using Context) =
isAsGoodValueType(tp1, tp2, isGiven(alt1), isGiven(alt2))
tp2 match
Expand All @@ -1837,7 +1837,7 @@ trait Applications extends Compatibility {
* available in 3.0-migration if mode `Mode.OldImplicitResolution` is turned on as well.
* It is used to highlight differences between Scala 2 and 3 behavior.
*
* - In Scala 3.0-3.5, the behavior is as follows: `T <:p U` iff there is an impliit conversion
* - In Scala 3.0-3.5, the behavior is as follows: `T <:p U` iff there is an implicit conversion
* from `T` to `U`, or
*
* flip(T) <: flip(U)
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/i13044.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -Xmax-inlines:33
//> using options -Xmax-inlines:35

import scala.deriving.Mirror
import scala.compiletime._
Expand Down
33 changes: 33 additions & 0 deletions tests/pos/i21212.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

trait Functor[F[_]]:
def map[A, B](fa: F[A])(f: A => B): F[B] = ???
trait Monad[F[_]] extends Functor[F]
trait MonadError[F[_], E] extends Monad[F]:
def raiseError[A](e: E): F[A]
trait Temporal[F[_]] extends MonadError[F, Throwable]

trait FunctorOps[F[_], A]:
def map[B](f: A => B): F[B] = ???
implicit def toFunctorOps[F[_], A](target: F[A])(implicit tc: Functor[F]): FunctorOps[F, A] = ???

class ContextBounds[F[_]: Temporal](using err: MonadError[F, Throwable]):
def useCase = err.raiseError(new RuntimeException())
val bool: F[Boolean] = ???
def fails = toFunctorOps(bool).map(_ => ()) // warns under -source:3.5, // error under -source:3.6

class UsingArguments[F[_]](using Temporal[F])(using err: MonadError[F, Throwable]):
def useCase = err.raiseError(new RuntimeException())
val bool: F[Boolean] = ???
def works = toFunctorOps(bool).map(_ => ()) // warns under -source:3.5


object Minimization:

trait A
trait B extends A

def test1(using a1: A)(using b1: B) = summon[A] // picks (most general) a1
def test2(using a2: A)(implicit b2: B) = summon[A] // picks (most general) a2, was ambiguous
def test3(implicit a3: A, b3: B) = summon[A] // picks (most specific) b3

end Minimization

0 comments on commit 3577352

Please sign in to comment.