@@ -147,6 +147,8 @@ object Constants {
147147 case _ => throw new Error (" value " + value + " is not a Double" )
148148 }
149149
150+ import dotty .tools .dotc .core .Decorators .i
151+
150152 /** Convert constant value to conform to given type. */
151153 def convertTo (pt : Type )(using Context ): Constant | Null = pt.dealias.stripTypeVar match
152154 case ConstantType (value) if value == this => this
@@ -162,9 +164,20 @@ object Constants {
162164 case NoType => convertTo(param.binder.paramInfos(param.paramNum).lo)
163165 case inst => convertTo(inst)
164166 case pt : OrType =>
167+ // For a union type, if both sides convert to constants,
168+ // return a constant only if two sides convert to the same constant
169+ // (same value and same tag).
170+ // For example, `2` can be converted to `Byte | String | Byte`,
171+ // but not to `Byte | Int` (which would be ambiguous).
172+ // TODO: However, the logic will not work here, since `2: Int` is already
173+ // a subtype of `Byte | Int` before `adapt`.
165174 val leftResult = convertTo(pt.tp1)
166- if leftResult != null then leftResult
167- else convertTo(pt.tp2)
175+ val rightResult = convertTo(pt.tp2)
176+ // println(s"convertTo OrType: $this to $pt, leftResult = $leftResult, rightResult = $rightResult, compare = ${leftResult == rightResult}")
177+ if leftResult == null then rightResult
178+ else if rightResult == null then leftResult
179+ else if leftResult == rightResult then leftResult
180+ else null
168181 case pt =>
169182 val target = pt.typeSymbol
170183 if target == tpe.typeSymbol then this
0 commit comments