Surprising given resoultion

Hello,
I got surprised by the following behavior:

trait A { override def toString = "A" }
trait B extends A { override def toString = "B" }

given A = new A{}
given B = new B{}

summon[A] // returns instance of B

I though it would either tell me the givens overlap, or to return the A instance, is this expected ?
(changing it to classes does not change the behavior)

Programming in Scala 5th Edition, Chapter 21.7 “When multiple givens apply”:

So, both givens are of type A but the B is more specific, I guess…

(Side note: sometimes I feel like I’m the only idiot who read the book… :cry: )

I don’t think anyone’s an idiot for reading a book !
I should really read it, that way we might be the only two ^^

1 Like

Note that this behavior will change in 3.6.0 (See PR: Change rules for given prioritization by odersky · Pull Request #19300 · scala/scala3 · GitHub) and a warning will be emited in 3.5.0.

You can already test it in 3.5.0-RC1, but you will have to add the following flag (‘-source 3.6’).

3 Likes

In 3.5.0-RC1 you get:

– Warning: …/…/new/test.scala:8:19 ------------------------------------------
8 | println(summon[A]) // returns instance of B
| ^
|Given search preference for A between alternatives (given_A : A) and (given_B : B) will change
|Current choice : the second alternative
|New choice from Scala 3.6: the first alternative
1 warning found

2 Likes

Indeed, I have just amended my comment

This is the first time Sporarum has posted — let’s welcome them to our community!

Welcome!

It can feel weird asking questions that are only resolved in the next version of the compiler, especially when many of us are just confused about whether to write with.

I hope you feel comfortable and welcome to pose questions others didn’t think to ask!

This must be what it’s like to raise your hand in Professor Odersky’s class.

1 Like