For an unqualified name, local callable (i.e. declarations in a statement scope) are always prioritised over non-local ones. The "things in inner scopes hides things in outer scopes" rule comes after that.
From the overload resolution section of the spec,
For an identifier named f
the following sets are analyzed (in the
given order):
- Local non-extension callables named
f
in the current scope and its upwards-linked scopes, ordered by the size of the scope (smallest
first), excluding the package scope;
- The overload candidate sets for each pair of implicit receivers
e
and d
available in the current scope, calculated as if e
is the
explicit receiver, in order of the receiver priority;
- [not relevant to this scenario]
Step 1 considers all the local callables, and only after that do we try callables with a receiver in the second step.
Applying this to your code,
fun f() {
val x = 0 // This 'x' is local to 'f'
val a = object {
val x = 1 // This 'x' is not local. The body of an object literal is a declaration scope, not a statement scope
fun g() {
println(x)
}
}
a.g()
}
If locals are not prioritised like this, you'd have no way of referring to the local x
when you're in g
.