@@ -2116,7 +2116,7 @@ trait Applications extends Compatibility {
21162116   *  Two trials: First, without implicits or SAM conversions enabled. Then, 
21172117   *  if the first finds no eligible candidates, with implicits and SAM conversions enabled. 
21182118   */  
2119-   def  resolveOverloaded (alts : List [TermRef ], pt : Type )(using  Context ):  List [TermRef ] = 
2119+   def  resolveOverloaded (alts : List [TermRef ], pt : Type ,  srcPos :  SrcPos )(using  Context ):  List [TermRef ] = 
21202120    record(" resolveOverloaded" 
21212121
21222122    /**  Is `alt` a method or polytype whose result type after the first value parameter 
@@ -2154,7 +2154,7 @@ trait Applications extends Compatibility {
21542154          case  Nil  =>  chosen
21552155          case  alt2 ::  Nil  =>  alt2
21562156          case  alts2 => 
2157-             resolveOverloaded(alts2, pt) match  {
2157+             resolveOverloaded(alts2, pt, srcPos ) match  {
21582158              case  alt2 ::  Nil  =>  alt2
21592159              case  _ =>  chosen
21602160            }
@@ -2169,12 +2169,12 @@ trait Applications extends Compatibility {
21692169            val  alts0  =  alts.filterConserve(_.widen.stripPoly.isImplicitMethod)
21702170            if  alts0 ne alts then  return  resolve(alts0)
21712171          else  if  alts.exists(_.widen.stripPoly.isContextualMethod) then 
2172-             return  resolveMapped(alts, alt =>  stripImplicit(alt.widen), pt)
2172+             return  resolveMapped(alts, alt =>  stripImplicit(alt.widen), pt, srcPos )
21732173        case  _ => 
21742174
2175-       var  found  =  withoutMode(Mode .ImplicitsEnabled )(resolveOverloaded1(alts, pt))
2175+       var  found  =  withoutMode(Mode .ImplicitsEnabled )(resolveOverloaded1(alts, pt, srcPos ))
21762176      if  found.isEmpty &&  ctx.mode.is(Mode .ImplicitsEnabled ) then 
2177-         found =  resolveOverloaded1(alts, pt)
2177+         found =  resolveOverloaded1(alts, pt, srcPos )
21782178      found match 
21792179        case  alt ::  Nil  =>  adaptByResult(alt, alts) ::  Nil 
21802180        case  _ =>  found
@@ -2221,10 +2221,44 @@ trait Applications extends Compatibility {
22212221   *  It might be called twice from the public `resolveOverloaded` method, once with 
22222222   *  implicits and SAM conversions enabled, and once without. 
22232223   */  
2224-   private  def  resolveOverloaded1 (alts : List [TermRef ], pt : Type )(using  Context ):  List [TermRef ] = 
2224+   private  def  resolveOverloaded1 (alts : List [TermRef ], pt : Type ,  srcPos :  SrcPos )(using  Context ):  List [TermRef ] = 
22252225    trace(i " resolve over  $alts%, %, pt =  $pt" , typr, show =  true ) {
22262226    record(s " resolveOverloaded1 " , alts.length)
22272227
2228+     val  sv  =  Feature .sourceVersion
2229+     val  isOldPriorityVersion :  Boolean  =  sv.isAtMost(SourceVersion .`3.6`)
2230+     val  isWarnPriorityChangeVersion  =  sv ==  SourceVersion .`3.6` ||  sv ==  SourceVersion .`3.7-migration`
2231+ 
2232+     inline  def  warnOnPriorityChange (oldCands : List [TermRef ], newCands : List [TermRef ])(f : List [TermRef ] =>  List [TermRef ]):  List [TermRef ] = 
2233+ 
2234+       def  doWarn (oldChoice : String , newChoice : String ):  Unit  = 
2235+         val  (change, whichChoice) = 
2236+           if  isOldPriorityVersion
2237+           then  (" will change" " Current choice " 
2238+           else  (" has changed" " Previous choice" 
2239+ 
2240+         val  msg  =  //  uses oldCands as the list of alternatives since they should be a superset of newCands
2241+           em """ Overloading resolution for  ${err.expectedTypeStr(pt)} between alternatives 
2242+               |  ${oldCands map (_.info)}%\n % 
2243+               | $change. 
2244+               | $whichChoice          :  $oldChoice
2245+               |New choice from Scala 3.7:  $newChoice""" 
2246+ 
2247+         report.warning(msg, srcPos)
2248+       end  doWarn 
2249+ 
2250+       lazy  val  oldRes  =  f(oldCands)
2251+       val  newRes  =  f(newCands)
2252+ 
2253+       if  isWarnPriorityChangeVersion then  (oldRes, newRes) match 
2254+         case  (oldAlt ::  Nil , newAlt ::  Nil ) if  oldAlt !=  newAlt =>  doWarn(oldAlt.info.show, newAlt.info.show)
2255+         case  (oldAlt ::  Nil , Nil ) =>  doWarn(oldAlt.info.show, " none" 
2256+         case  (Nil , newAlt ::  Nil ) =>  doWarn(" none" 
2257+         case  _ =>  //  neither scheme has determined an alternative
2258+ 
2259+       if  isOldPriorityVersion then  oldRes else  newRes
2260+     end  warnOnPriorityChange 
2261+ 
22282262    def  isDetermined (alts : List [TermRef ]) =  alts.isEmpty ||  alts.tail.isEmpty
22292263
22302264    /**  The shape of given tree as a type; cannot handle named arguments. */  
@@ -2372,7 +2406,7 @@ trait Applications extends Compatibility {
23722406              TypeOps .boundsViolations(targs1, tp.paramInfos, _.substParams(tp, _), NoType ).isEmpty
23732407          val  alts2  =  alts1.filter(withinBounds)
23742408          if  isDetermined(alts2) then  alts2
2375-           else  resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1)
2409+           else  resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1, srcPos )
23762410
23772411      case  pt => 
23782412        val  compat  =  alts.filterConserve(normalizedCompatible(_, pt, keepConstraint =  false ))
@@ -2430,37 +2464,37 @@ trait Applications extends Compatibility {
24302464      candidates
24312465    else 
24322466      val  found  =  narrowMostSpecific(candidates)
2433-       if  found.length  <=   1  then  found
2467+       if  isDetermined( found)  then  found
24342468      else 
24352469        val  deepPt  =  pt.deepenProto
24362470        deepPt match 
24372471          case  pt @  FunProto (_, PolyProto (targs, resType)) => 
24382472            //  try to narrow further with snd argument list and following type params
2439-             resolveMapped(found, 
2440-               skipParamClause(pt.typedArgs().tpes, targs.tpes), resType)
2473+             warnOnPriorityChange(candidates, found) : 
2474+               resolveMapped(_,  skipParamClause(pt.typedArgs().tpes, targs.tpes), resType, srcPos )
24412475          case  pt @  FunProto (_, resType : FunOrPolyProto ) => 
24422476            //  try to narrow further with snd argument list
2443-             resolveMapped(found, 
2444-               skipParamClause(pt.typedArgs().tpes, Nil ), resType)
2477+             warnOnPriorityChange(candidates, found) : 
2478+               resolveMapped(_,  skipParamClause(pt.typedArgs().tpes, Nil ), resType, srcPos )
24452479          case  _ => 
24462480            //  prefer alternatives that need no eta expansion
24472481            val  noCurried  =  alts.filterConserve(! resultIsMethod(_))
24482482            val  noCurriedCount  =  noCurried.length
24492483            if  noCurriedCount ==  1  then 
24502484              noCurried
24512485            else  if  noCurriedCount >  1  &&  noCurriedCount <  alts.length then 
2452-               resolveOverloaded1(noCurried, pt)
2486+               resolveOverloaded1(noCurried, pt, srcPos )
24532487            else 
24542488              //  prefer alternatves that match without default parameters
24552489              val  noDefaults  =  alts.filterConserve(! _.symbol.hasDefaultParams)
24562490              val  noDefaultsCount  =  noDefaults.length
24572491              if  noDefaultsCount ==  1  then 
24582492                noDefaults
24592493              else  if  noDefaultsCount >  1  &&  noDefaultsCount <  alts.length then 
2460-                 resolveOverloaded1(noDefaults, pt)
2494+                 resolveOverloaded1(noDefaults, pt, srcPos )
24612495              else  if  deepPt ne pt then 
24622496                //  try again with a deeper known expected type
2463-                 resolveOverloaded1(alts, deepPt)
2497+                 resolveOverloaded1(alts, deepPt, srcPos )
24642498              else 
24652499                candidates
24662500    }
@@ -2494,7 +2528,7 @@ trait Applications extends Compatibility {
24942528   *  type is mapped with `f`, alternatives with non-existing types or symbols are dropped, and the 
24952529   *  expected type is `pt`. Map the results back to the original alternatives. 
24962530   */  
2497-   def  resolveMapped (alts : List [TermRef ], f : TermRef  =>  Type , pt : Type )(using  Context ):  List [TermRef ] = 
2531+   def  resolveMapped (alts : List [TermRef ], f : TermRef  =>  Type , pt : Type ,  srcPos :  SrcPos )(using  Context ):  List [TermRef ] = 
24982532    val  reverseMapping  =  alts.flatMap { alt => 
24992533      val  t  =  f(alt)
25002534      if  t.exists &&  alt.symbol.exists then 
@@ -2517,7 +2551,7 @@ trait Applications extends Compatibility {
25172551    }
25182552    val  mapped  =  reverseMapping.map(_._1)
25192553    overload.println(i " resolve mapped:  ${mapped.map(_.widen)}%, % with  $pt" )
2520-     resolveOverloaded(mapped, pt)(using  ctx.retractMode(Mode .SynthesizeExtMethodReceiver ))
2554+     resolveOverloaded(mapped, pt, srcPos )(using  ctx.retractMode(Mode .SynthesizeExtMethodReceiver ))
25212555      .map(reverseMapping.toMap)
25222556
25232557  /**  Try to typecheck any arguments in `pt` that are function values missing a 
0 commit comments