> The definition is very simple - the inference engine must use nontrivial inference rules to reconstruct the types.
Where exactly is this rule coming from ? What is the source of your definition ? And if it is the authoritative definition, why don't you go rewrite the wikipedia page, which is then wrong ? https://en.wikipedia.org/wiki/Type_inference
> The rule “given P then P” alone doesn't quite cut it
"Doesn't quite cut it" sounds like a very precise and scientific definition ! Also your categorization of C# is wrong, even by your own definition, because of function types inference and of subtyping, which makes the algorithm non trivial.
> Then they just have unidirectional type propagation - which is perfectly fine, just not type inference.
Again:
1. This is wrong, even by your own definition. You can have local type inference limited to the initialization point, and have non trivial resolution rules. See this paper by Benjamin Pierce for an example : http://www.cis.upenn.edu/~bcpierce/papers/lti-toplas.pdf
2. Where is this definition even coming from ? In my book, unidirectional type propagation is a form of type inference, and it quite logically follows: The type is inferred. The fact that you chose to draw a line, say, to flow sensitive inference (in the case of Rust and Swift) or to global unification style inference (ala ML) is a completely arbitrary definition, and one that I have to this day never encountered. Indeed, I can't find any online resource that agrees with you. Most language documentations, including C#, C++ and Go, call this type inference. Most researchers call any mechanism where a language infers the type, type inference, even the mechanism that allows you to call generic without specifying the type of the instantiation, as in this paper : https://www.researchgate.net/profile/Erik_Meijer/publication...
I have absolutely never encountered any definition of type inference which draws this line, and for good reasons, because it doesn't make any sense.