Skip to content

Commit 6a1db57

Browse files
Revert "Compensate loss of transitivity" (#21356)
This reverts commit 7c4bd67 See [#21344 comment] (#21344 (comment)) We will have to reconsider how to alleviate the transitory problem before releasing 3.6. Fixes #21320 Fixes #21352
2 parents 15a0d05 + 5408a80 commit 6a1db57

File tree

7 files changed

+171
-15
lines changed

7 files changed

+171
-15
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Implicits.scala

+3-15
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,8 @@ trait Implicits:
13851385
def disambiguate(alt1: SearchResult, alt2: SearchSuccess) = alt1 match
13861386
case alt1: SearchSuccess =>
13871387
var diff = compareAlternatives(alt1, alt2, disambiguate = true)
1388+
assert(diff <= 0 || isWarnPriorityChangeVersion)
1389+
// diff > 0 candidates should already have been eliminated in `rank`
13881390
if diff == 0 && alt1.ref =:= alt2.ref then
13891391
diff = 1 // See i12951 for a test where this happens
13901392
else if diff == 0 && alt2.isExtension then
@@ -1636,21 +1638,7 @@ trait Implicits:
16361638
validateOrdering(ord)
16371639
throw ex
16381640

1639-
val sorted = sort(eligible)
1640-
val res = sorted match
1641-
case first :: rest =>
1642-
val firstIsImplicit = first.ref.symbol.is(Implicit)
1643-
if rest.exists(_.ref.symbol.is(Implicit) != firstIsImplicit) then
1644-
// Mixture of implicits and givens
1645-
// Rank implicits first, then, if there is a given that it better than the best implicit(s)
1646-
// switch over to givens.
1647-
val (sortedImplicits, sortedGivens) = sorted.partition(_.ref.symbol.is(Implicit))
1648-
val implicitResult = rank(sortedImplicits, NoMatchingImplicitsFailure, Nil)
1649-
rank(sortedGivens, implicitResult, Nil)
1650-
else
1651-
rank(sorted, NoMatchingImplicitsFailure, Nil)
1652-
case _ =>
1653-
NoMatchingImplicitsFailure
1641+
val res = rank(sort(eligible), NoMatchingImplicitsFailure, Nil)
16541642

16551643
// Issue all priority change warnings that can affect the result
16561644
val shownWarnings = priorityChangeWarnings.toList.collect:
File renamed without changes.

Diff for: tests/pos/i21320b.scala

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import scala.deriving.*
2+
import scala.compiletime.*
3+
4+
trait ConfigMonoid[T]:
5+
def zero: T
6+
def orElse(main: T, defaults: T): T
7+
8+
object ConfigMonoid:
9+
given option[T]: ConfigMonoid[Option[T]] = ???
10+
11+
inline def zeroTuple[C <: Tuple]: Tuple =
12+
inline erasedValue[C] match
13+
case _: EmptyTuple => EmptyTuple
14+
case _: (t *: ts) =>
15+
summonInline[ConfigMonoid[t]].zero *: zeroTuple[ts]
16+
17+
inline def valueTuple[C <: Tuple, T](index: Int, main: T, defaults: T): Tuple =
18+
inline erasedValue[C] match
19+
case _: EmptyTuple => EmptyTuple
20+
case _: (t *: ts) =>
21+
def get(v: T) = v.asInstanceOf[Product].productElement(index).asInstanceOf[t]
22+
summonInline[ConfigMonoid[t]].orElse(get(main), get(defaults)) *: valueTuple[ts, T](
23+
index + 1,
24+
main,
25+
defaults
26+
)
27+
28+
inline given derive[T](using m: Mirror.ProductOf[T]): ConfigMonoid[T] =
29+
new ConfigMonoid[T]:
30+
def zero: T = m.fromProduct(zeroTuple[m.MirroredElemTypes])
31+
def orElse(main: T, defaults: T): T = m.fromProduct(valueTuple[m.MirroredElemTypes, T](0, main, defaults))
32+
33+
34+
35+
final case class PublishOptions(
36+
v1: Option[String] = None,
37+
v2: Option[String] = None,
38+
v3: Option[String] = None,
39+
v4: Option[String] = None,
40+
v5: Option[String] = None,
41+
v6: Option[String] = None,
42+
v7: Option[String] = None,
43+
v8: Option[String] = None,
44+
v9: Option[String] = None,
45+
ci: PublishContextualOptions = PublishContextualOptions(),
46+
)
47+
object PublishOptions:
48+
implicit val monoid: ConfigMonoid[PublishOptions] = ConfigMonoid.derive
49+
50+
final case class PublishContextualOptions(
51+
v1: Option[String] = None,
52+
v2: Option[String] = None,
53+
v3: Option[String] = None,
54+
v4: Option[String] = None,
55+
v5: Option[String] = None,
56+
v6: Option[String] = None,
57+
v7: Option[String] = None,
58+
v8: Option[String] = None,
59+
v9: Option[String] = None,
60+
v10: Option[String] = None,
61+
v11: Option[String] = None,
62+
v12: Option[String] = None,
63+
v13: Option[String] = None,
64+
v14: Option[String] = None,
65+
v15: Option[String] = None,
66+
v16: Option[String] = None,
67+
v17: Option[String] = None,
68+
v18: Option[String] = None,
69+
v19: Option[String] = None,
70+
v20: Option[String] = None
71+
)
72+
object PublishContextualOptions:
73+
implicit val monoid: ConfigMonoid[PublishContextualOptions] = ConfigMonoid.derive // was crash

Diff for: tests/pos/i21352a/schema.scala

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//> using options -source:3.5
2+
3+
case class Schema[T](format: String):
4+
def asOption: Schema[Option[T]] = ???
5+
def name(name: Option[SName]): Schema[T] = ???
6+
def format(f: String): Schema[T] = ???
7+
8+
object Schema extends SchemaCompanionMacros:
9+
implicit def schemaForOption[T: Schema]: Schema[Option[T]] =
10+
implicitly[Schema[T]]
11+
???
12+
13+
trait SchemaCompanionMacros extends SchemaDerivation:
14+
given derivedStringBasedUnionEnumeration[S](using IsUnionOf[String, S]): Schema[S] =
15+
val x: Schema[S] = ???
16+
x.name(None)
17+
18+
@main def Test =
19+
case class Foo(x: Int) derives Schema

Diff for: tests/pos/i21352a/schemaDerivation.scala

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//> using options -source:3.5
2+
3+
import scala.deriving.*
4+
import scala.quoted.*
5+
6+
trait SName
7+
abstract class CaseClass[Typeclass[_], Type]:
8+
def param: CaseClass.Param[Typeclass, Type]
9+
10+
object CaseClass:
11+
trait Param[Typeclass[_], Type]:
12+
type PType
13+
def typeclass: Typeclass[PType]
14+
15+
16+
sealed trait IsUnionOf[T, A]
17+
object IsUnionOf:
18+
transparent inline given derived[T, A]: IsUnionOf[T, A] = ${ deriveImpl[T, A] }
19+
private def deriveImpl[T, A](using quotes: Quotes): Expr[IsUnionOf[T, A]] = ???
20+
21+
trait SchemaDerivation:
22+
inline implicit def derived[T](implicit m: Mirror.Of[T]): Schema[T] =
23+
val ctx: CaseClass[Schema, T] = ???
24+
val valueSchema = ctx.param.typeclass
25+
val format = valueSchema.format
26+
???

Diff for: tests/pos/i21352b.scala

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
object serializer:
3+
trait Reader[T]
4+
trait Writer[T]
5+
// Needs to be implicit val
6+
implicit val UnitReader: Reader[Unit] = ???
7+
implicit val StringReader: Reader[String] = ???
8+
// A way to derive instances needs to be available
9+
inline given superTypeReader[T: scala.reflect.ClassTag]: Reader[T] = ???
10+
import serializer.Reader
11+
12+
trait Codec[T]
13+
trait Channel[F[_]]:
14+
def notificationStub[In: Codec](): In => F[Unit]
15+
trait Monadic[F[_]]
16+
17+
sealed abstract class LSPNotification():
18+
type In
19+
given inputReader: Reader[In]
20+
21+
class PreparedNotification[X <: LSPNotification](val x: X, val in: x.In):
22+
type In = x.In
23+
24+
trait Communicate[F[_]]:
25+
def notification[X <: LSPNotification](notif: X, in: notif.In): F[Unit]
26+
27+
object Communicate:
28+
given codec[T: Reader]: Codec[T] = ???
29+
30+
def channel[F[_]: Monadic](channel: Channel[F]) =
31+
new Communicate[F]:
32+
override def notification[X <: LSPNotification](notif: X, in: notif.In): F[Unit] =
33+
channel.notificationStub().apply(in) // was error

Diff for: tests/pos/i21352c.scala

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
trait Text[T]
3+
trait Read[A]
4+
object Read extends ReadImplicits:
5+
implicit val unit: Read[Unit] = ???
6+
trait ReadImplicits:
7+
import scala.deriving.*
8+
given roe: Read[Option[EmptyTuple]] = ???
9+
given rou: Read[Option[Unit]] = ???
10+
given cons1[H, T <: Tuple](using Read[Option[H]], Read[Option[T]]): Read[Option[H *: T]] = ???
11+
12+
trait Fragment:
13+
def query[B: Read]: String = ???
14+
15+
@main def Test =
16+
val f: Fragment = ???
17+
f.query // was error

0 commit comments

Comments
 (0)