could anyone explain why smart-cast doesn’t work f...
# announcements
d
could anyone explain why smart-cast doesn’t work for range checks?
Copy code
if (pin?.length != 36) throw UnauthorizedResponse()
// pin is smart cast here
Copy code
if (pin?.length !in (8..36)) throw UnauthorizedResponse()
// pin is not smart cast here
g
Yes, it doesn’t work
d
but shouldn’t it? 🤔
g
nope
d
it’s smart cast because you know it’s 36 in the first example in the second example you know it’s in the range 8 to 36
which is just as non-nullable
g
In theory it’s possible to implement in compiler, but it just doesn’t work now
d
that i understand
g
also in second case compiler should understand range implementation detail which doesn’t look feasible (only by coupling stdlib implementation details to compiler)
also in general such code looks a bit messy for me. Better to make pin non nullable and handle it properly than combine null and range check, but it’s just my opinion
d
that’s what i ended up doing, i was just curious why it didn’t work
g
it’s just matter of compiler’s complexity imo
so example with 36 may be handled, probably make sense to create an issue. But I don’t think that it make sense for range (or even possible for generic implementation)
c
it can’t hurt to file a ticket
k
Can't a contract help here?
Copy code
private fun Int?.notInRange(range: IntRange): Boolean {
	contract {
		returns(false) implies (this@notInRange != null)
	}
	return this !in range
}
I tried this before but it seems contracts don't work on infix operators?