In a mathematical sense, the property whether, for any types `T1`

and `T2`

, the trait implementation `From<T2> for T1`

exists, i.e. whether the trait bound `T1: From<T2>`

is satisfied, or not, can be seen as a â€ś(binary) relationâ€ť. In this interpretation, the relation (between types) that the trait `From`

gives rise to, is â€śreflexiveâ€ť in the mathematical sense of the term. See also the Wikipedia pages I linked.

More commonly known examples for binary relations in mathematics are e.g. the < and â‰¤ relations. For any number n, the the statement â€śn â‰¤ nâ€ť is always true, e.g. 2â‰¤2, 3â‰¤3, etcâ€¦ are all true, so â€śâ‰¤â€ť, is a reflexive relation, too. On the other hand the same doesnâ€™t hold true for the â€ť<â€ť relation, where something like 2<2 is *false*. While for â€ś<â€ť this goes as far as that â€śn < nâ€ť is actually false for *all* numbers, in general, even a single such counter-example would be sufficient for a relation not to be considered reflexive.

For example the `Add`

trait in Rust, with its implementation in the standard library, also gives rise to a relation between types, much like `From`

, but this relation is not reflexive: While for certain types, `T: Add<T>`

is fulfilled, for example `i32: Add<i32>`

, and in fact the reflexive case is so common that `Add`

comes with a shorthand, where a trait bound `Foo: Add`

is short for `Foo: Add<Foo>`

, there *do* exist lots of types that donâ€™t implement `Add<â€¦>`

at all, and even ones that do, but not reflexively.

For example there is no implementation for `char`

, because you are not supposed to think of unicode scalar values as numbers, but more as characters, and those donâ€™t do arithmetic. Or e.g. for `Instant`

, there is an implementation for `Instant: Add<Duration>`

, but not `Instant: Add<Instant>`

, because you can offset points in time by time durations, but thereâ€™s no sense in adding points in time to each other. (E.g. thereâ€™s no sense in defining weird things like adding the year 2023 to itself giving, say, the year 4046; since any choice of a â€ś0â€ť point is just arbitrary, and we donâ€™t like results depending on such arbitrary choices.) Another example is `String`

and `&str`

which do implement `String: Add<&str>`

, but neither `&str`

nor `String`

has a reflexive implementation; this is mainly an arbitrary API choice in order to encourage the user to create unnecessary allocations. (Though also some people donâ€™t like it at all that strings allow a `+`

operator in Rust.)