Perhaps with effect tracking of references we can request that a value can only be assigned with a new reference, which would also help in overload resolution of constructors vs apply:
class Foo()
object Foo:
// here fresh implies that only a fresh value can be returned,
// so this is not recursive, however fresh variables can not be assigned to this result
fresh def apply(): Foo = Foo()
def cache(fresh x: Foo): Unit = ???
cache(Foo()) // calls constructor unambiguously