@@ -199,29 +199,38 @@ object TypeTestsCasts {
199
199
// if `test` is primitive but `found` is not, we might have a case like
200
200
// found = java.lang.Integer, test = Int, which could be true
201
201
// (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]`
202
205
! isDerivedValueClass(foundCls) && ! isDerivedValueClass(testCls)
203
206
// we don't have the logic to handle derived value classes
204
207
205
208
/** Check whether a runtime test that a value of `foundCls` can be a `testCls`
206
209
* can be true in some cases. Issues a warning or an error otherwise.
207
210
*/
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
211
230
ctx.error(" cannot test if value types are references" , tree.sourcePos)
212
231
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
225
234
226
235
if (expr.tpe <:< testType)
227
236
if (expr.tpe.isNotNull) {
@@ -232,7 +241,7 @@ object TypeTestsCasts {
232
241
else {
233
242
val nestedCtx = ctx.fresh.setNewTyperState()
234
243
val foundClsSyms = foundClasses(expr.tpe.widen, Nil )
235
- val sensical = foundClsSyms.exists(sym => checkSensical(sym )(using nestedCtx) )
244
+ val sensical = checkSensical(foundClsSyms )(using nestedCtx)
236
245
if (! sensical) {
237
246
nestedCtx.typerState.commit()
238
247
constant(expr, Literal (Constant (false )))
0 commit comments