@@ -199,29 +199,38 @@ object TypeTestsCasts {
199199 // if `test` is primitive but `found` is not, we might have a case like
200200 // found = java.lang.Integer, test = Int, which could be true
201201 // (not sure why that is so, but scalac behaves the same way)
202+ ! (! testCls.isPrimitiveValueClass && foundCls.isPrimitiveValueClass) &&
203+ // foundCls can be `Boolean`, while testCls is `Integer`
204+ // it can happen in `(3: Boolean | Int).isInstanceOf[Int]`
202205 ! isDerivedValueClass(foundCls) && ! isDerivedValueClass(testCls)
203206 // we don't have the logic to handle derived value classes
204207
205208 /** Check whether a runtime test that a value of `foundCls` can be a `testCls`
206209 * can be true in some cases. Issues a warning or an error otherwise.
207210 */
208- def checkSensical (foundCls : Symbol )(using Context ): Boolean =
209- if (! isCheckable(foundCls)) true
210- else if (foundCls.isPrimitiveValueClass && ! testCls.isPrimitiveValueClass) {
211+ def checkSensical (foundClasses : List [Symbol ])(using Context ): Boolean =
212+ def check (foundCls : Symbol ): Boolean =
213+ if (! isCheckable(foundCls)) true
214+ else if (! foundCls.derivesFrom(testCls)) {
215+ val unrelated = ! testCls.derivesFrom(foundCls) && (
216+ testCls.is(Final ) || ! testCls.is(Trait ) && ! foundCls.is(Trait )
217+ )
218+ if (foundCls.is(Final ))
219+ unreachable(i " type ${expr.tpe.widen} is not a subclass of $testCls" )
220+ else if (unrelated)
221+ unreachable(i " type ${expr.tpe.widen} and $testCls are unrelated " )
222+ else true
223+ }
224+ else true
225+ end check
226+
227+ val foundEffectiveClass = effectiveClass(expr.tpe.widen)
228+
229+ if foundEffectiveClass.isPrimitiveValueClass && ! testCls.isPrimitiveValueClass then
211230 ctx.error(" cannot test if value types are references" , tree.sourcePos)
212231 false
213- }
214- else if (! foundCls.derivesFrom(testCls)) {
215- val unrelated = ! testCls.derivesFrom(foundCls) && (
216- testCls.is(Final ) || ! testCls.is(Trait ) && ! foundCls.is(Trait )
217- )
218- if (foundCls.is(Final ))
219- unreachable(i " type ${expr.tpe.widen} is not a subclass of $testCls" )
220- else if (unrelated)
221- unreachable(i " type ${expr.tpe.widen} and $testCls are unrelated " )
222- else true
223- }
224- else true
232+ else foundClasses.exists(check)
233+ end checkSensical
225234
226235 if (expr.tpe <:< testType)
227236 if (expr.tpe.isNotNull) {
@@ -232,7 +241,7 @@ object TypeTestsCasts {
232241 else {
233242 val nestedCtx = ctx.fresh.setNewTyperState()
234243 val foundClsSyms = foundClasses(expr.tpe.widen, Nil )
235- val sensical = foundClsSyms.exists(sym => checkSensical(sym )(using nestedCtx) )
244+ val sensical = checkSensical(foundClsSyms )(using nestedCtx)
236245 if (! sensical) {
237246 nestedCtx.typerState.commit()
238247 constant(expr, Literal (Constant (false )))
0 commit comments