Why is non-null assert required in the second while loop?


#1

I am confused by the requirement for element!! after element?.node != null &&. Does not the element?.node not being null imply that element is also not null?

In the first while() code element after element?.node != null is smart cast in the second while() it is not.

class Sample {
    fun sample(element: PsiElement) {
        var useElement: PsiElement? = element

        while (useElement?.node != null
                && !TokenTypeSets.BLOCK_ELEMENTS.contains(useElement.node.elementType)) {
            useElement = useElement.parent
        }

        if (useElement?.node == null || useElement is PsiFile) return

        // collapse to the innermost block quote that is a single child
        while (useElement?.node != null
                && useElement.node.elementType == MultiMarkdownTypes.BLOCK_QUOTE
                && useElement.children.size == 1 
                && useElement.lastChild.node.elementType == MultiMarkdownTypes.BLOCK_QUOTE) {
            useElement = useElement.lastChild
        }

        if (useElement == null) return
    }
}

If I comment out the line:

if (useElement?.node == null || useElement is PsiFile) return

Then the second while() also smart casts. Am I missing something or is this a bug?

Kotlin version: 1.3.11-release-IJ2018.3-1


#2

Why do you think it smartcasts?