Let us assume a language that has final with Java semantics, i.e. a final type cannot have subtypes. Further, let that language have a full lattice type theory with at least one bottom type, e.g. NoReturn marking unreachable code.
Now, from the perspective of type theory, is it sound to make use of a final property of a type or value. In the sense that if e.g. a system.exit() is observed, to use knowledge about bottom or final types during type inference or type checking?
Or is any rule that even considers final during type checking unsound?
Would the answer change if other concepts like intersection types are added to the language?
Edit: Adding an example to illustrate my issue.
Let us assume we have three types Top, F and Bottom. The compiler of the hypothetical language allows inlining. The inlining is used to create a substitution without adding more type theory.
If we have an F identity function id(x : F) : F = x, is it valid to assume that the type of x is always exactly F if F is final?
Edit2: This question is not about Java or the JVM.
3isIntegerLiteralirrespective of the context seems to be unsound as it conflicts with a substitution rule that, to me, looks perfectly fine. $\endgroup$finaljust a restriction on a class itself, not the type of its values? $\endgroup$3example was a bad one. While it was what made me ask the question, the relation to the question is that I consider the type final, but I equally consider type variables with that type as upper bound subtypes. The longer I think about it the less clarity remains if I should collapse the variable types if the bound contains one element (the final type) or if the behaviour is correct and my treatment of final is plain wrong which I currently consider more likely. $\endgroup$