The "check_null_side" code you're proposing seems really horrid. For one thing, it seems quite out of place for eval_const_expressions to be doing that. For another, it's wrong in principle because eval_const_expressions doesn't know which part of the query tree it's being invoked on, so it cannot know whether outer-join nullability is an issue. For another, doing that work over again from scratch every time we see a potentially optimizable NullTest looks expensive. (I wonder whether you have tried to measure the performance penalty imposed by this patch in cases where it fails to make any proof.)
I was thinking about collecting data about joins only once at the start of eval_const_expressions but I assume most queries don't have NULL check expressions and postpone it until we find one. Thinking about it again I think it can be done better by storing check_null_side_state into eval_const_expressions_context to use it for subsequent evaluation.
Attached patch does like the above and includes NOT NULL constraint column.