Skip to content

Commit be16a7b

Browse files
committed
Derived members succeed other givens in cycle test
Sibling givens are always eligible for derived members, which are appended to the enclosing template.
1 parent 392d0a7 commit be16a7b

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,10 @@ trait Implicits:
17181718
def candSucceedsGiven(sym: Symbol): Boolean =
17191719
val owner = sym.owner
17201720
if owner == candSym.owner then
1721-
sym.is(GivenVal) && sym.span.exists && sym.span.start <= candSym.span.start
1721+
sym.is(GivenVal)
1722+
&& sym.span.exists && sym.span.start <= candSym.span.start
1723+
&& (sym.span.isSourceDerived || !sym.name.startsWith("derived$", 0))
1724+
// logically a synthetic injected at the end of the body
17221725
else if owner.isClass then false
17231726
else candSucceedsGiven(owner)
17241727

tests/pos/i23897.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
import scala.deriving.Mirror
3+
4+
class Test[A]
5+
object Test:
6+
def derived[A](using m: Mirror.Of[A], t: Test[Int]): Test[A] = new Test[A]
7+
8+
case class Foo(i: Int) derives Test
9+
object Foo:
10+
given i: Test[Int] = new Test[Int]
11+
12+
case class Bar(i: Int) derives Test
13+
object Bar:
14+
given Test[Int]()

tests/run/i23897.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
import scala.deriving.Mirror
3+
4+
trait Semigroup[A] {
5+
def combine(x: A, y: A): A
6+
}
7+
object Semigroup {
8+
given semigroupInt: Semigroup[Int] = _ + _
9+
10+
given emptyTuple: Semigroup[EmptyTuple] = (x, _) => x
11+
12+
given tupleN[H, T <: Tuple](using h: Semigroup[H], t: Semigroup[T]): Semigroup[H *: T] =
13+
(x, y) => h.combine(x.head, y.head) *: t.combine(x.tail, y.tail)
14+
15+
def derived[A <: Product](using m: Mirror.ProductOf[A], s: Semigroup[m.MirroredElemTypes]): Semigroup[A] =
16+
(x, y) => m.fromTuple(s.combine(Tuple.fromProductTyped(x), Tuple.fromProductTyped(y)))
17+
}
18+
19+
case class Foo(i: Int) derives Semigroup
20+
object Foo {
21+
given overrideSemigroupInt: Semigroup[Int] = _ * _
22+
}
23+
24+
@main def Test =
25+
assert:
26+
summon[Semigroup[Foo]].combine(Foo(2), Foo(3)) == Foo(6)
27+
28+
// Scala 3.3 and 3.4
29+
//summon[Semigroup[Foo]].combine(Foo(2), Foo(3)) // => Foo(6)
30+
// Scala 3.5+
31+
//summon[Semigroup[Foo]].combine(Foo(2), Foo(3)) // => Foo(5)

0 commit comments

Comments
 (0)