I understand the `usedAsExpression` flag in the FI...
# compiler
r
I understand the
usedAsExpression
flag in the FIR API is internal and not to be relied on, but I was curious about the rationale for this flag being false when, say an expression is used as an implicit return from a lambda.
Copy code
val a: (Int) -> Boolean = { i ->
    if (i > 3) { true } // the if isn't used as an expression?
    else { false }
}
Digging into the builder logic, I see that if the current node is the last child of its parent, the
usedAsExpression
flag of the parent is checked... it seems like oneline functions like
fun a() = ...
evaluate to true, but the parent check returns false for function literal parents... Why does it work that way? are there situations where it makes more sense to consider expressions that are implicitly returned to not be used as expressions? I'd love to hear from anybody who's worked on FIR, thanks in advance!
d
This flag is used only for determining the exhaustiveness status of whens and is calculated during raw FIR state, when nothing known about the code yet. So last statement of the lambda could be or could not be used as expression depending on the expected type of the lambda:
Copy code
// when is used as expression
val a: (Int) -> Boolean = { i ->
    when {
        i > 3 -> true
    }
}

// lambda coerced to Unit
val b: (Int) -> Unit = { i ->
    when {
        i > 3 -> true
    }
}
So here we have two options: • set
usedAsExpression
to
true
here, which will result in
NO_ELSE_IN_WHEN
for
a
and
b
• set it to
false
, which will lead to no
NO_ELSE_IN_WHEN
diagnostics (as both whens wouldn't be required to be exhaustive) but to
RETURN_TYPE_MISMATCH
for
a
(as type of
when
would be inferred to
Unit
). Considering that code in
b
is correct and nothing should be reported, the second option was chosen.
r
makes sense, thank you. I guess the best approach for such scenarios is to check for source element type of the parent return, since that would be implicit for such lambdas?
d
Sorry, best approach for what? Generally it's impossible to calculate the proper value for
usedAsExpression
without resolution of the code.
r
to clarify, my use case is to convert resolved FIR to a different IR, and I was exploring using usedAsExpression to help with translating when expressions in various contexts. but I see it isn't meant for that purpose.
👌 1