@@ -127,6 +127,9 @@ trait Applications extends Compatibility { self: Typer =>
127127 */
128128 protected def makeVarArg (n : Int , elemFormal : Type ): Unit
129129
130+ /** If all `args` have primitive numeric types, make sure it's the same one */
131+ protected def harmonizeArgs (args : List [TypedArg ]): List [TypedArg ]
132+
130133 /** Signal failure with given message at position of given argument */
131134 protected def fail (msg : => String , arg : Arg ): Unit
132135
@@ -334,7 +337,14 @@ trait Applications extends Compatibility { self: Typer =>
334337 addTyped(arg, formal)
335338 case _ =>
336339 val elemFormal = formal.widenExpr.argTypesLo.head
337- args foreach (addTyped(_, elemFormal))
340+ val origConstraint = ctx.typerState.constraint
341+ var typedArgs = args.map(typedArg(_, elemFormal))
342+ val harmonizedArgs = harmonizeArgs(typedArgs)
343+ if (harmonizedArgs ne typedArgs) {
344+ ctx.typerState.constraint = origConstraint
345+ typedArgs = harmonizedArgs
346+ }
347+ typedArgs.foreach(addArg(_, elemFormal))
338348 makeVarArg(args.length, elemFormal)
339349 }
340350 else args match {
@@ -389,6 +399,7 @@ trait Applications extends Compatibility { self: Typer =>
389399 def argType (arg : Tree , formal : Type ): Type = normalize(arg.tpe, formal)
390400 def treeToArg (arg : Tree ): Tree = arg
391401 def isVarArg (arg : Tree ): Boolean = tpd.isWildcardStarArg(arg)
402+ def harmonizeArgs (args : List [Tree ]) = harmonize(args)
392403 }
393404
394405 /** Subclass of Application for applicability tests with type arguments and value
@@ -405,6 +416,7 @@ trait Applications extends Compatibility { self: Typer =>
405416 def argType (arg : Type , formal : Type ): Type = arg
406417 def treeToArg (arg : Tree ): Type = arg.tpe
407418 def isVarArg (arg : Type ): Boolean = arg.isRepeatedParam
419+ def harmonizeArgs (args : List [Type ]) = harmonizeTypes(args)
408420 }
409421
410422 /** Subclass of Application for type checking an Apply node, where
@@ -430,6 +442,8 @@ trait Applications extends Compatibility { self: Typer =>
430442 typedArgBuf += seqToRepeated(seqLit)
431443 }
432444
445+ def harmonizeArgs (args : List [TypedArg ]) = harmonize(args)
446+
433447 override def appPos = app.pos
434448
435449 def fail (msg : => String , arg : Trees .Tree [T ]) = {
@@ -1025,25 +1039,34 @@ trait Applications extends Compatibility { self: Typer =>
10251039 }
10261040 }
10271041
1028- def harmonize (trees : List [Tree ])(implicit ctx : Context ): List [Tree ] = {
1029- def numericClasses (trees : List [Tree ], acc : Set [Symbol ]): Set [Symbol ] = trees match {
1030- case tree :: trees1 =>
1031- val sym = tree.tpe.typeSymbol
1032- if (sym.isNumericValueClass && tree.tpe.isRef(sym))
1033- numericClasses(trees1, acc + sym)
1034- else
1035- Set ()
1042+ private def harmonizeWith [T <: AnyRef ](ts : List [T ])(tpe : T => Type , adapt : (T , Type ) => T )(implicit ctx : Context ): List [T ] = {
1043+ def numericClasses (ts : List [T ], acc : Set [Symbol ]): Set [Symbol ] = ts match {
1044+ case t :: ts1 =>
1045+ val sym = tpe(t).widen.classSymbol
1046+ if (sym.isNumericValueClass) numericClasses(ts1, acc + sym)
1047+ else Set ()
10361048 case Nil =>
10371049 acc
10381050 }
1039- val clss = numericClasses(trees , Set ())
1051+ val clss = numericClasses(ts , Set ())
10401052 if (clss.size > 1 ) {
10411053 val lub = defn.ScalaNumericValueClassList .find(lubCls =>
10421054 clss.forall(defn.isValueSubClass(_, lubCls))).get.typeRef
1043- trees .mapConserve(tree => adaptInterpolated(tree , lub, tree ))
1055+ ts .mapConserve(adapt(_ , lub))
10441056 }
1045- else trees
1057+ else ts
10461058 }
1059+
1060+ def harmonize (trees : List [Tree ])(implicit ctx : Context ): List [Tree ] = {
1061+ def adapt (tree : Tree , pt : Type ): Tree = tree match {
1062+ case cdef : CaseDef => tpd.cpy.CaseDef (cdef)(body = adapt(cdef.body, pt))
1063+ case _ => adaptInterpolated(tree, pt, tree)
1064+ }
1065+ harmonizeWith(trees)(_.tpe, adapt)
1066+ }
1067+
1068+ def harmonizeTypes (tpes : List [Type ])(implicit ctx : Context ): List [Type ] =
1069+ harmonizeWith(tpes)(identity, (tp, pt) => pt)
10471070}
10481071
10491072/*
0 commit comments